JTextFieldの表示領域をJScrollBarでスクロールする
Total: 6236
, Today: 1
, Yesterday: 1
Posted by aterai at
Last-modified:
概要
JTextField
の表示領域をJScrollBar
でスクロール可能にします。
Screenshot
Advertisement
サンプルコード
解説
上記のサンプルでは、JTextField#getHorizontalVisibility()
で取得したBoundedRangeModel
(可視領域のモデル)をJScrollBar
に設定することで、これを使用したスクロールや現在の可視領域の位置、幅の表示などが可能になっています。
JScrollPane + VERTICAL_SCROLLBAR_NEVER
JTextField
をスクロールバーを常に非表示に設定したJScrollPane
に追加
BoundedRangeModel: textField.getHorizontalVisibility()
JTextField
と水平スクロールバーJScrollBar(Adjustable.HORIZONTAL)
を別々に配置JTextField#getHorizontalVisibility()
でBoundedRangeModel
を取得し、これをJScrollBar#setModel(...)
で設定して二つを同期する
BoundedRangeModel+textField.ArrowButtonlessScrollBarUI
- 上の
JScrollBar
に矢印ボタンなどを非表示化とノブの半透明化などを行うScrollBarUI
を設定
- 上の
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();
}
}
- 以下は、サイズ
0
のArrowButton
を使用するScrollBarUI
を設定する方法
class ArrowButtonlessScrollBarUI extends BasicScrollBarUI {
private static final Color DEFAULT_COLOR = new Color(220, 100, 100, 100);
private static final Color DRAGGING_COLOR = new Color(200, 100, 100, 100);
private static final Color ROLLOVER_COLOR = new Color(255, 120, 100, 100);
@Override protected JButton createDecreaseButton(int orientation) {
return new ZeroSizeButton();
}
@Override protected JButton createIncreaseButton(int orientation) {
return new ZeroSizeButton();
}
@Override protected void paintTrack(Graphics g, JComponent c, Rectangle r) {
// Graphics2D g2 = (Graphics2D) g.create();
// g2.setPaint(new Color(100, 100, 100, 100));
// g2.fillRect(r.x, r.y, r.width - 1, r.height - 1);
// g2.dispose();
}
@Override protected void paintThumb(Graphics g, JComponent c, Rectangle r) {
JScrollBar sb = (JScrollBar) c;
if (!sb.isEnabled()) {
return;
}
BoundedRangeModel m = sb.getModel();
int iv = m.getMaximum() - m.getMinimum() - m.getExtent() - 1; //-1:bug?
if (iv > 0) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
Color color;
if (isDragging) {
color = DRAGGING_COLOR;
} else if (isThumbRollover()) {
color = ROLLOVER_COLOR;
} else {
color = DEFAULT_COLOR;
}
g2.setPaint(color);
g2.fillRect(r.x, r.y, r.width - 1, r.height - 1);
g2.dispose();
}
}
}
JScrollPane scroll = new JScrollPane(new JTextField(TEXT), ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
- 縦スクロールバーを非表示にした
JScrollPane
を使用する場合、JTextField
内の文字列選択でスクロールしない - 文字列を適当な長さまで削除するとノブが非表示になる
- 縦スクロールバーを非表示にした