• category: swing folder: DisableScrollArrowsOnBoundaryValues title: JScrollBarのノブ位置が境界上かどうかでその矢印ボタンの有効・無効を切り替える tags: [JScrollBar, ArrowButton] author: aterai pubdate: 2022-03-21T04:17:26+09:00 description: JScrollBarのノブ位置が境界値まで到達したとき、対応する増加、減少矢印ボタンを無効化します。 image: https://drive.google.com/uc?id=1niEozeo_RPCr9KOxa4kN_gObARcoOl3o

概要

JScrollBarのノブ位置が境界値まで到達したとき、対応する増加、減少矢印ボタンを無効化します。

サンプルコード

JScrollPane scroll = new JScrollPane(new JTable(100, 3));
scroll.getVerticalScrollBar().addAdjustmentListener(e -> {
  JScrollBar scrollBar = (JScrollBar) e.getAdjustable();
  BoundedRangeModel m = scrollBar.getModel();
  int value = m.getValue();
  if (value == m.getMaximum() - m.getExtent()) {
    Optional.ofNullable(scrollBar.getComponent(0)) // incrButton
        .ifPresent(b -> b.setEnabled(false));
  } else if (value == m.getMinimum()) {
    Optional.ofNullable(scrollBar.getComponent(1)) // decrButton
        .ifPresent(b -> b.setEnabled(false));
  } else {
    for (Component button : scrollBar.getComponents()) {
      button.setEnabled(true);
    }
  }
});
View in GitHub: Java, Kotlin

解説

  • 左: デフォルト
    • JScrollBarのノブの位置が上限、または下限でも矢印ボタンの状態は変化しない
  • 右: addAdjustmentListener
    • JScrollBarAdjustmentListenerを追加してノブ位置が境界上に到達したらその矢印ボタンの有効・無効を切り替える
    • JScrollBar自体が無効化されている場合は考慮していない
    • JSpinnerJSpinnerの値が境界値になった場合、ArrowButtonを無効にするのようにUIManager.put("Spinner.disableOnBoundaryValues", Boolean.TRUE)で実現可能(BasicSpinnerUI#updateEnabledState(...))だが、JScrollBarAdjustmentListenerなどを追加して実装する必要がある
      • JSpinnerArrowButtonSpinner.nextButtonSpinner.previousButtonsetName(...)で名前が付いているのでこれを検索して有効・無効を切り替えているが、JScrollBarArrowButtonはデフォルトでは未設定なのでComponent#getComponent(0)incrButtonComponent#getComponent(1)decrButtonを取得している

参考リンク

コメント