Swing/TableNextMatchKeyHandler のバックアップ(No.6)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/TableNextMatchKeyHandler へ行く。
- 1 (2012-12-12 (水) 19:07:09)
- 2 (2013-07-26 (金) 01:00:43)
- 3 (2013-08-16 (金) 16:26:33)
- 4 (2014-03-25 (火) 15:02:30)
- 5 (2014-12-19 (金) 14:19:03)
- 6 (2015-02-18 (水) 15:08:14)
- 7 (2016-11-17 (木) 18:30:27)
- 8 (2017-11-16 (木) 12:30:45)
- 9 (2019-07-02 (火) 16:10:33)
- 10 (2021-03-11 (木) 19:41:41)
- 11 (2025-01-03 (金) 08:57:02)
- 12 (2025-01-03 (金) 09:01:23)
- 13 (2025-01-03 (金) 09:02:38)
- 14 (2025-01-03 (金) 09:03:21)
- 15 (2025-01-03 (金) 09:04:02)
- title: JTableで先頭文字のキー入力による検索を行う tags: [JTable, KeyListener] author: aterai pubdate: 2012-04-16T15:22:21+09:00 description: JTableにフォーカスがある状態でキー入力をした場合、先頭文字が一致する行を検索して選択状態にします。
概要
JTable
にフォーカスがある状態でキー入力をした場合、先頭文字が一致する行を検索して選択状態にします。
Screenshot

Advertisement
サンプルコード
//@see javax/swing/plaf/basic/BasicListUI.Handler
//@see javax/swing/plaf/basic/BasicTreeUI.Handler
class TableNextMatchKeyHandler extends KeyAdapter {
private static final int TARGET_COLUMN = 0;
private String prefix = "";
private String typedString = "";
private long lastTime = 0L;
private long timeFactor;
public TableNextMatchKeyHandler() {
//Long l = (Long)UIManager.get("List.timeFactor");
timeFactor = 500L; //(l!=null) ? l.longValue() : 1000L;
}
private boolean isNavigationKey(KeyEvent e) {
JTable t = (JTable)e.getSource();
InputMap im = t.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
KeyStroke key = KeyStroke.getKeyStrokeForEvent(e);
if (im != null && im.get(key) != null) {
return true;
}
return false;
}
@Override public void keyPressed(KeyEvent e) {
if (isNavigationKey(e)) {
prefix = "";
typedString = "";
lastTime = 0L;
}
}
@Override public void keyTyped(KeyEvent e) {
JTable src = (JTable)e.getSource();
int max = src.getRowCount();
if (max == 0 || e.isAltDown() || isNavigationKey(e)) {
// Nothing to select
return;
}
boolean startingFromSelection = true;
char c = e.getKeyChar();
int increment = e.isShiftDown() ? -1 : 1;
long time = e.getWhen();
int startIndex = src.getSelectedRow();
if (time - lastTime < timeFactor) {
typedString += c;
if ((prefix.length() == 1) && (c == prefix.charAt(0))) {
// Subsequent same key presses move the keyboard focus to the next
// object that starts with the same letter.
startIndex += increment;
} else {
prefix = typedString;
}
} else {
startIndex += increment;
typedString = "" + c;
prefix = typedString;
}
lastTime = time;
if (startIndex < 0 || startIndex >= max) {
if (e.isShiftDown()) {
startIndex = max - 1;
} else {
startingFromSelection = false;
startIndex = 0;
}
}
Position.Bias bias = e.isShiftDown() ? Position.Bias.Backward
: Position.Bias.Forward;
int index = getNextMatch(src, prefix, startIndex, bias);
if (index >= 0) {
src.getSelectionModel().setSelectionInterval(index, index);
src.scrollRectToVisible(src.getCellRect(index, TARGET_COLUMN, true));
} else if (startingFromSelection) { // wrap
index = getNextMatch(src, prefix, 0, bias);
if (index >= 0) {
src.getSelectionModel().setSelectionInterval(index, index);
src.scrollRectToVisible(src.getCellRect(index, TARGET_COLUMN, true));
}
}
}
//@see JList#getNextMatch(String prefix, int startIndex, Position.Bias bias)
//@see JTree#getNextMatch(String prefix, int startIndex, Position.Bias bias)
public static int getNextMatch(
JTable table, String prefix, int startingRow, Position.Bias bias) {
int max = table.getRowCount();
if (prefix == null) {
throw new IllegalArgumentException();
}
if (startingRow < 0 || startingRow >= max) {
throw new IllegalArgumentException();
}
String uprefix = prefix.toUpperCase(Locale.ENGLISH);
// start search from the next/previous element froom the
// selected element
int increment = (bias == Position.Bias.Forward) ? 1 : -1;
int row = startingRow;
do {
Object value = table.getValueAt(row, TARGET_COLUMN);
String text = Objects.toString(value, "");
if (text.toUpperCase(Locale.ENGLISH).startsWith(uprefix)) {
return row;
}
row = (row + increment + max) % max;
} while (row != startingRow);
return -1;
}
}
View in GitHub: Java, Kotlin解説
上記のサンプルでは、キー入力と0
列目の文字列の先頭文字が一致(大文字小文字は無視)する行を検索、選択し、そこまでスクロールします。
検索方法は、BasicListUI.Handler
、BasicTreeUI.Handler
、JList#getNextMatch(...)
、JTree#getNextMatch(...)
のものと、ほぼ同じ(Shiftキーを同時に押すと逆検索を追加)です。
table.putClientProperty("JTable.autoStartsEdit", Boolean.FALSE);
として、キー入力で編集を開始しないように設定- マウスクリック、F2キーでの編集は可能