• category: swing folder: SwapInternalFramesWithTabs title: JDesktopPane内のJInternalFrameをJTabbedPaneのタブと入れ替える tags: [JDesktopPane, JInternalFrame, JTabbedPane, CardLayout] author: aterai pubdate: 2015-04-13T00:00:05+09:00 description: JDesktopPaneとJTabbedPaneをCardLayoutで切り替えるとき、その内部のJInternalFrameとタブもすべて入れ替えます。 image: https://lh4.googleusercontent.com/-mNR8hjjt8Ao/VSp_fRS8WZI/AAAAAAAAN2Y/rTsBE6-6Ekg/s800/SwapInternalFramesWithTabs.png

概要

JDesktopPaneJTabbedPaneCardLayoutで切り替えるとき、その内部のJInternalFrameとタブもすべて入れ替えます。

サンプルコード

Action swapAction = new AbstractAction("JDesktopPane <-> JTabbedPane") {
  @Override public void actionPerformed(ActionEvent e) {
    if (((AbstractButton) e.getSource()).isSelected()) {
      Arrays.stream(desktopPane.getAllFrames())
        .sorted(Comparator.comparing(JInternalFrame::getTitle))
        .forEach(f -> tabbedPane.addTab(f.getTitle(), f.getFrameIcon(), f.getContentPane()));

      JInternalFrame sf = desktopPane.getSelectedFrame();
      if (Objects.nonNull(sf)) {
        tabbedPane.setSelectedIndex(tabbedPane.indexOfTab(sf.getTitle()));
      }
      cardLayout.show(panel, tabbedPane.getClass().getName());
    } else {
      Arrays.stream(desktopPane.getAllFrames())
        .forEach(f -> f.setContentPane(
          (Container) tabbedPane.getComponentAt(tabbedPane.indexOfTab(f.getTitle()))));
      cardLayout.show(panel, desktopPane.getClass().getName());
    }
  }
};
View in GitHub: Java, Kotlin

解説

  • JInternalFrameをタブに変換する
    • JDesktopPane#getAllFrames()で取得した順番は、JInternalFrameがアイコン化されているなどの状態で変化するので、タイトルでソートしてからJTabbedPaneに追加
    • JInternalFrame自体はそのままで、ContentPaneのみタブコンポーネントに変換する
    • 選択状態のJInternalFrameJDesktopPane#getSelectedFrame()で検索し、変換先のタブも選択状態になるようJTabbedPane#setSelectedIndex(...)で設定する
  • タブをJInternalFrameに変換する
    • JDesktopPaneには、位置やサイズ、アイコン化状態などを保存した状態でJInternalFrameが残っている
      • JTabbedPane側ではタブの削除を許可していない
    • JInternalFrameのタイトルと同じタブのインデックスをJTabbedPane#indexOfTab(String)で検索し、そのコンポーネントをContentPaneとしてJInternalFrameに戻す

コメント