• 追加された行はこの色です。
  • 削除された行はこの色です。
TITLE:JMenuBarの背景に画像を表示する
#navi(../)
RIGHT:Posted by [[aterai]] at 2009-08-10
*JMenuBarの背景に画像を表示する [#wd4f8033]
JMenuBarの背景に画像を表示します。

-&jnlp;
-&jar;
-&zip;

//#screenshot
#ref(http://lh3.ggpht.com/_9Z4BYR88imo/TQTPxQA13fI/AAAAAAAAAeg/SAN79wHPkQc/s800/MenuBarBackground.png)

**サンプルコード [#d260e806]
#code{{
public JMenuBar createMenubar() {
  final TexturePaint texture = makeTexturePaint();
  JMenuBar mb = new JMenuBar() {
    @Override protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D)g;
      g2.setPaint(texture);
      g2.fillRect(0, 0, getWidth(), getHeight());
    }
  };
  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();
    };
  };
  if("Windows XP".equals(System.getProperty("os.name"))) {
    menu.setBackground(new Color(0,0,0,0)); //XXX Windows XP lnf?
  }
  menu.add("dummy1"); menu.add("dummy2"); menu.add("dummy3");
  return menu;
}
}}

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

-注意点
--Windows LnF の場合、JMenu#setBackground(new Color(0,0,0,0)); とする必要がある?
--%%Nimbus LnF には対応していない%%
--Windows LnF に切り替えた直後、メニューの文字色などがおかしい?

----
JFrame#setJMenuBar()で追加したJMenuBarを透明にする場合のテスト(NimbusLnF)
#code{{
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
public class MenuBarRootPaneTest{
  private static JMenuBar createMenubar() {
    JMenuBar mb = new JMenuBar();
    mb.setOpaque(false);
    mb.setBackground(new Color(0,0,0,0));
    String[] menuKeys = {"File", "Edit", "Help"};
    for(String key: menuKeys) {
      JMenu m = createMenu(key);
      if(m != null) mb.add(m);
    }
    return mb;
  }
  private static JMenu createMenu(String key) {
    JMenu menu = new JMenu(key);
    menu.setForeground(Color.WHITE);
    menu.add("dummy1"); menu.add("dummy2"); menu.add("dummy3");
    return menu;
  }
  public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
      @Override public void run() {
        createAndShowGUI();
      }
    });
  }
  public static void createAndShowGUI() {
    try {
      for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels())
        if ("Nimbus".equals(laf.getName()))
          UIManager.setLookAndFeel(laf.getClassName());
    }catch(Exception e) {
      e.printStackTrace();
    }
    JFrame frame = new JFrame();
    frame.getRootPane().setBackground(Color.RED);
    //frame.getLayeredPane().setBackground(Color.GREEN);
    //frame.getContentPane().setBackground(Color.BLUE);
    ((JComponent)frame.getContentPane()).setOpaque(false);
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    frame.setJMenuBar(createMenubar());
    frame.setSize(320, 240);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
  }
}
}}

//**参考リンク
**コメント [#z71d0296]
- 選択状態を半透明にするテスト -- [[aterai]] &new{2010-01-09 (土) 23:08:42};
#code{{
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.awt.geom.*;
import javax.swing.*;
public class MenuBarBackgroundTest{
public class MenuBarBackgroundTest {
  public JComponent makeUI() {
    final TexturePaint texture = makeTexturePaint();
    JPanel p = new JPanel(new BorderLayout()) {
      @Override protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        g2.setPaint(texture);
        g2.fillRect(0, 0, getWidth(), getHeight());
      }
    };
    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(200,0,0));
    UIManager.put("Menu.useMenuBarBackgroundForTopLevel", Boolean.TRUE);
        JMenuBar mb = new JMenuBar() {
            private final TexturePaint texture = makeTexturePaint();
            @Override protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2 = (Graphics2D)g;
                g2.setPaint(texture);
                g2.fillRect(0, 0, getWidth(), getHeight());
            }
        };
        mb.setOpaque(false);
    JMenuBar mb = new JMenuBar() {
      private final TexturePaint texture = makeTexturePaint();
      @Override protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        g2.setPaint(texture);
        g2.fillRect(0, 0, getWidth(), getHeight());
      }
    };
    mb.setOpaque(false);
    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);
    menu.add("dummy1"); menu.add("dummy2"); menu.add("dummy3");
    menu.add("dummy1");
    menu.add("dummy2");
    menu.add("dummy3");
    return menu;
  }
  private static TexturePaint makeTexturePaint() {
    int cs = 6, sz = cs*cs;
    BufferedImage img = new BufferedImage(sz,sz,BufferedImage.TYPE_4BYTE_ABGR);
    Graphics2D g2 = img.createGraphics();
    g2.setPaint(new Color(200,150,100,50));
    g2.fillRect(0,0,sz,sz);
    for(int i=0;i*cs<sz;i++) {
      for(int j=0;j*cs<sz;j++) {
    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 new TexturePaint(img, new Rectangle(0,0,sz,sz));
  }
  public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
      @Override public void run() { createAndShowGUI(); }
      @Override public void run() {
        createAndShowGUI();
      }
    });
  }
  public static void createAndShowGUI() {
    try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    }catch(Exception e) {
        e.printStackTrace();
      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);
  }
}
}}
- Windows7 のLnFでうまくいかない場合があるようなので、すこし修正。 -- [[aterai]] &new{2011-09-26 (月) 21:13:47};

#comment