JTextFieldでカーソルキーによる水平スクロールのスパンを変更する
Total: 646, Today: 1, Yesterday: 1
Posted by aterai at
Last-modified:
Summary
JTextFieldへのカーソルキー入力で水平スクロールが発生する場合のスクロールスパンを変更します。
Screenshot

Advertisement
Source Code Examples
// @see WindowsTextFieldUI.WindowsFieldCaret
class HorizontalScrollCaret extends DefaultCaret {
@Override protected void adjustVisibility(Rectangle r) {
EventQueue.invokeLater(() -> {
JTextComponent c = getComponent();
if (c instanceof JTextField) {
horizontalScroll((JTextField) c, r);
}
});
}
private void horizontalScroll(JTextField field, Rectangle r) {
TextUI ui = field.getUI();
int dot = getDot();
Position.Bias bias = Position.Bias.Forward;
Rectangle startRect = null;
try {
startRect = ui.modelToView(field, dot, bias);
} catch (BadLocationException ble) {
UIManager.getLookAndFeel().provideErrorFeedback(field);
}
Insets i = field.getInsets();
BoundedRangeModel vis = field.getHorizontalVisibility();
int x = r.x + vis.getValue() - i.left;
int n = 8;
int span = vis.getExtent() / n;
if (r.x < i.left) {
vis.setValue(x - span);
} else if (r.x + r.width > i.left + vis.getExtent()) {
vis.setValue(x - (n - 1) * span);
}
if (startRect != null) {
try {
Rectangle endRect = ui.modelToView(field, dot, bias);
if (endRect != null && !endRect.equals(startRect)) {
damage(endRect);
}
} catch (BadLocationException ble) {
UIManager.getLookAndFeel().provideErrorFeedback(field);
}
}
}
}
View in GitHub: Java, KotlinDescription
LookAndFeel Default- デフォルトの
JTextFieldでは現在のLookAndFeelが使用するCaretに依存してカーソルキー入力による水平スクロールスパン(移動量)が決まる MetalLookAndFeelやNimbusLookAndFeelの場合、DefaultCaretがJTextComponent#scrollRectToVisible(...)を使用して1文字分ずつ滑らかにスクロールするWindowsTextFieldUIの場合、WindowsTextFieldUI.WindowsFieldCaretが同様にJTextComponent#scrollRectToVisible(...)を使用してスクロールするが、その移動量はJTextFieldに設定されたBoundedRangeModelのエクステント(JTextFieldの表示可能なサイズ)の1/4(int quarterSpan = vis.getExtent() / 4;)ずつのスパンでジャンプ・スクロールになる
- デフォルトの
DefaultCaretWindowsLookAndFeelでも1文字分ずつスクロールするようJTextFieldにDefaultCaretを設定
override DefaultCaret#adjustVisibility(...)- DefaultCaret#adjustVisibility(Rectangle)をオーバーライドしてエクステントの
1/8ずつのスパンでジャンプ・スクロールするCaretを作成し、JTextFieldに設定
- DefaultCaret#adjustVisibility(Rectangle)をオーバーライドしてエクステントの