在程序中依次设置以下几个参数:
- 设置窗口完全透明:AWTUtilities.setWindowOpaque(frame, false);
- 设置窗口无边缘:frame.setUndecorated(true);
- 设置窗口的ContentPane为要显示的Pane:frame.setContentPane(myPane);
- 在myPane中放置具体要显示的内容,也可以重载paint方法进行Java2D绘制。这些paint会直接发生在桌面背景上。
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);
}
}
运行效果如下图:
窗口的拖拽移动
窗口不再规则,窗口标题栏不再出现,如何移动窗口?按照其他类似软件的习惯做法,应当允许用鼠标直接拖拽窗体任意位置进行窗口移动。做一个鼠标监听器对窗口中的元素进行拖动监听,对窗口进行相应拖动距离的移动:
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。
<span style="font-family:Helvetica, Tahoma, Arial, sans-serif;"><span style="font-size: 14px; line-height: 25.2000007629395px; background-color: rgb(239, 239, 239);">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());
}
</span></span><p style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="font-family:Helvetica, Tahoma, Arial, sans-serif;"><span style="line-height: 25.2000007629395px; background-color: rgb(239, 239, 239);"><span style="font-size: 14px;"> };</span><span style="font-size:18px;">
</span></span></span></p><p style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="font-family:Helvetica, Tahoma, Arial, sans-serif;"><span style="line-height: 25.2000007629395px; background-color: rgb(239, 239, 239);"></span></span><pre name="code" class="java"><p style="font-size: 14px; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;">肆虐你的桌面:六月飘雪!
既然窗户纸捅破了,在桌面上就随意折腾吧。这几天窗外酷热难耐,咱们就来个桌面飘雪,也许可以望梅止渴,带来丝丝清凉吧!
先准备一个雪花的png透明图片,然后在桌面上随机生成50个雪花坐标,每次paint让每个雪花的左右略微抖一下(snowX[i] += TWaverUtil.getRandomInt(5) - 3),垂直距离下坠5像素(snowY[i] += 5),再旋转个小角度。然后,用一个线程不停的repaint窗口。
雪花png图片:
<img alt="" src="http://dl.iteye.com/upload/attachment/274324/d1c5c45e-8f3d-3089-b2fe-0efba12deed2.png" style="border: 0px;" />
程序代码如下:</p><div style="font-size: 14px;">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();
}
}</div><div><span style="font-size:24px;color:#ff0000;">注:程序中用到的第三方jar为:twaver.jar looks.2.1.4.jar</span></div><div><span style="font-size:24px;color:#ff0000;">
</span></div>
<p style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 25.2000007629395px; background-color: rgb(239, 239, 239);">如果愿意折腾,还可以修改代码中的:</p><p style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 25.2000007629395px; background-color: rgb(239, 239, 239);"> </p><ul style="margin: 0px 0px 1.5em; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 25.2000007629395px; background-color: rgb(239, 239, 239);"><li style="margin: 0px 0px 0.25em 30px; padding: 0px;">private int count = 50,调整雪花的数量;</li><li style="margin: 0px 0px 0.25em 30px; padding: 0px;">修改angles[i] += i / 5,调整雪花翻滚的速度;</li><li style="margin: 0px 0px 0.25em 30px; padding: 0px;">修改snowY[i] += 5,调整雪花下坠的速度;</li><li style="margin: 0px 0px 0.25em 30px; padding: 0px;">修改snowX[i] += TWaverUtil.getRandomInt(5) – 3,调整雪花左右摆动的速度;</li></ul><p style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 25.2000007629395px; background-color: rgb(239, 239, 239);"> </p><p style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 25.2000007629395px; background-color: rgb(239, 239, 239);">别说你不知道怎么结束程序啊,不会Alt+F4的话,你这个程序员肯定不合格了。</p><h2 style="line-height: 1.5em; margin: 0px 0px 0.5em; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; background-color: rgb(239, 239, 239);">秘密背后的秘密</h2><p style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 25.2000007629395px; background-color: rgb(239, 239, 239);">当把透明窗口Frame设置特别大以后(例如10000*10000),你会发现不但界面变得极其缓慢,而且还会内存溢出。Sun的秘密不言自明了:还是使用了BufferedImage。否则,鼠标点击你画的椭圆或桌面的图标,它如何知道是点击了窗体,还是操作了桌面?只能生成内存图片,在里面进行像素判断了。要挖掘再深入的秘密,我也不清楚了,自己继续探索吧!</p>