概要

JTabbedPaneでマウスクリックやキー入力といったユーザ操作イベントによるタブ切替を無効にします。

サンプルコード

class DisableInputLayerUI extends LayerUI<Component> {
  @Override public void installUI(JComponent c) {
    super.installUI(c);
    if (c instanceof JLayer) {
      ((JLayer<?>) c).setLayerEventMask(
        AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK
        | AWTEvent.MOUSE_WHEEL_EVENT_MASK | AWTEvent.KEY_EVENT_MASK
        | AWTEvent.FOCUS_EVENT_MASK | AWTEvent.COMPONENT_EVENT_MASK);
    }
  }

  @Override public void uninstallUI(JComponent c) {
    if (c instanceof JLayer) {
      ((JLayer<?>) c).setLayerEventMask(0);
    }
    super.uninstallUI(c);
  }

  @Override public void eventDispatched(AWTEvent e, JLayer<? extends Component> l) {
    if (e instanceof InputEvent && Objects.equals(l.getView(), e.getSource())) {
      ((InputEvent) e).consume();
    }
  }
}
View in GitHub: Java, Kotlin

解説

  • 上: setEnabled(false)
    • JTabbedPane#setEnabled(false)ですべてのタブの切替を禁止
      • 内部タブコンポーネントには影響しない
      • nextボタンでJTabbedPane#setSelectedIndex(...)メソッドを使用してタブを切り替えることは可能
    • JTabbedPane#setFocusable(false)を設定している場合でもWindowsLookAndFeelではマウスカーソルのあるタブがハイライトされる
  • 中: setTabComponentAt(...)
    • 上のサンプルと同様にJTabbedPane#setEnabled(false)ですべてのタブの切替を禁止
    • JTabbedPane#setTabComponentAt(idx, new JLabel(title))でタブタイトルコンポーネントをJLabelに置き換え、使用不可になっているタブタイトルの文字色を使用可の状態に戻す
  • 下: DisableInputLayerUI()
    • JTabbedPaneにマウスイベントやキー入力イベントをすべて消費するLayerUIを設定してすべてのタブの切替を禁止
    • LayerUI#eventDispatched(...)メソッドをオーバーライドしてすべてのInputEventを消費すると内部タブコンポーネント(このサンプルではJTextField)も入力不可になるので、JLayerを設定したJTabbedPaneの場合のみイベントを消費する用設定
      @Override
      public void eventDispatched(AWTEvent e, JLayer<? extends Component> l) {
        if (e instanceof InputEvent && Objects.equals(l.getView(), e.getSource())) {
          ((InputEvent) e).consume();
        }
      }
      

参考リンク

コメント