概要

JTabbedPaneのタブをマウスの左プレスで選択したとき、表示状態になったタブコンポーネントにフォーカスを移動するよう設定します。

スクリーンショット

Swing/RequestFocusForVisibleComponent.png

サンプルコード

class TabSelectionMouseListener extends MouseAdapter {
  private final BasicTabbedPaneUI ui;

  protected TabSelectionMouseListener(BasicTabbedPaneUI ui) {
    super();
    this.ui = ui;
  }

  @Override public void mousePressed(MouseEvent e) {
    JTabbedPane tabPane = (JTabbedPane) e.getComponent();
    if (!tabPane.isEnabled() || SwingUtilities.isRightMouseButton(e)) {
      return;
    }
    int tabIndex = ui.tabForCoordinate(tabPane, e.getX(), e.getY());
    if (tabIndex >= 0 && tabPane.isEnabledAt(tabIndex)) {
      if (tabIndex != tabPane.getSelectedIndex() && e.getClickCount() < 2) {
        tabPane.setSelectedIndex(tabIndex);
        String cmd = "requestFocusForVisibleComponent";
        ActionEvent a = new ActionEvent(tabPane, ActionEvent.ACTION_PERFORMED, cmd);
        EventQueue.invokeLater(() -> tabPane.getActionMap().get(cmd).actionPerformed(a));
      } else if (tabPane.isRequestFocusEnabled()) {
        tabPane.requestFocus();
      }
    }
  }
}
view all

解説

  • 上: Default
    • デフォルトのJTabbedPaneでは自身のタブコンポーネントにフォーカスがない(自身のタブ、または別コンポーネントにフォーカスが存在する)場合、現在選択されているタブ以外のタブをクリックしてタブ選択状態が切り替わってもフォーカスは移動しない
    • 自身のタブコンポーネントにフォーカスが存在する場合は、タブ選択で表示状態になったタブコンポーネントにフォーカスが移動する
    • マウスの右ボタンプレスでタブ選択の切り替えが可能(ポップアップメニューが開いている状態でマウスの右ボタンプレスした場合はタブの切り替え不可)
  • 下: requestFocusForVisibleComponent
    • BasicTabbedPaneUI#createMouseListener()をオーバーライドしてタブをマウスで選択した場合、フォーカスを表示されたタブコンポーネントに移動する
      • JTabbedPaneに直接同様のMouseListenerを追加する方法もあるが、その場合以下のようなマウスの右ボタンプレスでのタブ選択無効化ができない
    • マウスの右ボタンプレスでのタブ選択を無効化(マウス右クリックでのポップアップメニュー表示は有効)
    • 現在選択されているタブ以外のタブがシングルクリックされた場合、タブ選択状態の移動後にrequestFocusForVisibleComponentアクション(Ctrl+↓キーでも実行可能)を実行してタブ選択で表示状態になったタブコンポーネントにフォーカスを移動
    • 現在選択されているタブがクリックされたり、ダブルクリックなどの場合はタブにフォーカスを移動
    • requestFocusForVisibleComponentアクションではなく直接BasicTabbedPaneUI#requestFocusForVisibleComponent()メソッドを使用したいが、まだパッケージプライベートのままなので使用できない
      // REMIND(aim,7/29/98): This method should be made
      // protected in the next release where
      // API changes are allowed
      boolean requestFocusForVisibleComponent() {
        return SwingUtilities2.tabbedPaneChangeFocusTo(getVisibleComponent());
      }
      

参考リンク

コメント