java - 我想要一个JTable单元格/列,只允许我输入一位数字(如1到9)。我怎么能这样做?
我试过这个,但我按下的号码在单元格中出现两次。
table.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
System.out.println("pressed..."+e.getKeyChar());
char key = e.getKeyChar();
int selectedColumn = table.getSelectedColumn();
int selectedRow = table.getSelectedRow();
if(table.getValueAt(selectedRow, selectedColumn) == null)
table.setValueAt(key, selectedRow, selectedColumn);
}
});
答案 0 :(得分:5)
请勿使用KeyListener
。您可以执行的操作是使用JTextField
TableCellEditor
,只需将DocumentFilter
添加到仅允许数字的JTextField
。
这是一个正在运行的例子
import javax.swing.DefaultCellEditor;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.table.TableCellEditor;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;
import javax.swing.text.DocumentFilter.FilterBypass;
public class JTableNumberColumn {
public JTableNumberColumn() {
JFrame frame = new JFrame();
JTextField field = createTextField();
frame.add(new JScrollPane(createTable(field)));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private JTextField createTextField() {
JTextField field = new JTextField();
((AbstractDocument) field.getDocument()).setDocumentFilter(new DocumentFilter() {
@Override
public void insertString(FilterBypass fb, int off, String str, AttributeSet attr)
throws BadLocationException {
fb.insertString(off, str.replaceAll("\\D++", ""), attr); // remove non-digits
}
@Override
public void replace(FilterBypass fb, int off, int len, String str, AttributeSet attr)
throws BadLocationException {
fb.replace(off, len, str.replaceAll("\\D++", ""), attr); // remove non-digits
}
});
return field;
}
private JTable createTable(final JTextField field) {
String[] cols = {"Only Numbers", "Col 2", "Col 3"};
String[][] data = {{null, null, null}, {null, null, null}, {null, null, null}};
final TableCellEditor editor = new DefaultCellEditor(field);
JTable table = new JTable(data, cols) {
@Override
public TableCellEditor getCellEditor(int row, int column) {
int modelColumn = convertColumnIndexToModel(column);
if (modelColumn == 0) {
return editor;
} else {
return super.getCellEditor(row, column);
}
}
};
return table;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new JTableNumberColumn();
}
});
}
}
我可能误解了你的问题。如果您只想允许一个号码。然后,您可以使用JFormattedTextField
MaskFormatter
作为TableCellEditor
。这是一个例子
import javax.swing.DefaultCellEditor;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.TableCellEditor;
import javax.swing.text.MaskFormatter;
public class JTableNumberColumn {
public JTableNumberColumn() {
JFrame frame = new JFrame();
JFormattedTextField field = createFormattedTextField();
frame.add(new JScrollPane(createTable(field)));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private JFormattedTextField createFormattedTextField() {
JFormattedTextField field = new JFormattedTextField(createFormatter("#"));
return field;
}
protected MaskFormatter createFormatter(String s) {
MaskFormatter formatter = null;
try {
formatter = new MaskFormatter(s);
} catch (java.text.ParseException exc) {
System.err.println("formatter is bad: " + exc.getMessage());
System.exit(-1);
}
return formatter;
}
private JTable createTable(final JFormattedTextField field) {
String[] cols = {"Only Numbers", "Col 2", "Col 3"};
String[][] data = {{null, null, null}, {null, null, null}, {null, null, null}};
final TableCellEditor editor = new DefaultCellEditor(field);
JTable table = new JTable(data, cols) {
@Override
public TableCellEditor getCellEditor(int row, int column) {
int modelColumn = convertColumnIndexToModel(column);
if (modelColumn == 0) {
return editor;
} else {
return super.getCellEditor(row, column);
}
}
};
return table;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new JTableNumberColumn();
}
});
}
}
它引起了我的注意,我也忽略了你只想要1-9而不是0-9的事实。在这种情况下,我只会坚持使用JTextField
DocumentFilter
的第一个选项,但在过滤器中,检查输入的长度并将正则表达式更改为仅允许1-9。
这是示例
import javax.swing.DefaultCellEditor;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.table.TableCellEditor;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;
import javax.swing.text.DocumentFilter.FilterBypass;
public class JTableNumberColumn {
public JTableNumberColumn() {
JFrame frame = new JFrame();
JTextField field1 = createTextField();
frame.add(new JScrollPane(createTable(field1)));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private JTextField createTextField() {
final JTextField field = new JTextField();
((AbstractDocument) field.getDocument()).setDocumentFilter(new DocumentFilter() {
@Override
public void insertString(FilterBypass fb, int off, String str, AttributeSet attr)
throws BadLocationException {
int length = field.getDocument().getLength();
if (length + str.length() <= 1) {
fb.insertString(off, str.replaceAll("[^1-9]", ""), attr); // remove non-digits
}
}
@Override
public void replace(FilterBypass fb, int off, int len, String str, AttributeSet attr)
throws BadLocationException {
int length = field.getDocument().getLength();
if (length + str.length() <= 1) {
fb.replace(off, len, str.replaceAll("[^1-9]", ""), attr); // remove non-digits
}
}
});
return field;
}
private JTable createTable(final JTextField field) {
String[] cols = {"Only Numbers", "Col 2", "Col 3"};
String[][] data = {{null, null, null}, {null, null, null}, {null, null, null}};
final TableCellEditor editor = new DefaultCellEditor(field);
JTable table = new JTable(data, cols) {
@Override
public TableCellEditor getCellEditor(int row, int column) {
int modelColumn = convertColumnIndexToModel(column);
if (modelColumn == 0) {
return editor;
} else {
return super.getCellEditor(row, column);
}
}
};
return table;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new JTableNumberColumn();
}
});
}
}
答案 1 :(得分:0)
一种方法是实现自己的TableModel(无论如何我会这样做)并实现setValueAt(Object,int,int)方法。在该方法中验证,如果值不好则不设置值(包括放置JDialog或其他适当的值)。以下是一些代码:
public class MyTableModel extends AbstractTableModel {
...
@Override
public void setValueAt(Object o, int i, int j) {
if (o instanceof String) {
char c = ((String) o).charAt(0);
if (((String) o).length() == 1 && c >= '0' && c <= '9') {
data[i][j] = Integer.valueOf(((String) o).substring(0, 1));
return;
}
}
JOptionPane.showMessageDialog(null, "Must input a number from 0-9");
}
我花了很长时间才发布其他人回答的帖子!无论如何,因为我的方法不同,我想我会把它包括在内。我正在制定一个有效的计划。
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
public class TestTable {
public static void main(String[] args) {
TestTable tt = new TestTable();
tt.init();
}
private void init() {
// Make model
MyModel model = new MyModel ();
JTable table = new JTable(model);
// Add to a frame
JScrollPane pane = new JScrollPane(table);
JFrame frame = new JFrame("Test");
frame.add(pane);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
class MyModel extends AbstractTableModel {
// Just some dummy data
Integer[][] data = new Integer[10][6];
// Init the dummy data
public MyModel() {
super();
for (int i = 0; i < data.length; i++) {
Integer[] is = data[i];
for (int j = 0; j < is.length; j++) {
data[i][j] = 20 * i + j;
}
}
}
@Override
public int getRowCount() {
return data.length;
}
@Override
public int getColumnCount() {
return data[0].length;
}
@Override
public Object getValueAt(int i, int j) {
return data[i][j];
}
// Makes cells editable
@Override
public boolean isCellEditable(int i, int j) {
return true;
}
@Override
public void setValueAt(Object o, int i, int j) {
if (o instanceof String) {
char c = ((String) o).charAt(0);
if (((String) o).length() == 1 && c >= '0' && c <= '9') {
data[i][j] = Integer.valueOf(((String) o).substring(0, 1));
return;
}
}
JOptionPane.showMessageDialog(null, "Must input a number from 0-9");
}
}