我有一个实际上有6列和多行的JTable。现在我想更改选择并通过按键盘上的一个或多个键跳转到该行。
这是我想要的例子:
如果我按下" S"在键盘上我的应用程序应该选择我的表中的第一行,其中一个条目以char" S"开头。
但是如果按两个键" SC"对于以" SC"开头的行应该做同样的事情。像上面一样。
当我按下另一个键时,例如" BHM",它应该对以" BHM"开头的行执行相同操作。像上面一样。
我已经实现了这个但是它无法正常工作
P.S在按键过多后,GUI也会冻结。
这是我的完整代码。
MyTable.java
public class MyTable extends JPanel {
public JScrollPane jScrollPane1;
public JTextField searchField;
public JTable table;
Object[] data = new Object[6];
ArrayList rows = new ArrayList();
MyTable() {
table = new JTable();
table.setAutoCreateRowSorter(true);
table.setModel(new DefaultTableModel(
new Object[][]{},
new String[]{
"Description", "Code", "Qty", "Cost", "Rate", "Packing"
}
) {
Class[] types = new Class[]{
String.class, String.class, Integer.class, Double.class, Double.class, String.class
};
boolean[] canEdit = new boolean[]{
false, false, false, false, false, false
};
public Class getColumnClass(int columnIndex) {
return types[columnIndex];
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit[columnIndex];
}
});
table.setColumnSelectionAllowed(true);
table.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
table.getTableHeader().setReorderingAllowed(false);
table.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
if (table.getColumnModel().getColumnCount() > 0) {
table.getColumnModel().getColumn(0).setMinWidth(300);
table.getColumnModel().getColumn(0).setPreferredWidth(300);
table.getColumnModel().getColumn(0).setMaxWidth(1000);
table.getColumnModel().getColumn(1).setMinWidth(100);
table.getColumnModel().getColumn(1).setPreferredWidth(100);
table.getColumnModel().getColumn(1).setMaxWidth(500);
table.getColumnModel().getColumn(2).setMinWidth(50);
table.getColumnModel().getColumn(2).setPreferredWidth(50);
table.getColumnModel().getColumn(2).setMaxWidth(100);
table.getColumnModel().getColumn(3).setMinWidth(80);
table.getColumnModel().getColumn(3).setPreferredWidth(80);
table.getColumnModel().getColumn(3).setMaxWidth(200);
table.getColumnModel().getColumn(4).setMinWidth(80);
table.getColumnModel().getColumn(4).setPreferredWidth(80);
table.getColumnModel().getColumn(4).setMaxWidth(200);
table.getColumnModel().getColumn(5).setMinWidth(80);
table.getColumnModel().getColumn(5).setPreferredWidth(80);
table.getColumnModel().getColumn(5).setMaxWidth(200);
}
table.setPreferredScrollableViewportSize(new Dimension(800, 600));
table.setFillsViewportHeight(true);
table.setRowHeight(30);
JScrollPane scrollPane = new JScrollPane(table);
add(scrollPane);
table.addKeyListener(new SearchingKeyAdapter(table));
addRowData();
table.changeSelection(0, 0, false, false);
}
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("MyTable");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
MyTable newContentPane = new MyTable();
newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
}
private void addRowData() {
String desc = "SL 123";
Integer code = 12345;
Integer qty = 10;
Double rate = new Double(1000);
Double cost = new Double(900);
String pack = "10x10x10";
data[0] = desc;
data[1] = code;
data[2] = qty;
data[3] = cost;
data[4] = rate;
data[5] = pack;
DefaultTableModel model = (DefaultTableModel) table.getModel();
for (int i = 0; i < 5; i++) {
data[0] = "SL " + i;
rows.add(data);
model.addRow(data);
}
rows.clear();
for (int i = 0; i < 5; i++) {
data[0] = "SC " + i;
rows.add(data);
model.addRow(data);
}
data[0] = "AP";
model.addRow(data);
data[0] = "GP";
model.addRow(data);
data[0] = "PS";
model.addRow(data);
data[0] = "PP";
model.addRow(data);
data[0] = "BHM";
model.addRow(data);
data[0] = "BGP";
model.addRow(data);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
SearchingKeyAdapter.java
public class SearchingKeyAdapter extends KeyAdapter {
String key = "";
private final JTable table;
private int selectedRow = -1;//before start
public SearchingKeyAdapter(JTable table) {
this.table = table;
}
@Override
public void keyPressed(KeyEvent e) {
key += String.valueOf(e.getKeyChar());
}
@Override
public void keyReleased(KeyEvent e) {
String keyChar = key.toUpperCase();
key = "";
TableModel model = table.getModel();
int startRow = selectedRow;
if (selectedRow == model.getRowCount() - 1) {
startRow = -1;//Go before start
}
int col = 0;
for (int row = startRow + 1; row < model.getRowCount(); row++) {
String value = (String) model.getValueAt(row, col);
if (value != null && !value.isEmpty() && value.toUpperCase().startsWith(keyChar)) {
table.getSelectionModel().clearSelection();
table.getColumnModel().getSelectionModel().clearSelection();
table.setRowSelectionInterval(row, row);
table.changeSelection(row, col, false, false);
selectedRow = row;
return;
}
}
}
}
谢谢!
答案 0 :(得分:1)
我已经实现了这个但是它无法正常工作
您的示例似乎并未假设所选行已通过箭头键或鼠标单击进行更改。
修改JList
中的类似功能可能比创建自己的KeyListener
更容易。
JList#getNextMatch(...):返回其toString值以给定前缀开头的下一个列表元素。
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.text.Position;
public class MyTable2 extends JPanel {
public JScrollPane jScrollPane1;
public JTextField searchField;
public JTable table;
private final Object[] data = new Object[6];
private final ArrayList<Object[]> rows = new ArrayList<>();
private MyTable2() {
table = new JTable();
table.setAutoCreateRowSorter(true);
table.setModel(new DefaultTableModel(
new String[] {
"Description", "Code", "Qty", "Cost", "Rate", "Packing"
}, 0
) {
Class[] types = new Class[] {
String.class, String.class, Integer.class, Double.class, Double.class, String.class
};
@Override public Class getColumnClass(int columnIndex) {
return types[columnIndex];
}
@Override public boolean isCellEditable(int rowIndex, int columnIndex) {
return false;
}
});
table.setColumnSelectionAllowed(true);
table.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
table.getTableHeader().setReorderingAllowed(false);
table.getColumnModel().getSelectionModel().setSelectionMode(
ListSelectionModel.SINGLE_SELECTION);
table.setPreferredScrollableViewportSize(new Dimension(800, 600));
table.setFillsViewportHeight(true);
table.setRowHeight(30);
//table.addKeyListener(new SearchingKeyAdapter(table));
table.addKeyListener(new TableNextMatchKeyHandler());
JScrollPane scrollPane = new JScrollPane(table);
add(scrollPane);
addRowData();
table.changeSelection(0, 0, false, false);
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("MyTable");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new MyTable2());
frame.pack();
frame.setVisible(true);
}
private void addRowData() {
String desc = "SL 123";
Integer code = 12345;
Integer qty = 10;
Double rate = new Double(1000);
Double cost = new Double(900);
String pack = "10x10x10";
data[0] = desc;
data[1] = code;
data[2] = qty;
data[3] = cost;
data[4] = rate;
data[5] = pack;
DefaultTableModel model = (DefaultTableModel) table.getModel();
for (int i = 0; i < 5; i++) {
data[0] = "SL " + i;
rows.add(data);
model.addRow(data);
}
rows.clear();
for (int i = 0; i < 5; i++) {
data[0] = "SC " + i;
rows.add(data);
model.addRow(data);
}
data[0] = "AP";
model.addRow(data);
data[0] = "GP";
model.addRow(data);
data[0] = "PS";
model.addRow(data);
data[0] = "PP";
model.addRow(data);
data[0] = "BHM";
model.addRow(data);
data[0] = "BGP";
model.addRow(data);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
//@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 static final long TIME_FACTOR = 500L;
private String prefix = "";
private String typedString;
private long lastTime;
private boolean isNavigationKey(KeyEvent event) {
JTable table = (JTable) event.getComponent();
InputMap im = table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
KeyStroke key = KeyStroke.getKeyStrokeForEvent(event);
return Objects.nonNull(im) && Objects.nonNull(im.get(key));
}
@Override public void keyPressed(KeyEvent e) {
if (isNavigationKey(e)) {
prefix = "";
typedString = "";
lastTime = 0L;
}
}
@Override public void keyTyped(KeyEvent e) {
JTable src = (JTable) e.getComponent();
int max = src.getRowCount();
if (max == 0 || e.isAltDown() || isNavigationKey(e)) {
//|| BasicGraphicsUtils.isMenuShortcutKeyDown(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 < TIME_FACTOR) {
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 = String.valueOf(c);
prefix = typedString;
}
lastTime = time;
selectAndScrollNextMatch(src, max, e, prefix, startIndex, startingFromSelection);
}
private static void selectAndScrollNextMatch(
JTable src, int max, KeyEvent e, String prefix,
int startIndex, boolean startingFromSelection) {
int start = startIndex;
boolean isStartingSelection = startingFromSelection;
if (start < 0 || start >= max) {
if (e.isShiftDown()) {
start = max - 1;
} else {
isStartingSelection = false;
start = 0;
}
}
Position.Bias bias = e.isShiftDown() ? Position.Bias.Backward : Position.Bias.Forward;
int index = getNextMatch(src, prefix, start, bias);
if (index >= 0) {
src.getSelectionModel().setSelectionInterval(index, index);
src.scrollRectToVisible(src.getCellRect(index, TARGET_COLUMN, true));
} else if (isStartingSelection) { // wrap
index = getNextMatch(src, prefix, 0, bias);
if (index >= 0) {
src.getSelectionModel().setSelectionInterval(index, index);
src.scrollRectToVisible(src.getCellRect(index, TARGET_COLUMN, true));
}
}
}
//@see javax/swing/JList#getNextMatch(String prefix, int startIndex, Position.Bias bias)
//@see javax/swing/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 (Objects.isNull(prefix) || 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;
}
}