• category: swing folder: DisableScrollDueToClickInTrack title: JSliderのトラックをクリックしても値の変更が発生しないように設定する tags: [JSlider, JLayer] author: aterai pubdate: 2016-10-10T01:47:45+09:00 description: JSliderのノブのドラッグとカーソルキーでのみ値変更を許可し、トラックのマウスクリックによる値変更を無効にします。 image: https://drive.google.com/uc?id=1ifIQLyAQgYQFw_5p3MbXRm4Z9j5VB33lSg

概要

JSliderのノブのドラッグとカーソルキーでのみ値変更を許可し、トラックのマウスクリックによる値変更を無効にします。

サンプルコード

slider.setUI(new MetalSliderUI() {
  @Override protected TrackListener createTrackListener(JSlider slider) {
    return new TrackListener() {
      @Override public boolean shouldScroll(int direction) {
        return false;
      }
    };
  }
});
View in GitHub: Java, Kotlin

解説

上記のサンプルでは、以下の2種類の方法でSliderのトラックをマウスでクリックしても値変更が発生しないように設定しています。

  • Override TrackListener#shouldScroll(...): false
    • BasicSliderUI#createTrackListener(...)メソッドをオーバーライドし、shouldScroll(...)メソッドが常にfalseを返すTrackListenerを生成する
    • BasicSliderUI#scrollDueToClickInTrack(...)メソッドを空にしても、長押しでスクロールを行うTimerが起動してBasicSliderUI#scrollByBlock(...)などが実行されて値が変化する
    • BasicSliderUI#scrollDueToClickInTrack(...)メソッドを空にしても長押しでスクロールを行うTimerが起動してBasicSliderUI#scrollByBlock(...)などが実行されて値が変化する
  • JLayer + Slider.onlyLeftMouseButtonDrag: false
    • UIManager.put("Slider.onlyLeftMouseButtonDrag", false);を設定し、かつマウスの右ボタンでノブのドラッグを可能に設定してJLayerを使用して左ボタンの押下を右ボタンの押下に入れ替える
    • 参考: JSliderのノブをマウスの右ボタンで操作不可に設定する
    • トラックの右クリックは元々無効なので、この入れ替えによりトラックのクリックによる値変更は無効になる
      class DisableLeftPressedLayerUI extends LayerUI<JSlider> {
        @Override public void installUI(JComponent c) {
          super.installUI(c);
          if (c instanceof JLayer) {
            ((JLayer) c).setLayerEventMask(AWTEvent.MOUSE_EVENT_MASK);
          }
        }
      #spanadd
      
      #spanend
        @Override public void uninstallUI(JComponent c) {
          if (c instanceof JLayer) {
            ((JLayer) c).setLayerEventMask(0);
          }
          super.uninstallUI(c);
        }
      #spanadd
      
      #spanend
        @Override protected void processMouseEvent(
            MouseEvent e, JLayer<? extends JSlider> l) {
          if (e.getID() == MouseEvent.MOUSE_PRESSED
              && SwingUtilities.isLeftMouseButton(e)) {
            e.getComponent().dispatchEvent(new MouseEvent(
                e.getComponent(),
                e.getID(), e.getWhen(),
                InputEvent.BUTTON3_DOWN_MASK, //e.getModifiers(),
                e.getX(), e.getY(),
                e.getXOnScreen(), e.getYOnScreen(),
                e.getClickCount(),
                e.isPopupTrigger(),
                MouseEvent.BUTTON3)); //e.getButton());
            e.consume();
          }
        }
      }
      

参考リンク

コメント