Swing/TextFieldCaretScrollSapn のバックアップ(No.1)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/TextFieldCaretScrollSapn へ行く。
- 1 (2025-01-06 (月) 01:06:29)
- 2 (2025-01-06 (月) 03:57:54)
- 3 (2025-01-06 (月) 13:43:07)
- category: swing folder: TextFieldCaretScrollSapn title: JTextFieldでキー入力による水平スクロールのスパンを変更する tags: [JTextField, Caret, LookAndFeel] author: aterai pubdate: 2025-01-06T01:05:24+09:00 description: JTextFieldへのカーソルキー入力で水平スクロールが発生する場合のスクロールスパンを変更します。 image: https://drive.google.com/uc?id=1tdPGBll2KYlWEut4sUdnNRs43VwGgBU5
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
のエクステント(JTextField
の表示可能なサイズ)の1/4
(int quarterSpan = vis.getExtent() / 4;
)ずつのスパンでジャンプ・スクロールになる
- デフォルトの
DefaultCaret
WindowsLookAndFeel
でも1
文字分ずつスクロールするようJTextField
にDefaultCaret
を設定
override DefaultCaret#adjustVisibility(...)
- DefaultCaret#adjustVisibility(Rectangle)をオーバーライドして
JTextField
のエクステントの1/8
スパンずつジャンプ・スクロールするCaret
を作成し、JTextField
に設定
- DefaultCaret#adjustVisibility(Rectangle)をオーバーライドして