TITLE:JFrameを半透明化

Posted by at 2010-06-14

JFrameを半透明化

JFrameを半透明にします。

  • &jnlp;
  • &jar;
  • &zip;
WindowOpacity.png

サンプルコード

JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame();
//com.sun.awt.AWTUtilities.setWindowOpacity(frame, .5f);
com.sun.awt.AWTUtilities.setWindowOpaque(frame, false);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JPanel p = new JPanel();
p.add(new JButton("JButton"));
p.setBackground(new Color(.5f,.8f,.5f,.5f));
frame.getContentPane().add(p);
frame.setSize(320, 240);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
View in GitHub: Java, Kotlin

解説

com.sun.awt.AWTUtilities.setWindowOpacity(frame, .5f);を使って半透明化すると、フレームのタイトルバーや、子コンポーネントまで半透明化されるので、代わりに上記のサンプルでは以下のようにして半透明化を行っています。

  • JFrame.setDefaultLookAndFeelDecorated(true);で、タイトルバーなどをJRootPaneに描画
  • com.sun.awt.AWTUtilities.setWindowOpaque(frame, false);でJFrameを完全に透明化
    • 1.7.0の場合は、代わりに、frame.setBackground(new Color(0,0,0,0));
  • ContentPaneにsetBackground(new Color(.5f,.8f,.5f,.5f));で半透明の背景色を設定したパネルを追加

参考リンク

コメント

  • そんな簡単にできるんですね!昔画面キャプチャしたり色々苦労した結果断念しました; -- riki
  • 「Windows 7 + JDK 1.7.0」で、このサンプルにあるJComboBoxのドロップダウンリストが正常に描画されない? 「Windows XP + JDK 1.7.0」や、「Windows 7 + JDK 1.6.0_27」は問題なし。 -- aterai
  • JDK 1.7.0 では、背景を切り替えたときに前の背景の残像が残る場合がある? -- aterai
    • こちらは((JFrame)w).getContentPane().repaint();でうまくいくが理由が不明… ようなので修正。 -- aterai
  • 1.7.0_04で?、透明にしたJFrameにJComboBoxを追加すると、ドロップダウンリストがおかしい? -- aterai
    • 以下のようなPopupMenuListenerを追加すれば回避できるが…。 -- aterai
combo.addPopupMenuListener(new PopupMenuListener() {
  @Override public void popupMenuWillBecomeVisible(final PopupMenuEvent e) {
    EventQueue.invokeLater(new Runnable() {
      @Override public void run() {
        JComboBox c = (JComboBox)e.getSource();
        Object o = c.getAccessibleContext().getAccessibleChild(0);
        if(o instanceof JComponent) { //BasicComboPopup
          ((JComponent)o).repaint();
        }
      }
    });
  }
  @Override public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {}
  @Override public void popupMenuCanceled(PopupMenuEvent e) {}
});