JTextFieldでカーソルキーによる水平スクロールのスパンを変更する
Total: 37
, Today: 3
, Yesterday: 34
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, KotlinExplanation
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;
)ずつのスパンでジャンプ・スクロールになる
- デフォルトの
DefaultCaret
WindowsLookAndFeel
でも1
文字分ずつスクロールするようJTextField
にDefaultCaret
を設定
override DefaultCaret#adjustVisibility(...)
- DefaultCaret#adjustVisibility(Rectangle)をオーバーライドしてエクステントの
1/8
ずつのスパンでジャンプ・スクロールするCaret
を作成し、JTextField
に設定
- DefaultCaret#adjustVisibility(Rectangle)をオーバーライドしてエクステントの