Swing/TranslucentFrameRepaint のバックアップ(No.3)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/TranslucentFrameRepaint へ行く。
- 1 (2011-10-24 (月) 15:53:52)
- 2 (2011-10-24 (月) 18:11:47)
- 3 (2011-10-24 (月) 19:37:18)
- 4 (2012-02-10 (金) 17:34:36)
- 5 (2012-04-17 (火) 17:26:14)
- 6 (2012-10-30 (火) 21:02:17)
- 7 (2012-12-16 (日) 01:38:42)
- 8 (2013-06-28 (金) 18:34:17)
- 9 (2013-11-26 (火) 16:26:21)
- 10 (2014-01-17 (金) 17:24:20)
- 11 (2014-02-26 (水) 15:41:24)
- 12 (2014-11-19 (水) 20:22:56)
- 13 (2014-11-21 (金) 18:11:05)
- 14 (2015-04-07 (火) 19:54:46)
- 15 (2017-02-22 (水) 13:59:47)
- 16 (2018-01-03 (水) 19:53:11)
- 17 (2018-02-24 (土) 19:51:30)
- 18 (2019-03-06 (水) 14:00:48)
- 19 (2020-12-16 (水) 11:01:16)
- 20 (2023-03-18 (土) 16:05:58)
TITLE:JFrameの透明化と再描画
Posted by aterai at 2011-10-24
JFrameの透明化と再描画
半透明にしたJFrameの再描画を行います。
- &jnlp;
- &jar;
- &zip;
サンプルコード
private final SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
private final JLabel label = new JLabel(df.format(new Date()));
private final Timer timer = new Timer(1000, new ActionListener() {
@Override public void actionPerformed(ActionEvent e) {
label.setText(df.format(new Date()));
repaintWindowAncestor(label);
}
});
private void repaintWindowAncestor(Component c) {
Window w = SwingUtilities.getWindowAncestor(c);
if(w instanceof JFrame) {
JFrame f = (JFrame)w;
JComponent cp = (JComponent)f.getContentPane();
//cp.repaint();
Rectangle r = c.getBounds();
r = SwingUtilities.convertRectangle(c, r, cp);
cp.repaint(r.x, r.y, r.width, r.height);
//r = SwingUtilities.convertRectangle(c, r, f);
//f.repaint(r.x, r.y, r.width, r.height);
}else{
c.repaint();
}
}
解説
上記のサンプルでは、実際はJFrameが半透明ではなく、以下のように半透明にした透明にしたJFrameに、半透明のJPanelを追加、さらにその子として一秒ごとに文字列が変化するJLabel(時計)を配置しています。
- JFrame
- 透明
com.sun.awt.AWTUtilities.setWindowOpaque(frame, false); //frame.setBackground(new Color(0,0,0,0)); //1.7.0
- AWTUtilities.setWindowOpacity(...)、Window#setOpacity(...)は子コンポーネント全体が半透明になるので、このサンプルでは使用していない
- 透明
- JPanel
- frame.getContentPane().add(panel)で追加
- 半透明(二種類)
- setOpaque(true)+半透明のアルファ成分をもつ色をsetBackground()で設定
- setOpaque(false)+paintComponent()をオーバーライドして背景画像などを描画
- JLabel
- panel.add(label)で追加
- 一秒ごとに文字列を変更する時計
- setOpaque(false)で透明
JFrameが半透明なので、JFrame自体は透明ですが、そのContentPaneから再描画しないと、JLabelとの間にあるContainerの背景色などが重複して上書きされる(色が濃くなる)ようです。