TITLE:JInternalFrameをJFrameとして表示する
Posted by terai at 2009-08-31

JInternalFrameをJFrameとして表示する

JFrameのタイトルバーなどを非表示にし、JInternalFrameのタイトルバーでこれらを代用します。
  • category: swing folder: InternalFrameTitleBar title: JInternalFrameをJFrameとして表示する tags: [JFrame, JInternalFrame, MouseListener, MouseMotionListener] author: aterai pubdate: 2009-08-31T15:27:18+09:00 description: JFrameのタイトルバーなどを非表示にし、JInternalFrameのタイトルバーでこれらを代用します。 image: https://lh4.googleusercontent.com/_9Z4BYR88imo/TQTOo9LcVwI/AAAAAAAAAcs/fUEpKhXr_aI/s800/InternalFrameTitleBar.png hreflang:
       href: https://java-swing-tips.blogspot.com/2009/11/add-jinternalframe-to-undecorated.html
       lang: en

概要

JFrameのタイトルバーなどを非表示にし、JInternalFrameのタイトルバーでこれらを代用します。

#screenshot

サンプルコード

#spanend
#spandel
final JInternalFrame internal = new JInternalFrame("@title@");
#spanend
#spandel
BasicInternalFrameUI ui = (BasicInternalFrameUI)internal.getUI();
#spanend
#spanadd
* サンプルコード [#sourcecode]
#spanend
#spanadd
#code(link){{
#spanend
#spanadd
JInternalFrame internal = new JInternalFrame("@title@");
#spanend
#spanadd
BasicInternalFrameUI ui = (BasicInternalFrameUI) internal.getUI();
#spanend
Component title = ui.getNorthPane();
#spandel
for(MouseMotionListener l:title.getListeners(MouseMotionListener.class)) {
#spanend
#spanadd
for (MouseMotionListener l: title.getListeners(MouseMotionListener.class)) {
#spanend
  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") {
  public void actionPerformed(ActionEvent e) {
    Window w = SwingUtilities.windowForComponent((Component)e.getSource());
    //w.dispose();
  @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();
#spandel
focusManager.addPropertyChangeListener(new PropertyChangeListener() {
#spanend
  public void propertyChange(PropertyChangeEvent e) {
    String prop = e.getPropertyName();
    if("activeWindow".equals(prop)) {
      try{
        internal.setSelected(e.getNewValue()!=null);
      }catch(PropertyVetoException ex) {
        ex.printStackTrace();
      }
#spanadd
focusManager.addPropertyChangeListener(e -> {
#spanend
  String prop = e.getPropertyName();
  if ("activeWindow".equals(prop)) {
    try {
      internal.setSelected(Objects.nonNull(e.getNewValue()));
    } catch (PropertyVetoException ex) {
      throw new IllegalStateException(ex);
    }
  }
});

解説

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

解説

上記のサンプルでは、JInternalFrameのタイトルバーを使用することでタイトルバーに閉じるボタンのないフレームを作成しています。
  • JFrame#setUndecorated(true) で、JFrameのタイトルバーなどを非表示
  • BasicInternalFrameUI#getNorthPane()でJInternalFrameのタイトルバーを取得
    • 元のMouseMotionListenerを削除
    • JInternalFrameをドラッグすると親のJFrameが移動するMouseMotionListenerを追加
  • JFrame#setUndecorated(true)JFrameのタイトルバーなどを非表示
  • BasicInternalFrameUI#getNorthPane()JInternalFrameのタイトルバーを取得
    • 元のMouseMotionListenerを削除
    • JInternalFrameをドラッグすると親のJFrameが移動するMouseMotionListenerを追加
  • JDK 1.7.0以上の場合はframe.setBackground(new Color(0x0, true)); frame.add(p = new MainPanel()); p.setOpaque(false);で角の透明化が可能
  • 最大化、最小化、リサイズなどには未対応
    • Alt+Spaceで最大化、最小化できるが、元のサイズに戻せなくなる場合がある
  • 角の透明化には未対応
    • 目立たなくするために、LookAndFeelNimbusに変更
  • 制限
    • 最大化、最小化、リサイズなどには未対応
      • Alt+Spaceで最大化、最小化できるが、元のサイズに戻せなくなる場合がある
    • 角の透明化には未対応
      • 目立たなくするために、LookAndFeelはNimbusに変更
      • JDK 1.7.0 なら、frame.setBackground(new Color(0,0,0,0));frame.add(p=new MainPanel());p.setOpaque(false); で良さそう

参考リンク

コメント

  • JFrameのアクティブ状態が変わったら、JInternalFrameの選択状態も変化するように変更。 -- terai

コメント