TITLE:JInternalFrameをJFrameとして表示する
#navi(../)
#tags(JFrame, JInternalFrame, MouseListener, MouseMotionListener)
RIGHT:Posted by &author(aterai); at 2009-08-31
*JInternalFrameをJFrameとして表示する [#tf5e5ced]
``JFrame``のタイトルバーなどを非表示にし、``JInternalFrame``のタイトルバーでこれらを代用します。

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

//#screenshot
#ref(http://lh4.ggpht.com/_9Z4BYR88imo/TQTOo9LcVwI/AAAAAAAAAcs/fUEpKhXr_aI/s800/InternalFrameTitleBar.png)

**サンプルコード [#k636189e]
#code(link){{
final JInternalFrame internal = new JInternalFrame("@title@");
BasicInternalFrameUI ui = (BasicInternalFrameUI)internal.getUI();
Component title = ui.getNorthPane();
for(MouseMotionListener l:title.getListeners(MouseMotionListener.class)) {
  title.removeMouseMotionListener(l);
}
DragWindowListener dwl = new DragWindowListener();
title.addMouseListener(dwl);
title.addMouseMotionListener(dwl);
JPanel p = new JPanel(new BorderLayout());
p.add(new JScrollPane(new JTree()));
p.add(new JButton(new AbstractAction("close") {
  @Override public void actionPerformed(ActionEvent e) {
    Window w = SwingUtilities.windowForComponent((Component)e.getSource());
    //w.dispose();
    w.getToolkit().getSystemEventQueue().postEvent(
      new WindowEvent(w, WindowEvent.WINDOW_CLOSING));
  }
}), BorderLayout.SOUTH);
internal.getContentPane().add(p);
internal.setVisible(true);

KeyboardFocusManager focusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
focusManager.addPropertyChangeListener(new PropertyChangeListener() {
  @Override public void propertyChange(PropertyChangeEvent e) {
    String prop = e.getPropertyName();
    if("activeWindow".equals(prop)) {
      try{
        internal.setSelected(e.getNewValue()!=null);
      }catch(PropertyVetoException ex) {
        ex.printStackTrace();
      }
    }
  }
});
}}

**解説 [#d219693c]
上記のサンプルでは、``JInternalFrame``のタイトルバーを使用することで、タイトルバーに閉じるボタンのないフレームを作成しています。

-``JFrame#setUndecorated(true)``で、``JFrame``のタイトルバーなどを非表示
-``BasicInternalFrameUI#getNorthPane()``で``JInternalFrame``のタイトルバーを取得
--元の``MouseMotionListener``を削除
--``JInternalFrame``をドラッグすると親の``JFrame``が移動する``MouseMotionListener``を追加

-制限
--最大化、最小化、リサイズなどには未対応
---``Alt+Space``で最大化、最小化できるが、元のサイズに戻せなくなる場合がある
--角の透明化には未対応
---目立たなくするために、``LookAndFeel``は``Nimbus``に変更
---``JDK 1.7.0``なら、``frame.setBackground(new Color(0,0,0,0)); frame.add(p=new MainPanel()); p.setOpaque(false);``で角の透明化が可能

**参考リンク [#y4fccd48]
- [[JWindowをマウスで移動>Swing/DragWindow]]
- [[JFrameのタイトルバーなどの装飾を独自のものにカスタマイズする>Swing/CustomDecoratedFrame]]
- [[JRootPaneにリサイズのための装飾を設定する>Swing/WindowDecorationStyle]]

**コメント [#b720b8d7]
- ``JFrame``のアクティブ状態が変わったら、``JInternalFrame``の選択状態も変化するように変更。 -- [[aterai]] &new{2009-11-13 (金) 14:57:18};
- リサイズ可能?にする場合のテスト。 -- [[aterai]] &new{2010-06-10 (木) 15:07:18};
-- [[JRootPaneにリサイズのための装飾を設定する>Swing/WindowDecorationStyle]]に移動。 -- [[aterai]] &new{2013-06-17 (月) 02:29:47};

#comment