12.5.2 创建透明、不规则形状窗口

12.5.2 创建透明、不规则形状窗口

Java7Frame提供了如下两个方法:

方法 描述
void setShape(Shape shape) 设置窗口的形状,可以将窗口设置成任意不规则的形状。
void setOpacity(float opacity) 设置窗口的透明度,可以将窗口设置成半透明的。当opacity为1.0f时,该窗口完全不透明

这两个方法简单、易用,可以直接改变窗口的形状和透明度。除此之外,如果希望开发出渐变透明的窗口,则可以考虑使用一个渐变透明的JPanel来代替JFrameContentPane;按照这种思路,还可以开发出有图片背景的窗口。

程序 透明不规则窗口

下面程序示范了如何开发出透明、不规则的窗口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import java.io.*;
import java.awt.*;
import javax.imageio.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.geom.Ellipse2D;

public class NonRegularWindow extends JFrame implements ActionListener {

private static final long serialVersionUID = 8373752799905574018L;
// 定义3个窗口
JFrame transWin = new JFrame("透明窗口");
JFrame gradientWin = new JFrame("渐变透明窗口");
JFrame bgWin = new JFrame("背景图片窗口");
JFrame shapeWin = new JFrame("椭圆窗口");

public NonRegularWindow() {
super("不规则窗口测试");
setLayout(new FlowLayout());
JButton transBn = new JButton("透明窗口");
JButton gradientBn = new JButton("渐变透明窗口");
JButton bgBn = new JButton("背景图片窗口");
JButton shapeBn = new JButton("椭圆窗口");
// 为3个按钮添加事件监听器
transBn.addActionListener(this);
gradientBn.addActionListener(this);
bgBn.addActionListener(this);
shapeBn.addActionListener(this);
add(transBn);
add(gradientBn);
add(bgBn);
add(shapeBn);
// -------设置透明窗口-------
transWin.setLayout(new GridBagLayout());
transWin.setSize(300, 200);
transWin.add(new JButton("透明窗口里的简单按钮"));
// 设置透明度为0.65f,透明度为1时完全不透明。
transWin.setOpacity(0.65f);
// -------设置渐变透明的窗口-------
gradientWin.setBackground(new Color(0, 0, 0, 0));
gradientWin.setSize(new Dimension(300, 200));
// 使用一个JPanel对象作为渐变透明的背景
JPanel panel = new JPanel() {
private static final long serialVersionUID = -3046929062708838980L;

protected void paintComponent(Graphics g) {
if (g instanceof Graphics2D) {
final int R = 240;
final int G = 240;
final int B = 240;
// 创建一个渐变画笔
Paint p = new GradientPaint(0.0f, 0.0f, new Color(R, G, B, 0), 0.0f, getHeight(),
new Color(R, G, B, 255), true);
Graphics2D g2d = (Graphics2D) g;
g2d.setPaint(p);
g2d.fillRect(0, 0, getWidth(), getHeight());
}
}
};
// 使用JPanel对象作为JFrame的contentPane
gradientWin.setContentPane(panel);
panel.setLayout(new GridBagLayout());
gradientWin.add(new JButton("渐变透明窗口里的简单按钮"));
// -------设置有背景图片的窗口-------
bgWin.setBackground(new Color(0, 0, 0, 0));
bgWin.setSize(new Dimension(300, 200));
// 使用一个JPanel对象作为背景图片
JPanel bgPanel = new JPanel() {
private static final long serialVersionUID = -4650113493486706945L;

protected void paintComponent(Graphics g) {
try {
Image bg = ImageIO.read(new File("images/java.png"));
// 绘制一张图片作为背景
g.drawImage(bg, 0, 0, getWidth(), getHeight(), null);
} catch (IOException ex) {
ex.printStackTrace();
}
}
};
// 使用JPanel对象作为JFrame的contentPane
bgWin.setContentPane(bgPanel);
bgPanel.setLayout(new GridBagLayout());
bgWin.add(new JButton("有背景图片窗口里的简单按钮"));
// -------设置椭圆形窗口-------
shapeWin.setLayout(new GridBagLayout());
shapeWin.setUndecorated(true);
shapeWin.setOpacity(0.7f);
// 通过为shapeWin添加监听器来设置窗口的形状。
// 当shapeWin窗口的大小被改变时,程序动态设置该窗口的形状
shapeWin.addComponentListener(new ComponentAdapter() {
// 当窗口大小被改变时,椭圆的大小也会相应地改变
public void componentResized(ComponentEvent e) {
// 设置窗口的形状
shapeWin.setShape(new Ellipse2D.Double(0, 0, shapeWin.getWidth(), shapeWin.getHeight())); // ①
}
});
shapeWin.setSize(300, 200);
shapeWin.add(new JButton("椭圆形窗口里的简单按钮"));
// -------设置主程序的窗口-------
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}

public void actionPerformed(ActionEvent event) {
switch (event.getActionCommand()) {
case "透明窗口":
transWin.setVisible(true);
break;
case "渐变透明窗口":
gradientWin.setVisible(true);
break;
case "背景图片窗口":
bgWin.setVisible(true);
break;
case "椭圆窗口":
shapeWin.setVisible(true);
break;
}
}

public static void main(String[] args) {
JFrame.setDefaultLookAndFeelDecorated(true);
new NonRegularWindow();
}
}

上面程序中的粗体字代码就是设置透明窗口、渐变透明窗口、有背景图片窗口的关键代码;当需要开发不规则形状的窗口时,程序往往会为该窗口实现一个ComponentListener,该监听器负责监听窗口大小发生改变的事件——当窗口大小发生改变时,程序调用窗口的setShape()方法来控制窗口的形状,如①号粗体字代码所示。
运行上面程序,打开透明窗口和渐变透明窗口,效果如图12.27所示。
这里有一张图片
打开有背景图片窗口和椭圆窗口,效果如图12.28所示。
这里有一张图片