[英]Stop JTable being editable only when focussed and key pressed
我编写了一个自定义的DefaultCellEditor
以便在示例JTable
的length
列中键入内容时只能输入数字。
为此,我向用作编辑器组件的JTextField
添加了一个KeyListener
。 如果双击单元格以编辑值,则效果很好,但单击一次单元格然后开始键入,则无效。
如果用户单击该单元格一次然后开始输入,同时又允许用户双击该单元格来开始对其进行编辑,如何防止用户能够编辑该单元格呢?
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());
}
}
停止JTable仅在聚焦并按下键时才可编辑
好吧,这是在编辑带有字符串数据的单元格时的默认行为。
尝试输入数字数据时为什么会有什么不同?
我编写了一个自定义的DefaultCellEditor,以便在示例JTable的长度列中键入内容时只能输入数字。
无需编写自定义编辑器。 只需使用JFormattedTextField
而不是JTextField作为编辑器即可:
就像是。
MaskFormatter format = new MaskFormatter("######");
JFormattedTextField ftf = new JFormattedTextField( format );
DefaultCellEditor dce = new DefaultCellEditor( ftf );
table.getColumnModel().getColumn(2).setCellEditor(dce);
看一下CellEditor.isCellEditable( EventObject anEvent )
。 AbstractCellEditor
和DefaultCellEditor
实现CellEditor
接口。
如果EventObject
是KeyEvent
类型的实例,则可以重写此方法以返回false。 否则返回super.isCellEditable( anEvent )
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.