Swing 不规则窗体的制作
2013-08-23 19:13
127 查看
终极解决之道
经过反复的研究探索,终于获得了一个完美的解决方法:不用shape、不用抓图、不用workaround,真正的、彻底的、完全的、随意的在桌面上任意绘图、涂鸦、撒野,真正的属于程序员的Freedom!下面就来一起揭开这层窗户纸吧!
在程序中依次设置以下几个参数:
设置窗口完全透明:AWTUtilities.setWindowOpaque(frame, false);
设置窗口无边缘:frame.setUndecorated(true);
设置窗口的ContentPane为要显示的Pane:frame.setContentPane(myPane);
在myPane中放置具体要显示的内容,也可以重载paint方法进行Java2D绘制。这些paint会直接发生在桌面背景上。
接下来,就是见证奇迹的时刻!
(不好意思,暴露我的桌面了)
通过上面方法,可以做一个任意大小、任意位置的window,在相应的桌面位置上随意显示Swing组件,或做任意Java2D画图。比如下面小例子可以在屏幕上直接画一个红色的立体矩形,而没有显示窗口:
Java代码
运行效果如下图:
Java代码
对窗体上的组件安装这一listener,就可以对窗口中任意元素进行拖拽,直接拖动窗体四处晃悠了。
图片的切割
要做好的界面,需要一个耐心、有创意的美工大力协助,例如图片的切割就很重要。下图展示了如何从效果图进行具体切割素材:
Java代码
肆虐你的桌面:六月飘雪!
既然窗户纸捅破了,在桌面上就随意折腾吧。这几天窗外酷热难耐,咱们就来个桌面飘雪,也许可以望梅止渴,带来丝丝清凉吧!
先准备一个雪花的png透明图片,然后在桌面上随机生成50个雪花坐标,每次paint让每个雪花的左右略微抖一下(snowX[i] += TWaverUtil.getRandomInt(5) - 3),垂直距离下坠5像素(snowY[i] += 5),再旋转个小角度。然后,用一个线程不停的repaint窗口。
雪花png图片:
程序代码如下:
Java代码
快快运行代码,让雪花飘起来吧!
如果愿意折腾,还可以修改代码中的:
private int count = 50,调整雪花的数量;
修改angles[i] += i / 5,调整雪花翻滚的速度;
修改snowY[i] += 5,调整雪花下坠的速度;
修改snowX[i] += TWaverUtil.getRandomInt(5) – 3,调整雪花左右摆动的速度;
别说你不知道怎么结束程序啊,不会Alt+F4的话,你这个程序员肯定不合格了。
经过反复的研究探索,终于获得了一个完美的解决方法:不用shape、不用抓图、不用workaround,真正的、彻底的、完全的、随意的在桌面上任意绘图、涂鸦、撒野,真正的属于程序员的Freedom!下面就来一起揭开这层窗户纸吧!
在程序中依次设置以下几个参数:
设置窗口完全透明:AWTUtilities.setWindowOpaque(frame, false);
设置窗口无边缘:frame.setUndecorated(true);
设置窗口的ContentPane为要显示的Pane:frame.setContentPane(myPane);
在myPane中放置具体要显示的内容,也可以重载paint方法进行Java2D绘制。这些paint会直接发生在桌面背景上。
接下来,就是见证奇迹的时刻!
(不好意思,暴露我的桌面了)
通过上面方法,可以做一个任意大小、任意位置的window,在相应的桌面位置上随意显示Swing组件,或做任意Java2D画图。比如下面小例子可以在屏幕上直接画一个红色的立体矩形,而没有显示窗口:
Java代码
import com.sun.awt.AWTUtilities; import java.awt.Color; import java.awt.Graphics; import javax.swing.JFrame; import javax.swing.JPanel; public class Test { public static void main(String[] args) { JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setUndecorated(true); frame.setBounds(500, 500, 300, 300); AWTUtilities.setWindowOpaque(frame, false); JPanel pane = new JPanel() { @Override public void paint(Graphics g) { super.paint(g); g.setColor(Color.red); g.fill3DRect(10, 10, 100, 100, true); } }; frame.setContentPane(pane); frame.setVisible(true); } }
运行效果如下图:
窗口的拖拽移动
窗口不再规则,窗口标题栏不再出现,如何移动窗口?按照其他类似软件的习惯做法,应当允许用鼠标直接拖拽窗体任意位置进行窗口移动。做一个鼠标监听器对窗口中的元素进行拖动监听,对窗口进行相应拖动距离的移动:Java代码
private MouseAdapter moveWindowListener = new MouseAdapter() { private Point lastPoint = null; @Override public void mousePressed(MouseEvent e) { lastPoint = e.getLocationOnScreen(); } @Override public void mouseDragged(MouseEvent e) { Point point = e.getLocationOnScreen(); int offsetX = point.x - lastPoint.x; int offsetY = point.y - lastPoint.y; Rectangle bounds = FreeLoginUI.this.getBounds(); bounds.x += offsetX; bounds.y += offsetY; FreeLoginUI.this.setBounds(bounds); lastPoint = point; } };
对窗体上的组件安装这一listener,就可以对窗口中任意元素进行拖拽,直接拖动窗体四处晃悠了。
图片的切割
要做好的界面,需要一个耐心、有创意的美工大力协助,例如图片的切割就很重要。下图展示了如何从效果图进行具体切割素材:
制作渐变背景Panel
仔细观察中间的输入区域部分,其背景是有渐变设计的。其制作方法也很简单:首先让美工帮助制作一个一个像素宽、整个panel高度的小图片作为素材;然后用这个图片创建纹理Paint;最后用这个纹理对真个panel进行fill。Java代码
private JPanel inputPane = new JPanel() { private String backgroundImageURL = FreeUtil.getImageURL("login_background.png"); private TexturePaint paint = FreeUtil.createTexturePaint(backgroundImageURL); @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; g2d.setPaint(paint); g2d.fillRect(0, 0, this.getWidth(), this.getHeight()); } };
肆虐你的桌面:六月飘雪!
既然窗户纸捅破了,在桌面上就随意折腾吧。这几天窗外酷热难耐,咱们就来个桌面飘雪,也许可以望梅止渴,带来丝丝清凉吧!
先准备一个雪花的png透明图片,然后在桌面上随机生成50个雪花坐标,每次paint让每个雪花的左右略微抖一下(snowX[i] += TWaverUtil.getRandomInt(5) - 3),垂直距离下坠5像素(snowY[i] += 5),再旋转个小角度。然后,用一个线程不停的repaint窗口。
雪花png图片:
程序代码如下:
Java代码
public class TestSnow { public static void main(String[] args) { final JFrame frame = new JFrame(); frame.setAlwaysOnTop(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setUndecorated(true); frame.setExtendedState(JFrame.MAXIMIZED_BOTH); AWTUtilities.setWindowOpaque(frame, false); final JPanel pane = new JPanel() { private int[] snowX = null; private int[] snowY = null; private int[] angles = null; private int count = 50; @Override public void paint(Graphics g) { super.paint(g); Rectangle bounds = frame.getBounds(); if (snowX == null) { snowX = new int[count]; for (int i = 0; i < snowX.length; i++) { snowX[i] = TWaverUtil.getRandomInt(bounds.width); } snowY = new int[count]; for (int i = 0; i < snowY.length; i++) { snowY[i] = TWaverUtil.getRandomInt(bounds.height); } angles = new int[count]; for (int i = 0; i < snowY.length; i++) { angles[i] = TWaverUtil.getRandomInt(360); } } Graphics2D g2d = (Graphics2D) g; Image image = TWaverUtil.getImage("/free/test/snow.png"); for (int i = 0; i < count; i++) { snowX[i] += TWaverUtil.getRandomInt(5) - 3; snowY[i] += 5; angles[i] += i / 5; snowY[i] = snowY[i] > bounds.height ? 0 : snowY[i]; angles[i] = angles[i] > 360 ? 0 : angles[i]; int x = snowX[i]; int y = snowY[i]; int angle = angles[i]; g2d.translate(x, y); double angleValue = Math.toRadians(angle); g2d.rotate(angleValue); g2d.drawImage(image, 0, 0, null); g2d.rotate(-angleValue); g2d.translate(-x, -y); } } }; frame.setContentPane(pane); frame.setVisible(true); Thread thread = new Thread() { @Override public void run() { while (true) { try { Thread.sleep(10); } catch (Exception ex) { ex.printStackTrace(); } pane.repaint(); } } }; thread.start(); } }
快快运行代码,让雪花飘起来吧!
如果愿意折腾,还可以修改代码中的:
private int count = 50,调整雪花的数量;
修改angles[i] += i / 5,调整雪花翻滚的速度;
修改snowY[i] += 5,调整雪花下坠的速度;
修改snowX[i] += TWaverUtil.getRandomInt(5) – 3,调整雪花左右摆动的速度;
别说你不知道怎么结束程序啊,不会Alt+F4的话,你这个程序员肯定不合格了。
秘密背后的秘密
当把透明窗口Frame设置特别大以后(例如10000*10000),你会发现不但界面变得极其缓慢,而且还会内存溢出。Sun的秘密不言自明了:还是使用了BufferedImage。否则,鼠标点击你画的椭圆或桌面的图标,它如何知道是点击了窗体,还是操作了桌面?只能生成内存图片,在里面进行像素判断了。要挖掘再深入的秘密,我也不清楚了,自己继续探索吧!相关文章推荐
- java在线聊天项目0.1版本 制作客户端窗体,使用swing(用户界面开发工具包)和awt(抽象窗口工具包)
- 用C#.net轻松制作不规则窗体
- JDK 6 u10 中 Swing最新特性:增加透明窗体及不规则窗体功能
- C# winform中不规则窗体制作的解决方案,方案二[转]
- swing窗体制作及系统编程中的窗体切换及关闭的实现
- java在线聊天项目0.2版本 制作客户端窗体,使用swing(用户界面开发工具包)和awt(抽象窗口工具包) BorderLayout布局与GridLayout布局不同之处 JPanel设置大小
- 详解使用C#制作不规则窗体的方法
- C# winform中不规则窗体制作的解决方案(已经解决24位色以上不能正常显示问题)
- C# 制作不规则窗体的两种解决方案
- C#制作不规则窗体的简单方法
- QT制作不规则窗体
- C# winform中不规则窗体制作的解决方案(已经解决24位色以上不能正常显示问题)
- JavaSwing不规则窗体
- C# winform中不规则窗体制作的解决方案(已经解决24位色以上不能正常显示问题)
- [转]用C# Builder制作不规则窗体
- Winform中不规则窗体制作的解决方案
- 利用位图制作不规则窗体
- C# winform中不规则窗体制作的解决方案 转
- Winform中不规则窗体制作的解决方案(续)
- 自己制作不规则窗体