Я написал обычай DefaultCellEditor
, чтобы при вводе в столбце length
примера JTable
я не могу ничего вводить, кроме цифр.Стоп JTable доступен для редактирования только при фокусировке и нажатии клавиши
Для этого я добавил KeyListener
в JTextField
, который используется в качестве компонента редактора. Хотя это отлично работает, если вы дважды щелкните по ячейке, чтобы изменить значение, это не сработает, если вы нажмете на ячейку один раз, а затем начнете вводить текст.
Как я могу запретить пользователю редактировать ячейку, если они нажимают на ячейку один раз, а затем начинают печатать, в то же время позволяя пользователю дважды щелкнуть по ячейке, чтобы начать ее редактирование?
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.lang.reflect.Constructor;
import javax.swing.DefaultCellEditor;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.border.LineBorder;
@SuppressWarnings("serial")
public class JTableTest extends JFrame {
private JTableTest() {
super("JTable Test");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new GridLayout(1, 1));
createPanel();
pack();
setVisible(true);
}
JPanel panel = new JPanel(new GridLayout(1, 1));
JScrollPane scroll;
private void createPanel() {
Object[] headers = {"Length", "Title"};
Object[][] sampleData = {{"673", "Bat Outta Hell"},
{"358", "Spanish Train"},
{"673", "Bat Outta Hell"}};
JTable table = new JTable(sampleData, headers);
table.setDefaultEditor(Object.class, new NumEditor());
scroll = new JScrollPane(table);
panel.add(scroll);
getContentPane().add(panel);
}
private class NumEditor extends DefaultCellEditor {
Class<?>[] argTypes = new Class<?>[]{String.class};
Constructor<?> constructor;
Object value;
public NumEditor() {
super(new JTextField());
getComponent().setName("Table.editor");
}
public boolean stopCellEditing() {
String s = (String)super.getCellEditorValue();
try {
if ("".equals(s)) {
if (constructor.getDeclaringClass() == String.class) {
value = s;
}
return super.stopCellEditing();
}
value = constructor.newInstance(new Object[]{s});
}
catch (Exception e) {
((JComponent)getComponent()).setBorder(new LineBorder(Color.red));
return false;
}
return super.stopCellEditing();
}
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
this.value = null;
((JComponent)getComponent()).setBorder(new LineBorder(Color.black));
try {
Class<?> type = table.getColumnClass(column);
if (type == Object.class) {
type = String.class;
}
KeyListener kL = new KeyListener() {
public void keyPressed(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
char c = e.getKeyChar();
if(Character.isDigit(c)){
} else {
e.consume();
}
}
};
if(column == 0)
((JComponent)getComponent()).addKeyListener(kL);
else
((JComponent)getComponent()).removeKeyListener(kL);
constructor = type.getConstructor(argTypes);
}
catch (Exception e) {
return null;
}
return super.getTableCellEditorComponent(table, value, isSelected, row, column);
}
public Object getCellEditorValue() {
return value;
}
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> new JTableTest());
}
}
Это было действительно очень просто. Спасибо за помощь – Dan
Добро пожаловать @Dan =) –
Просто быстрый вопрос. Вы не знаете, почему «KeyListener» не удаляется, когда я использую другой столбец? – Dan