Swing/TranslucentSubMenu のバックアップ(No.1)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/TranslucentSubMenu へ行く。
- 1 (2012-10-22 (月) 18:38:06)
- 2 (2012-10-22 (月) 20:22:51)
- 3 (2012-12-06 (木) 12:15:23)
- 4 (2012-12-07 (金) 16:40:20)
- 5 (2012-12-25 (火) 23:11:35)
- 6 (2012-12-26 (水) 11:24:59)
- 7 (2014-11-01 (土) 00:46:09)
- 8 (2014-12-11 (木) 15:09:07)
- 9 (2015-02-22 (日) 21:04:31)
- 10 (2016-07-20 (水) 20:33:11)
- 11 (2017-09-27 (水) 19:04:28)
- 12 (2017-11-02 (木) 15:34:40)
- 13 (2019-05-22 (水) 19:35:38)
- 14 (2019-06-11 (火) 19:44:14)
- 15 (2021-02-24 (水) 06:02:07)
- 16 (2022-08-20 (土) 22:15:25)
TITLE:JMenuなどから開くPopupMenuを半透明化
Posted by aterai at 2012-10-22
JMenuなどから開くPopupMenuを半透明化
JPopupMenuの親のJWindow、JMenuやJMenuItemなどを透明にして、JPopupMenuを半透明にします。
- &jnlp;
- &jar;
- &zip;
サンプルコード
class TransparentMenu extends JMenu {
public TransparentMenu(String title) {
super(title);
}
//http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4688783
private JPopupMenu popupMenu;
private void ensurePopupMenuCreated() {
if(popupMenu == null) {
this.popupMenu = new TranslucentPopupMenu();
popupMenu.setInvoker(this);
popupListener = createWinListener(popupMenu);
}
}
@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);
}
popupMenu.add(c);
return c;
}
@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();
}
}
View in GitHub: Java, Kotlin解説
上記のサンプルでは、JMenuを継承するTransparentMenuを作成して、自身とJMenuItemなどを透明化し、JMenuから開くJPopupMenuは、JPopupMenuを半透明にするを使用して半透明にしています。
- JPopupMenuの親の透明化
- Translucent and Shaped Swing Windows | Java.net を参考に PopupFactory#getPopup(...)をオーバーライドし、常にJPopupMenu(半透明)の親にJWindow(完全に透明、Heavy weight)を使用するように設定
PopupFactory.setSharedInstance(new TranslucentPopupFactory());
class TranslucentPopupFactory extends PopupFactory {
@Override public Popup getPopup(Component owner, Component contents, int x, int y)
throws IllegalArgumentException {
return new TranslucentPopup(owner, contents, x, y);
}
}
- JPopupMenuを半透明にするの場合は、JPopupMenu#show(...)メソッドをオーバーライドし、ポップアップが親フレームからはみ出して Heavy weightのJWindowが親として使用される時にだけ、JWindow#setBackground(ALPHA_ZERO)などで透明化(JPopupMenuは半透明)しているが、Bug ID: 7156657 Version 7 doesn't support translucent popup menus against a translucent window が原因?で、1.7.0_06 以前では、サブメニューが半透明化されない場合がある
- PopupFactory.setSharedInstance(new TranslucentPopupFactory())では、バグの影響を受けない
参考リンク
- Translucent and Shaped Swing Windows | Java.net
- Bug ID: 7156657 Version 7 doesn't support translucent popup menus against a translucent window
- JPopupMenuを半透明にする