Swing/DropShadowPopup のバックアップ(No.34)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/DropShadowPopup へ行く。
- 1 (2007-03-22 (木) 12:29:12)
- 2 (2007-04-18 (水) 12:39:57)
- 3 (2008-04-10 (木) 18:24:18)
- 4 (2011-04-19 (火) 15:43:56)
- 5 (2011-04-19 (火) 18:55:52)
- 6 (2012-02-05 (日) 14:22:34)
- 7 (2012-02-09 (木) 13:47:39)
- 8 (2012-02-21 (火) 16:45:48)
- 9 (2012-11-23 (金) 04:40:42)
- 10 (2013-02-27 (水) 13:58:49)
- 11 (2013-03-02 (土) 05:32:25)
- 12 (2013-03-04 (月) 09:53:00)
- 13 (2013-03-05 (火) 20:22:26)
- 14 (2013-03-11 (月) 17:09:34)
- 15 (2013-08-09 (金) 13:15:04)
- 16 (2013-08-20 (火) 14:37:23)
- 17 (2013-09-12 (木) 01:13:54)
- 18 (2014-06-10 (火) 18:59:39)
- 19 (2014-09-19 (金) 16:51:25)
- 20 (2014-10-18 (土) 12:45:15)
- 21 (2014-11-25 (火) 03:03:31)
- 22 (2015-02-12 (木) 15:49:13)
- 23 (2015-03-20 (金) 15:23:39)
- 24 (2015-04-04 (土) 22:09:18)
- 25 (2016-01-27 (水) 18:20:45)
- 26 (2016-05-26 (木) 14:50:42)
- 27 (2016-09-20 (火) 04:59:27)
- 28 (2017-03-30 (木) 14:05:39)
- 29 (2017-08-15 (火) 14:13:00)
- 30 (2018-08-16 (木) 15:36:50)
- 31 (2018-12-05 (水) 18:50:12)
- 32 (2020-11-10 (火) 13:48:52)
- 33 (2022-11-06 (日) 20:06:50)
- 34 (2024-02-03 (土) 13:59:47)
- category: swing folder: DropShadowPopup title: JPopupMenuに半透明の影を付ける tags: [JPopupMenu, Border, Robot, JMenuItem, Translucent] author: aterai pubdate: 2006-07-03T12:55:36+09:00 description: Robotで画面をキャプチャーするなどして、半透明の影をJPopupMenuに付けます。 image:
概要
Robot
で画面をキャプチャーするなどして、半透明の影をJPopupMenu
に付けます。
Screenshot
Advertisement
サンプルコード
class ShadowBorder extends AbstractBorder {
private final int xoff, yoff;
private final transient BufferedImage screen;
private transient BufferedImage shadow;
public ShadowBorder(int x, int y, JComponent c, Point p) {
super();
this.xoff = x;
this.yoff = y;
BufferedImage bi = null;
try {
Robot robot = new Robot();
Dimension d = c.getPreferredSize();
bi = robot.createScreenCapture(
new Rectangle(p.x, p.y, d.width + xoff, d.height + yoff));
} catch (AWTException ex) {
ex.printStackTrace();
}
screen = bi;
}
@Override public Insets getBorderInsets(Component c) {
return new Insets(0, 0, xoff, yoff);
}
@Override public void paintBorder(
Component c, Graphics g, int x, int y, int w, int h) {
if (screen == null) {
return;
}
if (shadow == null || shadow.getWidth() != w || shadow.getHeight() != h) {
shadow = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = shadow.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .2f));
g2.setPaint(Color.BLACK);
for (int i = 0; i < xoff; i++) {
g2.fillRoundRect(xoff, xoff, w - xoff - xoff + i, h - xoff - xoff + i, 4, 4);
}
g2.dispose();
}
Graphics2D g2d = (Graphics2D) g.create();
g2d.drawImage(screen, 0, 0, c);
g2d.drawImage(shadow, 0, 0, c);
g2d.setPaint(c.getBackground()); //??? 1.7.0_03
g2d.fillRect(x, y, w - xoff, h - yoff);
g2d.dispose();
}
}
View in GitHub: Java, Kotlin解説
ポップアップメニューに半透明の影をつける際、フレームからはみ出すかどうかで異なる処理を行っています。
上記のサンプルコードは、フレームからはみ出す場合に使用するBorder
クラスです。
- フレーム内
JPopupMenu#paintComponent
メソッドで半透明の影を描画
- フレーム外
Robot
を使って画面全体をキャプチャーしこれを利用して半透明の影をBorder
として作成- このためポップアップメニューがはみ出しても影を付けることが可能
1.6.0_10
以上の場合フレーム外でもRobot
を使用せず以下のようにJPopupMenu
の上位Window
の背景色を透明にすれば影の描画が可能class DropShadowPopupMenu extends JPopupMenu { private static final int OFFSET = 4; private final Dimension dim = new Dimension(); private transient BufferedImage shadow; @Override public void updateUI() { setBorder(null); super.updateUI(); Border inner = getBorder(); Border outer = BorderFactory.createEmptyBorder(0, 0, OFFSET, OFFSET); setBorder(BorderFactory.createCompoundBorder(outer, inner)); } @Override public boolean isOpaque() { return false; } @Override protected void paintComponent(Graphics g) { // super.paintComponent(g); Graphics2D g2 = (Graphics2D) g.create(); g2.drawImage(shadow, 0, 0, this); g2.setPaint(getBackground()); // ??? 1.7.0_03 g2.fillRect(0, 0, getWidth() - OFFSET, getHeight() - OFFSET); g2.dispose(); } @Override public void show(Component c, int x, int y) { Dimension d = getPreferredSize(); int w = d.width; int h = d.height; if (dim.width != w || dim.height != h) { dim.setSize(w, h); shadow = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = shadow.createGraphics(); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .2f)); g2.setPaint(Color.BLACK); for (int i = 0; i < OFFSET; i++) { g2.fillRoundRect( OFFSET, OFFSET, w - OFFSET - OFFSET + i, h - OFFSET - OFFSET + i, 4, 4); } g2.dispose(); } EventQueue.invokeLater(() -> { Window top = SwingUtilities.getWindowAncestor(this); if (top != null && top.getType() == Window.Type.POPUP) { // Popup$HeavyWeightWindow top.setBackground(new Color(0x0, true)); // JDK 1.7.0 } }); super.show(c, x, y); } }