TITLE:JFrameを半透明化
#navi(../)
#tags()
RIGHT:Posted by &author(aterai); at 2010-06-14
*JFrameを半透明化 [#ea286453]
JFrameを半透明にします。

-&jnlp;
-&jar;
-&zip;

//#screenshot
#ref(http://lh5.ggpht.com/_9Z4BYR88imo/TQTWw2d9LNI/AAAAAAAAApw/NXG2EcaSv_s/s800/WindowOpacity.png)

**サンプルコード [#l5dd57cc]
#code(link){{
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);
}}

**解説 [#v5c228ee]
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));で半透明の背景色を設定したパネルを追加

**参考リンク [#pc13cea7]
-[http://www.viva-edo.com/komon/edokomon.html 江戸の文様(和風素材・デスクトップ壁紙)]
-[http://java.sun.com/developer/technicalArticles/GUI/translucent_shaped_windows/ How to Create Translucent and Shaped Windows]

**コメント [#d57b3c09]
- そんな簡単にできるんですね!昔画面キャプチャしたり色々苦労した結果断念しました; -- [[riki]] &new{2010-06-14 (月) 22:57:11};
-- AWTUtilities.setWindowOpaqueなどが使えるようになったのは、6u10からですが、上記のサンプルみたいなことができるようになったのは、6u14から(多分[http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6683775 Bug ID: 6683775 Painting artifacts is seen when panel is made setOpaque(false) for a translucent window])みたいですから、最近(ちょうど一年ぐらい)のようです。 -- [[aterai]] &new{2010-06-15 (火) 13:26:11};
- 「Windows 7 + JDK 1.7.0」で、このサンプルにあるJComboBoxのドロップダウンリストが正常に描画されない? 「Windows XP + JDK 1.7.0」や、「Windows 7 + JDK 1.6.0_27」は問題なし。 -- [[aterai]] &new{2011-10-18 (火) 19:01:43};
- JDK 1.7.0 では、背景を切り替えたときに前の背景の残像が残る場合がある? -- [[aterai]] &new{2011-10-18 (火) 19:06:07};
-- こちらは((JFrame)w).getContentPane().repaint();でうまく%%いくが理由が不明…%% ようなので修正。 -- [[aterai]] &new{2011-10-18 (火) 19:19:00};
- 1.7.0_04で?、透明にしたJFrameにJComboBoxを追加すると、ドロップダウンリストがおかしい? -- [[aterai]] &new{2012-05-15 (火) 12:49:23};
-- 以下のようなPopupMenuListenerを追加すれば回避できるが…。 -- [[aterai]] &new{2012-05-15 (火) 14:16:17};

#code{{
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) {}
});
}}
-- 7u6 では修正されている。1.7.0_06のBug Fixesに載っている [http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7156657 Bug ID: 7156657 Version 7 doesn't support translucent popup menus against a translucent window] が関係している気がするけど、Release Fixed に、7u6が無い? -- [[aterai]] &new{2012-09-19 (水) 18:18:48};

#comment