• category: swing folder: FloatingToolBarLayout title: JToolBarがドラッグ・アウト状態になった場合、そのLayoutManagerを変更する tags: [JToolBar, LayoutManager, BoxLayout, GridLayout] author: aterai pubdate: 2018-04-16T15:27:23+09:00 description: JToolBarがドラッグ・アウト状態になった場合、そのLayoutManagerをデフォルトのBoxLayoutからGridLayoutに変更します。 image: https://drive.google.com/uc?id=1C5Cd9XW5NYoQba530bfzr0nsstb407QGwA

概要

JToolBarがドラッグ・アウト状態になった場合、そのLayoutManagerをデフォルトのBoxLayoutからGridLayoutに変更します。

サンプルコード

JToolBar toolbar = new JToolBar(SwingConstants.VERTICAL);
// toolbar.setLayout(new BoxLayout(toolbar, BoxLayout.PAGE_AXIS));

// TEST:
// JToolBar toolbar = new JToolBar(orientation) {
//   @Override public Dimension getPreferredSize() {
//     if (((BasicToolBarUI) getUI()).isFloating()) {
//       setLayout(new GridLayout(0, 3));
//       return new Dimension(ICON_SIZE * 3, ICON_SIZE * 2);
//     } else {
//       setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
//       return super.getPreferredSize();
//     }
//   }
//   @Override public Dimension getMinimumSize() {
//     return getPreferredSize();
//   }
//   @Override public Dimension getMaximumSize() {
//     return getPreferredSize();
//   }
// };

JPanel panel = new JPanel() {
  @Override public Dimension getPreferredSize() {
    if (((BasicToolBarUI) toolbar.getUI()).isFloating()) {
      setLayout(new GridLayout(0, 3));
      return new Dimension(ICON_SIZE * 3, ICON_SIZE * 2);
    } else {
      setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
      return super.getPreferredSize();
    }
  }
  @Override public Dimension getMinimumSize() {
    return getPreferredSize();
  }
  @Override public Dimension getMaximumSize() {
    return getPreferredSize();
  }
};
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.add(new ColorPanel(Color.RED));
panel.add(new ColorPanel(Color.GREEN));
panel.add(new ColorPanel(Color.BLUE));
panel.add(new ColorPanel(Color.ORANGE));
panel.add(new ColorPanel(Color.CYAN));

toolbar.add(panel);
toolbar.add(Box.createGlue());
View in GitHub: Java, Kotlin

解説

上記のサンプルでは、JToolBarが親JFrameに格納されている場合は縦BoxLayout、ドラッグ・アウトされてfloating状態の場合は3GridLayoutになるよう設定しています。

  • このサンプルのJToolBarは親JFrameの左右にのみドッキング可能に制限
  • JToolBarがドラッグ・アウトされているかどうかは、BasicToolBarUI#isFloating()で判断
  • getPreferredSize()メソッドが実行されたときに、推奨サイズの変更と合わせてLayoutManagerの切り替えを行う
    • AncestorListener#ancestorAdded(...)が実行されたときにLayoutManagerの切り替えを行う方法もあるが、ドラッグ・アウト継続中にJToolBarの縦横が変化する場合に対応できない
    • JToolBar#getPreferredSize()をオーバーライドした場合、ドラッグ・アウトされたJToolBarのサイズがJToolBarの親JDialogまで拡大されてしまう
    • JToolBarの親JDialogのサイズは固定?で変更できないので、JToolBarの子にJPanelを挟んでこのJPanel#getPreferredSize()メソッドをオーバーライドし、LayoutManagerを切り替えることで回避(ドラッグ・アウトされたJToolBarの左右に余白を設ける)

参考リンク

コメント