Swing/MenuBarBackground のバックアップの現在との差分(No.9)
- バックアップ一覧
- 差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- バックアップ を表示
- Swing/MenuBarBackground へ行く。
- 1 (2009-08-10 (月) 15:27:32)
- 2 (2010-01-09 (土) 23:08:42)
- 3 (2010-06-10 (木) 15:34:46)
- 4 (2011-05-10 (火) 23:27:28)
- 5 (2011-09-26 (月) 21:12:32)
- 6 (2011-10-11 (火) 17:11:08)
- 7 (2011-10-19 (水) 00:35:36)
- 8 (2011-12-20 (火) 18:08:56)
- 9 (2012-02-28 (火) 21:24:03)
- 10 (2013-01-06 (日) 21:32:50)
- 11 (2013-01-07 (月) 00:33:12)
- 12 (2013-02-26 (火) 19:51:14)
- 13 (2014-11-20 (木) 01:49:24)
- 14 (2014-11-30 (日) 00:52:48)
- 15 (2015-01-25 (日) 18:28:41)
- 16 (2015-04-01 (水) 20:09:52)
- 17 (2015-04-05 (日) 23:10:01)
- 18 (2016-01-17 (日) 02:07:31)
- 19 (2016-07-20 (水) 20:41:36)
- 20 (2016-07-20 (水) 22:02:52)
- 21 (2017-09-27 (水) 19:01:44)
- 22 (2017-10-27 (金) 16:26:13)
- 23 (2017-11-02 (木) 15:38:08)
- 24 (2018-02-24 (土) 19:51:30)
- 25 (2018-05-31 (木) 14:36:14)
- 26 (2020-05-22 (金) 17:41:59)
- 27 (2021-11-10 (水) 12:39:18)
- 28 (2022-08-20 (土) 22:15:25)
- 29 (2024-02-09 (金) 13:57:13)
- 追加された行はこの色です。
- 削除された行はこの色です。
TITLE:JMenuBarの背景に画像を表示する #navi(../) RIGHT:Posted by [[aterai]] at 2009-08-10 *JMenuBarの背景に画像を表示する [#wd4f8033] 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: https://lh3.googleusercontent.com/_9Z4BYR88imo/TQTPxQA13fI/AAAAAAAAAeg/SAN79wHPkQc/s800/MenuBarBackground.png hreflang: href: https://java-swing-tips.blogspot.com/2009/08/jmenubar-background-image.html lang: en --- * 概要 [#summary] `JMenu`が未選択状態の場合はその背景を透明にし、`JMenuBar`の背景に設定した画像を表示可能にします。 -&jnlp; -&jar; -&zip; #download(https://lh3.googleusercontent.com/_9Z4BYR88imo/TQTPxQA13fI/AAAAAAAAAeg/SAN79wHPkQc/s800/MenuBarBackground.png) //#screenshot #ref(http://lh3.ggpht.com/_9Z4BYR88imo/TQTPxQA13fI/AAAAAAAAAeg/SAN79wHPkQc/s800/MenuBarBackground.png) **サンプルコード [#d260e806] #code{{ * サンプルコード [#sourcecode] #code(link){{ 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; } 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; } }} **解説 [#xdc98524] 上記のサンプルでは、JMenuBarに画像を描画し、これに追加するJMenuを通常は透明、選択されたときなどは不透明となるようにsetOpaqueメソッドで切り替えています。 * 解説 [#explanation] 上記のサンプルでは、`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`を透明にする場合のテスト #code{{ import java.awt.*; import java.awt.image.*; import java.util.Objects; 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)); import javax.swing.plaf.*; public class MenuBarRootPaneTest { private static final Color ALPHA_ZERO = new Color(0x0, true); private static final Color POPUP_BACK = new Color(0, 0, 0, 100); 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; } 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(); } 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()); 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); 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); 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(); } @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(); // 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); @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); } @Override protected void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D) g.create(); g2.setPaint(POPUP_BACK); g2.fillRect(0, 0, getWidth(), getHeight()); g2.dispose(); } } } }} //**参考リンク **コメント [#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 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; protected TransparentMenu(String title) { super(title); } @Override public boolean isOpaque() { return false; } // 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()); } @Override public JPopupMenu getPopupMenu() { ensurePopupMenuCreated(); return popupMenu; } @Override public JMenuItem add(JMenuItem menuItem) { ensurePopupMenuCreated(); menuItem.setOpaque(false); return popupMenu.add(menuItem); } @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; @Override public void addSeparator() { ensurePopupMenuCreated(); popupMenu.addSeparator(); } @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); } @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; } @Override public void insertSeparator(int index) { if (index < 0) { throw new IllegalArgumentException("index less than zero."); } ensurePopupMenuCreated(); popupMenu.insert(new JPopupMenu.Separator(), index); } @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; } 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); } } // //https://ateraimemo.com/Swing/TranslucentPopupMenu.html // class TranslucentPopupMenu extends JPopupMenu { }} - Windows7 のLnFでうまくいかない場合があるようなので、すこし修正。 -- [[aterai]] &new{2011-09-26 (月) 21:13:47}; * 参考リンク [#reference] - [https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/AbstractButton.html#fireStateChanged-- AbstractButton#fireStateChanged() (Java Platform SE 8)] - [[JRootPaneの背景として画像を表示>Swing/RootPaneBackground]] * コメント [#comment] #comment - 選択状態を半透明にするテスト -- &user(aterai); &new{2010-01-09 (土) 23:08:42}; -- `Windows7`での`WindowsLookAndFeel`でうまくいかない場合があるようなので、すこし修正。 -- &user(aterai); &new{2011-09-26 (月) 21:13:47}; -- [[JRootPaneの背景として画像を表示>Swing/RootPaneBackground]]に移動 #comment