在Windows的“開始”菜單上,會在菜單左側顯示一幅圖像。很多基于Windows的軟件也有類似效果的菜單。用Java Swing可以制作出類似效果的菜單嗎?答案當然是肯定的,而且非常簡單。
我們首先從Swing的JPopupMenu組件進行擴展,讓其接受一個圖片,顯示在左側;或者接受一個字符串,動態生成圖片后,在顯示在左側。為了避免準備圖片的麻煩,我們就以動態生成內存圖片為例,編寫一個JImagedPopupMenu類。
JImagedPopupMenu在創建時可以接受一個字符串,生成一副內存圖片BufferedImage。然后,我們需要覆蓋JComponent的getInsets方法,重新計算Inset的left值,將其在原數值基礎上加上圖片的寬度,然后返回:
1
public Insets getInsets() {
2
Insets insets = (Insets)super.getInsets().clone();
3
insets.left += imageIcon.getIconWidth();
4
return insets;
5
}
最后,覆蓋paintComponent方法,在原基礎上增加圖片的繪制:
2

3

4

5

1
public void paintComponent(Graphics g) {
2
super.paintComponent(g);
3
if (imageIcon != null) {
4
Insets insets = getInsets();
5
g.drawImage(imageIcon.getImage(),
6
insets.left - imageIcon.getIconWidth(),
7
insets.top,
8
null);
9
}
10
}

2

3

4

5

6

7

8

9

10

完整代碼如下:
1
import java.awt.*;
2
import java.awt.event.*;
3
import java.awt.geom.*;
4
import java.awt.image.*;
5
import javax.swing.*;
6
7
public class JImagedPopupMenu extends JPopupMenu {
8
9
private Font font = new Font("微軟雅黑", Font.BOLD, 16);
10
private ImageIcon imageIcon = null;
11
12
public JImagedPopupMenu(ImageIcon imageIcon) {
13
this.imageIcon = imageIcon;
14
}
15
16
public JImagedPopupMenu(String text) {
17
this.imageIcon = createImage(text);
18
}
19
20
private ImageIcon createImage(String text) {
21
BufferedImage bi = new BufferedImage(30, 1000, BufferedImage.TYPE_INT_ARGB);
22
ImageIcon image = new ImageIcon(bi);
23
Graphics2D g2d = bi.createGraphics();
24
25
GradientPaint paint = new GradientPaint(0, 0, Color.green.darker(), 30, 10, Color.yellow.brighter(), true);
26
g2d.setPaint(paint);
27
28
g2d.fillRect(0, 0, bi.getWidth(), bi.getHeight());
29
30
AffineTransform at = new AffineTransform();
31
at.rotate(-Math.PI / 2);
32
33
g2d.setTransform(at);
34
g2d.setColor(Color.darkGray);
35
g2d.setFont(font);
36
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
37
g2d.drawString(text, -150, bi.getWidth() / 2 + 5);
38
39
return image;
40
}
41
42
@Override
43
public Insets getInsets() {
44
Insets insets = (Insets) super.getInsets().clone();
45
insets.left += imageIcon.getIconWidth();
46
return insets;
47
}
48
49
@Override
50
public void paint(Graphics g) {
51
super.paint(g);
52
if (imageIcon != null) {
53
Insets insets = getInsets();
54
g.drawImage(imageIcon.getImage(),
55
insets.left - imageIcon.getIconWidth(),
56
insets.top,
57
null);
58
}
59
}
60
61
public static void main(String[] args) {
62
final JFrame frame = new JFrame();
63
frame.setSize(600, 400);
64
frame.setTitle("TWaver中文社區之Swing探秘");
65
final JImagedPopupMenu menu = new JImagedPopupMenu("TWaver中文社區");
66
menu.add(new JMenuItem("Winzip 8.0"));
67
menu.addSeparator();
68
menu.add(new JMenuItem("Programs"));
69
menu.add(new JMenuItem("Document"));
70
menu.add(new JMenuItem("Settings"));
71
menu.add(new JMenuItem("Search"));
72
menu.add(new JMenuItem("Help and Support"));
73
menu.add(new JMenuItem("Run
"));
74
menu.addSeparator();
75
menu.add(new JMenuItem("Shut Down
"));
76
JLabel label = new JLabel("Right click me to show image popup menu.");
77
label.addMouseListener(new java.awt.event.MouseAdapter() {
78
79
public void mouseReleased(MouseEvent e) {
80
if (e.isPopupTrigger()) {
81
menu.show(frame, e.getPoint().x, e.getPoint().y);
82
}
83
}
84
});
85
frame.getContentPane().add(label, BorderLayout.CENTER);
86
frame.show();
87
}
88
}

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

運行效果如下: