TITLE:JTextFieldの表示領域をJScrollBarでスクロールする

Posted by at 2014-05-12

JTextFieldの表示領域をJScrollBarでスクロールする

JTextFieldの表示領域をJScrollBarでスクロール可能にします。

HorizontalVisibility.png

サンプルコード

scroller.setModel(textField.getHorizontalVisibility());
View in GitHub: Java, Kotlin

解説

上記のサンプルでは、JTextField#getHorizontalVisibility()で取得したBoundedRangeModel(可視領域のモデル)をJScrollBarに設定することで、これを使用したスクロールや現在の可視領域の位置、幅の表示などが可能になっています。

  • 注: setCaretPosition: 0
    • JTextField#setCaretPosition(0);JTextFieldにフォーカスが無い場合無効?
    • JScrollBarが同期しない場合がある
  • 注: setScrollOffset: 0
    • JScrollBarのノブがマウスドラッグに反応しなくなる場合がある?
  • 注: ノブの表示
    • 文字列をすべて削除するなどしても、ノブが非表示にならない
    • 1pxの余白?、以下のようなリスナーで回避するテストを追加
class EmptyThumbHandler extends ComponentAdapter implements DocumentListener {
  private final BoundedRangeModel emptyThumbModel = new DefaultBoundedRangeModel(0, 1, 0, 1);
  private final JTextField textField;
  private final JScrollBar scroller;
  public EmptyThumbHandler(JTextField textField, JScrollBar scroller) {
    super();
    this.textField = textField;
    this.scroller = scroller;
  }
  private void changeThumbModel() {
    EventQueue.invokeLater(new Runnable() {
      @Override public void run() {
        BoundedRangeModel m = textField.getHorizontalVisibility();
        int iv = m.getMaximum() - m.getMinimum() - m.getExtent() - 1; // -1: bug?
        if (iv <= 0) {
          scroller.setModel(emptyThumbModel);
        } else {
          scroller.setModel(textField.getHorizontalVisibility());
        }
      }
    });
  }
  @Override public void componentResized(ComponentEvent e) {
    changeThumbModel();
  }
  @Override public void insertUpdate(DocumentEvent e) {
    changeThumbModel();
  }
  @Override public void removeUpdate(DocumentEvent e) {
    changeThumbModel();
  }
  @Override public void changedUpdate(DocumentEvent e) {
    changeThumbModel();
  }
}

  • JScrollPane scroll = new JScrollPane(new JTextField(TEXT), ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
    • 縦スクロールバーを非表示にしたJScrollPaneを使用する場合、JTextField内の文字列選択でスクロールしない
    • 文字列を適当な長さまで削除するとノブが非表示になる

コメント