TITLE:JMenuBarの背景に画像を表示する

Posted by terai at 2009-08-10

JMenuBarの背景に画像を表示する

JMenuBarの背景に画像を表示します。

  • &jnlp;
  • &jar;
  • &zip;

#screenshot

サンプルコード

public JMenuBar createMenubar() {
  final TexturePaint texture = makeTexturePaint();
  JMenuBar mb = new JMenuBar() {
    @Override protected void paintComponent(Graphics g) {
      Graphics2D g2 = (Graphics2D)g;
      g2.setPaint(texture);
      g2.fillRect(0, 0, getWidth(), getHeight());
      super.paintComponent(g);
    }
  };
  mb.setOpaque(false);
  String[] menuKeys = {"File", "Edit", "Help"};
  for(String key: menuKeys) {
    JMenu m = createMenu(key);
    if(m != null) mb.add(m);
  }
  return mb;
}
private JMenu createMenu(String key) {
  JMenu menu = new JMenu(key) {
    @Override protected void fireStateChanged() {
      ButtonModel m = getModel();
      if(m.isPressed() && m.isArmed()) {
        setOpaque(true);
      }else if(m.isSelected()) {
        setOpaque(true);
      }else if(isRolloverEnabled() && m.isRollover()) {
        setOpaque(true);
      }else{
        setOpaque(false);
      }
      super.fireStateChanged();
    };
  };
  menu.setBackground(new Color(0,0,0,0)); //XXX windows lnf?
  menu.add("dummy1"); menu.add("dummy2"); menu.add("dummy3");
  return menu;
}

解説

上記のサンプルでは、JMenuBarに画像を描画し、これに追加するJMenuを通常は透明、選択されたときなどは不透明となるようにsetOpaqueメソッドで切り替えています。

  • 注意点
    • Windows LnF の場合、JMenu#setBackground(new Color(0,0,0,0)); とする必要がある?
    • Nimbus LnF には対応していない

コメント

  • 選択状態を半透明にするテスト -- terai
    import java.awt.*;
    import java.awt.event.*;
    import java.awt.image.*;
    import java.awt.geom.*;
    import javax.swing.*;
    public class MenuBarBackgroundTest{
      public JComponent makeUI() {
        final TexturePaint texture = makeTexturePaint();
        JPanel p = new JPanel(new BorderLayout()) {
          @Override protected void paintComponent(Graphics g) {
            Graphics2D g2 = (Graphics2D)g;
            g2.setPaint(texture);
            g2.fillRect(0, 0, getWidth(), getHeight());
            super.paintComponent(g);
          }
        };
        p.setOpaque(false);
        p.add(createMenubar(), BorderLayout.NORTH);
        return p;
      }
      public static JMenuBar createMenubar() {
        UIManager.put("Menu.background", new Color(200,0,0,0));
        UIManager.put("Menu.selectionBackground", new Color(0,0,100,100));
        UIManager.put("Menu.selectionForeground", new Color(0,200,0));
        UIManager.put("Menu.useMenuBarBackgroundForTopLevel", Boolean.TRUE);
        JMenuBar mb = new JMenuBar();
        mb.setOpaque(false);
        for(String key: new String[] {"File", "Edit", "Help"}) {
          JMenu m = createMenu(key);
          if(m != null) mb.add(m);
        }
        return mb;
      }
      private static JMenu createMenu(String key) {
        final JMenu menu = new JMenu(key) {
           @Override protected void fireStateChanged() {
             ButtonModel m = getModel();
             if(m.isPressed() && m.isArmed()) {
               setOpaque(true);
             }else if(m.isSelected()) {
               setOpaque(true);
             }else if(isRolloverEnabled() && m.isRollover()) {
               setOpaque(true);
             }else{
               setOpaque(false);
             }
             super.fireStateChanged();
           }
        };
        menu.addMouseListener(new MouseAdapter() {
          public void mouseEntered(MouseEvent e) {
            if(menu.getModel().isSelected()) {
              menu.setOpaque(false);
            }
          }
          public void mouseExited(MouseEvent e) {
            menu.setOpaque(false);
          }
        });
        menu.add("dummy1"); menu.add("dummy2"); menu.add("dummy3");
        return menu;
      }
      private static BufferedImage makeBGImage() {
        Color color = new Color(200,150,100,50);
        int cs = 6, sz = cs*cs;
        BufferedImage img = new BufferedImage(sz,sz,BufferedImage.TYPE_4BYTE_ABGR);
        Graphics2D g2 = img.createGraphics();
        g2.setPaint(color);
        g2.fillRect(0,0,sz,sz);
        for(int i=0;i*cs<sz;i++) {
          for(int j=0;j*cs<sz;j++) {
            if((i+j)%2==0) g2.fillRect(i*cs, j*cs, cs, cs);
          }
        }
        g2.dispose();
        return img;
      }
      private static TexturePaint makeTexturePaint() {
        BufferedImage img = makeBGImage();
        int w = img.getWidth(), h = img.getHeight();
        Rectangle2D r2d = new Rectangle2D.Float(0,0,w,h);
        return new TexturePaint(img, r2d);
      }
      public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
          public void run() { createAndShowGUI(); }
        });
      }
      public static void createAndShowGUI() {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }catch(Exception e) {
            e.printStackTrace();
        }
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.getContentPane().add(new MenuBarBackgroundTest().makeUI());
        frame.setSize(320,240);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
      }
    }