Swing/TranslucentFrameRepaint のバックアップ(No.20)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - 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)
- category: swing
folder: TranslucentFrameRepaint
title: JFrameの透明化と再描画
tags: [JFrame, JRootPane, Translucent, JPanel, JLabel, TexturePaint]
author: aterai
pubdate: 2011-10-24T15:53:52+09:00
description: 透明にしたJFrameに半透明のデジタル時計を配置し、文字更新による背景色の再描画をテストします。
image:
hreflang:
href: https://java-swing-tips.blogspot.com/2014/02/translucent-jframe-repaint.html lang: en
概要
透明にしたJFrame
に半透明のデジタル時計を配置し、文字更新による背景色の再描画をテストします。
Screenshot
Advertisement
サンプルコード
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
JLabel label = new JLabel(LocalTime.now().format(formatter), SwingConstants.CENTER);
Timer timer = new Timer(100, null);
timer.addActionListener(e -> {
label.setText(LocalTime.now().format(formatter));
Container parent = SwingUtilities.getUnwrappedParent(label);
if (Objects.nonNull(parent) && parent.isOpaque()) {
repaintWindowAncestor(label);
}
});
// ...
private void repaintWindowAncestor(JComponent c) {
JRootPane root = c.getRootPane();
if (root == null) {
return;
}
Rectangle r = SwingUtilities.convertRectangle(c, c.getBounds(), root);
root.repaint(r.x, r.y, r.width, r.height);
}
View in GitHub: Java, Kotlin解説
上記のサンプルでは、実際はJFrame
が半透明ではなく、以下のように透明にしたJFrame
に半透明のJPanel
を追加、さらにその子として一秒ごとに文字列が変化するJLabel
(時計)を配置しています。
JFrame
- 透明
com.sun.awt.AWTUtilities.setWindowOpaque(frame, false); // JDK 1.6.0 frame.setBackground(new Color(0x0, true)); // JDK 1.7.0以降
Window#setOpacity(...)
(またはJDK 1.6.0
でAWTUtilities.setWindowOpacity(...)
)は子コンポーネントを含めてすべて半透明になるので、このサンプルでは使用していない
- 透明
JPanel
frame.getContentPane().add(panel)
で追加- 半透明(二種類)
setOpaque(true)
+半透明のアルファ成分をもつ色をsetBackground()
で設定JPanel
がsetOpaque(true)
なのでContentPane
から再描画しないとJPanel
に設定した半透明の背景色が重複して上書きされる(色が濃くなる)setOpaque(false)
+paintComponent()
をオーバーライドして背景画像などを描画
JLabel
panel.add(label)
で追加- 一秒ごとに文字列を変更する時計
setOpaque(false)
で背景は透明