效果如下:
在Windows的“开始”菜单上,会在菜单左侧显示一幅图像。很多基于Windows的软件也有类似效果的菜单。用Java Swing可以制作出类似效果的菜单吗?答案当然是肯定的,而且非常简单。
我们首先从Swing的JPopupMenu组件进行扩展,让其接受一个图片,显示在左侧;或者接受一个字符串,动态生成图片后,在显示在左侧。为 了避免准备图片的麻烦,我们就以动态生成内存图片为例,编写一个JImagedPopupMenu类。
JImagedPopupMenu在创建时可以接受一个字符串,生成一副内存图片BufferedImage。然后,我们需要覆盖JComponent的getInsets方法,重新计算Inset的left值,将其在原数值基础上加上图片的宽度,然后返回:
public Insets getInsets() { Insets insets = (Insets)super.getInsets().clone(); insets.left += imageIcon.getIconWidth(); return insets; }
最后,覆盖paintComponent方法,在原基础上增加图片的绘制:
public void paintComponent(Graphics g) { super.paintComponent(g); if (imageIcon != null) { Insets insets = getInsets(); g.drawImage(imageIcon.getImage(), insets.left - imageIcon.getIconWidth(), insets.top, null); } }
完整代码如下:
import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import java.awt.image.*; import javax.swing.*; public class JImagedPopupMenu extends JPopupMenu { private static final long serialVersionUID = 1L; private Font font = new Font("Dialog", Font.BOLD, 13); private ImageIcon imageIcon = null; public JImagedPopupMenu(ImageIcon imageIcon) { this.imageIcon = imageIcon; } public JImagedPopupMenu(String text) { this.imageIcon = createImage(text); } private ImageIcon createImage(String text) { BufferedImage bi = new BufferedImage(30, 1000, BufferedImage.TYPE_INT_ARGB); ImageIcon image = new ImageIcon(bi); Graphics2D g2d = bi.createGraphics(); GradientPaint paint = new GradientPaint(0, 0, Color.yellow, 30, 10, Color.red, true); g2d.setPaint(paint); g2d.fillRect(0, 0, bi.getWidth(), bi.getHeight()); AffineTransform at = new AffineTransform(); at.rotate(-Math.PI / 2); g2d.setTransform(at); g2d.setColor(Color.white); g2d.setFont(font); g2d.drawString(text, -180, bi.getWidth() / 2); return image; } @Override public Insets getInsets() { Insets insets = (Insets) super.getInsets().clone(); insets.left += imageIcon.getIconWidth(); return insets; } @Override public void paint(Graphics g) { super.paint(g); if (imageIcon != null) { Insets insets = getInsets(); g.drawImage(imageIcon.getImage(), insets.left - imageIcon.getIconWidth(), insets.top, null); } } public static void main(String[] args) { final JFrame frame = new JFrame(); frame.setSize(600, 500); frame.setTitle("ImageMenu"); final JImagedPopupMenu menu = new JImagedPopupMenu( "Windows XP Perfessional"); menu.add(new JMenuItem("Winzip 8.0")); menu.addSeparator(); menu.add(new JMenuItem("Programs")); menu.add(new JMenuItem("Document")); menu.add(new JMenuItem("Settings")); menu.add(new JMenuItem("Search")); menu.add(new JMenuItem("Help and Support")); menu.add(new JMenuItem("Run...")); menu.addSeparator(); menu.add(new JMenuItem("Shut Down...")); JLabel label = new JLabel("Right click me to show image popup menu."); label.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseReleased(MouseEvent e) { if (e.isPopupTrigger()) { menu.show(frame, e.getPoint().x, e.getPoint().y); } } }); frame.getContentPane().add(label, BorderLayout.CENTER); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }