JPopupMenuを半透明にする
Total: 5810, Today: 1, Yesterday: 3
Posted by aterai at
Last-modified:
Summary
JPopupMenu自体の背景を透明に設定し、別途そのpaintComponent(...)メソッドをオーバーライドして半透明の背景を描画します。
Screenshot

Advertisement
Source Code Examples
class TranslucentPopupMenu extends JPopupMenu {
private static final Color ALPHA_ZERO = new Color(0x0, true);
private static final Color POPUP_BACK = new Color(250, 250, 250, 200);
private static final Color POPUP_LEFT = new Color(230, 230, 230, 200);
private static final int LEFT_WIDTH = 24;
@Override public boolean isOpaque() {
return false;
}
@Override public void updateUI() {
super.updateUI();
if (UIManager.getBorder("PopupMenu.border") == null) {
setBorder(new BorderUIResource(BorderFactory.createLineBorder(Color.GRAY)));
}
}
@Override public JMenuItem add(JMenuItem menuItem) {
menuItem.setOpaque(false);
// menuItem.setBackground(ALPHA_ZERO);
return super.add(menuItem);
}
@Override public void show(Component c, int x, int y) {
EventQueue.invokeLater(new Runnable() {
@Override public void run() {
Window p = SwingUtilities.getWindowAncestor(TranslucentPopupMenu.this);
if (p instanceof JWindow) {
System.out.println("Heavy weight");
JWindow w = (JWindow) p;
w.setBackground(ALPHA_ZERO);
} else {
System.out.println("Light weight");
}
}
});
super.show(c, x, y);
}
@Override protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setPaint(POPUP_LEFT);
g2.fillRect(0, 0, LEFT_WIDTH, getHeight());
g2.setPaint(POPUP_BACK);
g2.fillRect(LEFT_WIDTH, 0, getWidth(), getHeight());
g2.dispose();
//super.paintComponent(g);
}
}
View in GitHub: Java, KotlinDescription
上記のサンプルでは、JPopupMenuはisOpaque()メソッドをオーバーライド、JMenuItemはsetOpaque(false)としてそれぞれ透明に設定し、JPopupMenu#paintComponent(...)で半透明の背景を描画しています。
JPopupMenuが親フレームの外にはみ出す場合はHeavyweightのJWindowを使ってJPopupMenuが表示されるので、JWindow#setBackground(new Color(0x0, true))で(JDK 1.6.0_10ではcom.sun.awt.AWTUtilities.setWindowOpaque(w, false))、JPopupMenu#show(...)が呼ばれるたびに毎回(親フレームの透明度を引き継がないように?)JWindow自体を透明にしています。
JPopupMenu(ルート)がLight weightでそのJMenuから開くJPopupMenu(サブメニュー) がHeavy weightのときに半透明にならない