Swing/MenuBarBackground のバックアップの現在との差分(No.9)
TITLE:JMenuBarの背景に画像を表示する
Posted by aterai at 2009-08-10
JMenuBarの背景に画像を表示する
JMenuBarの背景に画像を表示します。-
category: swing
folder: MenuBarBackground
title: JMenuBarの背景に画像を表示する
tags: [JMenuBar, JMenu, JMenuItem, TexturePaint]
author: aterai
pubdate: 2009-08-10T15:27:32+09:00
description: JMenuが未選択状態の場合はその背景を透明にし、JMenuBarの背景に設定した画像を表示可能にします。
image:
hreflang:
href: https://java-swing-tips.blogspot.com/2009/08/jmenubar-background-image.html lang: en
概要
JMenu
が未選択状態の場合はその背景を透明にし、JMenuBar
の背景に設定した画像を表示可能にします。
- &jnlp;
- &jar;
- &zip;
Screenshot
Advertisement
サンプルコード
#spanend
#spanadd
* サンプルコード [#sourcecode]
#spanend
#spanadd
#code(link){{
#spanend
public JMenuBar createMenubar() {
final TexturePaint texture = makeTexturePaint();
JMenuBar mb = new JMenuBar() {
@Override protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
Graphics2D g2 = (Graphics2D) g.create();
g2.setPaint(texture);
g2.fillRect(0, 0, getWidth(), getHeight());
g2.dispose();
}
};
mb.setOpaque(false);
String[] menuKeys = {"File", "Edit", "Help"};
for(String key: menuKeys) {
for (String key: menuKeys) {
JMenu m = createMenu(key);
if(m != null) mb.add(m);
if (m != null) {
mb.add(m);
}
}
return mb;
}
#spanadd
#spanend
private JMenu createMenu(String key) {
JMenu menu = new JMenu(key) {
@Override protected void fireStateChanged() {
ButtonModel m = getModel();
if(m.isPressed() && m.isArmed()) {
if (m.isPressed() && m.isArmed()) {
setOpaque(true);
}else if(m.isSelected()) {
} else if (m.isSelected()) {
setOpaque(true);
}else if(isRolloverEnabled() && m.isRollover()) {
} else if (isRolloverEnabled() && m.isRollover()) {
setOpaque(true);
}else{
} 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?
if ("Windows XP".equals(System.getProperty("os.name"))) {
menu.setBackground(new Color(0x0, true)); // XXX: Windows XP lnf?
}
menu.add("dummy1"); menu.add("dummy2"); menu.add("dummy3");
menu.add("JMenuItem1");
menu.add("JMenuItem2");
menu.add("JMenuItem3");
return menu;
}
解説
上記のサンプルでは、JMenuBarに画像を描画し、これに追加するJMenuを通常は透明、選択されたときなどは不透明となるようにsetOpaqueメソッドで切り替えています。解説
上記のサンプルでは、JMenuBar
に画像を描画し、これに追加するJMenu
を通常は透明、選択されたときなどは不透明となるようにsetOpaque
メソッドで切り替えています。
- 注意点
- Windows LnF の場合、JMenu#setBackground(new Color(0,0,0,0)); とする必要がある?
Nimbus LnF には対応していない- Windows LnF に切り替えた直後、メニューの文字色などがおかしい?
-
WindowsLookAndFeel
の場合、JMenu#setBackground(new Color(0x0, true))
を設定する必要がある -
WindowsLookAndFeel
に切り替えた直後のメニュー文字色などがおかしい?
JFrame#setJMenuBar()で追加したJMenuBarを透明にする場合のテスト(NimbusLnF)
- 以下は
JFrame#setJMenuBar()
で追加したJMenuBar
を透明にする場合のテスト
import java.awt.*;
import java.awt.image.*;
#spanadd
import java.util.Objects;
#spanend
import javax.swing.*;
#spandel
public class MenuBarRootPaneTest{
#spanend
private static JMenuBar createMenubar() {
JMenuBar mb = new JMenuBar();
mb.setOpaque(false);
mb.setBackground(new Color(0,0,0,0));
#spanadd
import javax.swing.plaf.*;
#spanend
#spanadd
#spanend
#spanadd
public class MenuBarRootPaneTest {
#spanend
private static final Color ALPHA_ZERO = new Color(0x0, true);
private static final Color POPUP_BACK = new Color(0, 0, 0, 100);
#spanadd
#spanend
private static JMenuBar createMenuBar() {
JMenuBar mb = new JMenuBar() {
@Override public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
d.height = 30;
return d;
}
};
mb.setBackground(POPUP_BACK);
String[] menuKeys = {"File", "Edit", "Help"};
for(String key: menuKeys) {
JMenu m = createMenu(key);
if(m != null) mb.add(m);
for (String key : menuKeys) {
mb.add(createMenu(key));
}
return mb;
}
#spanadd
#spanend
private static JMenu createMenu(String key) {
JMenu menu = new JMenu(key);
menu.setForeground(Color.WHITE);
menu.add("dummy1"); menu.add("dummy2"); menu.add("dummy3");
JMenu menu = new TransparentMenu(key);
menu.add(new JMenuItem("JMenuItem1"));
menu.add(new JMenuItem("JMenuItem2"));
menu.add(new JMenuItem("JMenuItem3"));
return menu;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override public void run() {
createAndShowGUI();
}
#spanadd
#spanend
public static void main(String... args) {
EventQueue.invokeLater(() -> {
UIManager.put("MenuBar.background", POPUP_BACK);
UIManager.put("MenuBar.border", BorderFactory.createEmptyBorder());
UIManager.put("PopupMenu.border", BorderFactory.createEmptyBorder());
#spanadd
#spanend
UIManager.put("Menu.foreground", Color.WHITE);
UIManager.put("Menu.background", ALPHA_ZERO);
UIManager.put("Menu.selectionBackground", POPUP_BACK);
UIManager.put("Menu.selectionForeground", Color.WHITE);
UIManager.put("Menu.borderPainted", Boolean.FALSE);
#spanadd
#spanend
UIManager.put("MenuItem.foreground", Color.WHITE);
UIManager.put("MenuItem.background", ALPHA_ZERO);
UIManager.put("MenuItem.selectionBackground", POPUP_BACK);
UIManager.put("MenuItem.selectionForeground", Color.WHITE);
UIManager.put("MenuItem.borderPainted", Boolean.FALSE);
#spanadd
#spanend
JFrame frame = new JFrame() {
@Override protected JRootPane createRootPane() {
return new JRootPane() {
private final TexturePaint texture = makeTexturePaint();
@Override protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
g2.setPaint(texture);
g2.fillRect(0, 0, getWidth(), getHeight());
g2.dispose();
}
#spanadd
#spanend
@Override public boolean isOpaque() {
return true;
}
};
}
};
frame.getRootPane().setBackground(Color.BLUE);
frame.getLayeredPane().setBackground(Color.GREEN);
frame.getContentPane().setBackground(Color.RED);
((JComponent) frame.getContentPane()).setOpaque(false);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setJMenuBar(createMenuBar());
frame.setSize(320, 240);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
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();
#spanadd
#spanend
// TranslucentPopupMenu
// https://ateraimemo.com/Swing/TranslucentPopupMenu.html
static class TranslucentPopupMenu extends JPopupMenu {
@Override public boolean isOpaque() {
return false;
}
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);
#spanadd
#spanend
@Override public void show(Component c, int x, int y) {
EventQueue.invokeLater(() -> {
Container p = getTopLevelAncestor();
if (p instanceof JWindow) {
System.out.println("Heavy weight");
((JWindow) p).setBackground(ALPHA_ZERO);
}
});
super.show(c, x, y);
}
#spanadd
#spanend
@Override protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setPaint(POPUP_BACK);
g2.fillRect(0, 0, getWidth(), getHeight());
g2.dispose();
}
}
#spandel
}
#spanend
#spandel
コメント
- 選択状態を半透明にするテスト -- aterai
#spanend #spandel import java.awt.*; #spanend #spandel import java.awt.event.*; #spanend #spandel import java.awt.image.*; #spanend #spandel import java.awt.geom.*; #spanend #spandel import javax.swing.*; #spanend #spandel public class MenuBarBackgroundTest { #spanend 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()); static class TransparentMenu extends JMenu { private JPopupMenu popupMenu; #spanadd #spanend protected TransparentMenu(String title) { super(title); } #spanadd #spanend @Override public boolean isOpaque() { return false; } #spanadd #spanend // Bug ID: JDK-4688783 JPopupMenu hardcoded i JMenu // https://bugs.openjdk.org/browse/JDK-4688783 private void ensurePopupMenuCreated() { if (Objects.isNull(popupMenu)) { this.popupMenu = new TranslucentPopupMenu(); popupMenu.setInvoker(this); popupListener = createWinListener(popupMenu); } }; 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()); } #spanadd #spanend @Override public JPopupMenu getPopupMenu() { ensurePopupMenuCreated(); return popupMenu; } #spanadd #spanend @Override public JMenuItem add(JMenuItem menuItem) { ensurePopupMenuCreated(); menuItem.setOpaque(false); return popupMenu.add(menuItem); } #spanadd #spanend @Override public Component add(Component c) { ensurePopupMenuCreated(); if (c instanceof JComponent) { ((JComponent) c).setOpaque(false); } }; mb.setOpaque(false); mb.setOpaque(false); for(String key: new String[] {"File", "Edit", "Help"}) { JMenu m = createMenu(key); if(m != null) mb.add(m); popupMenu.add(c); return c; } return mb; #spanadd #spanend @Override public void addSeparator() { ensurePopupMenuCreated(); popupMenu.addSeparator(); } #spanadd #spanend @Override public void insert(String s, int pos) { if (pos < 0) { throw new IllegalArgumentException("index less than zero."); } ensurePopupMenuCreated(); popupMenu.insert(new JMenuItem(s), pos); } #spanadd #spanend @Override public JMenuItem insert(JMenuItem mi, int pos) { if (pos < 0) { throw new IllegalArgumentException("index less than zero."); } ensurePopupMenuCreated(); popupMenu.insert(mi, pos); return mi; } #spanadd #spanend @Override public void insertSeparator(int index) { if (index < 0) { throw new IllegalArgumentException("index less than zero."); } ensurePopupMenuCreated(); popupMenu.insert(new JPopupMenu.Separator(), index); } #spanadd #spanend @Override public boolean isPopupMenuVisible() { ensurePopupMenuCreated(); return popupMenu.isVisible(); } } private static JMenu createMenu(String key) { final JMenu menu = new JMenu(key); menu.add("dummy1"); menu.add("dummy2"); menu.add("dummy3"); return menu; } #spanadd #spanend private static TexturePaint makeTexturePaint() { int cs = 6, sz = cs*cs; BufferedImage img = new BufferedImage(sz,sz,BufferedImage.TYPE_4BYTE_ABGR); int cs = 6; int sz = cs * cs; BufferedImage img = new BufferedImage(sz, sz, BufferedImage.TYPE_INT_ARGB); 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++) { if((i+j)%2==0) g2.fillRect(i*cs, j*cs, cs, cs); g2.setPaint(new Color(222, 222, 222, 50)); 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 new TexturePaint(img, new Rectangle(0,0,sz,sz)); return new TexturePaint(img, new Rectangle(sz, sz)); } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override 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); } } #spanadd #spanend #spanadd // //https://ateraimemo.com/Swing/TranslucentPopupMenu.html #spanend #spanadd // class TranslucentPopupMenu extends JPopupMenu { #spanend
- Windows7 のLnFでうまくいかない場合があるようなので、すこし修正。 -- aterai