如何防止JTable中的单元格为空

时间:2014-02-24 10:26:52

标签: java jtable

我有一个包含自定义表模型的表,用于设置每列的类。如果用户尝试在数字列中输入字符串,则他/她将无法移动到下一个单元格。这是自动完成的,因为我已在表模型类中指定了列类型。问题是,在我的程序中,如果用户删除单元格中的所有内容并按Tab键移动到下一个单元格,我会收到错误消息:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at sweets.SP1$6.tableChanged(Main.java:1508)
at javax.swing.table.AbstractTableModel.fireTableChanged(AbstractTableModel.java:296)
at javax.swing.table.AbstractTableModel.fireTableCellUpdated(AbstractTableModel.java:275)
at javax.swing.table.DefaultTableModel.setValueAt(DefaultTableModel.java:667)
at javax.swing.JTable.setValueAt(JTable.java:2740)
at javax.swing.JTable.editingStopped(JTable.java:4722)
at javax.swing.AbstractCellEditor.fireEditingStopped(AbstractCellEditor.java:141)
at javax.swing.DefaultCellEditor$EditorDelegate.stopCellEditing(DefaultCellEditor.java:368)
at javax.swing.DefaultCellEditor.stopCellEditing(DefaultCellEditor.java:233)
at javax.swing.JTable$GenericEditor.stopCellEditing(JTable.java:5467)
at javax.swing.plaf.basic.BasicTableUI$Actions.actionPerformed(BasicTableUI.java:502)
at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1664)
at javax.swing.JComponent.processKeyBinding(JComponent.java:2879)
at javax.swing.JTable.processKeyBinding(JTable.java:5258)
at javax.swing.JComponent.processKeyBindings(JComponent.java:2940)
at javax.swing.JComponent.processKeyEvent(JComponent.java:2842)
at java.awt.Component.processEvent(Component.java:6282)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4861)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1895)
at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:762)
at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1027)
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:899)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:727)
at java.awt.Component.dispatchEventImpl(Component.java:4731)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Window.dispatchEventImpl(Window.java:2719)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:735)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:694)
at java.awt.EventQueue$3.run(EventQueue.java:692)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:708)
at java.awt.EventQueue$4.run(EventQueue.java:706)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:705)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

如何禁止用户将单元格留空?或者至少,如果他/她在单元格为空时按Tab键,那么我希望重新实例化单元格中的最后一个正确值。感谢。

1 个答案:

答案 0 :(得分:0)

此链接:http://tips4java.wordpress.com/2009/06/07/table-cell-listener/显示了一种添加侦听器的方法,一旦单元格的数据发生更改,该侦听器就可以访问单元格的旧值和新值。 (您必须包含一个也包含在站点中的自定义类)如果您可以使用它,则检测单元格何时更改,如果新值等于null / empty,则提示用户输入一些数据,或者只需将单元格设置为旧值。

修改

下面的内容可能就是您想要的。记得把额外的.java文件放在Classpath上的某个地方

public class SO {
public static void main(String args[]) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Vector<String> rowOne = new Vector<String>();
rowOne.addElement("Bob");
rowOne.addElement("dave");
rowOne.addElement("Rowan");

Vector<String> rowTwo = new Vector<String>();
rowTwo.addElement("Jane");
rowTwo.addElement("Florence");
rowTwo.addElement("Heather");

Vector<String> rowThree = new Vector<String>();
rowThree.add("Star Wars");
rowThree.add("Darth Vader");
rowThree.add("Great White Shark");


Vector<Vector<String>> rowData = new Vector<Vector<String>>();
rowData.addElement(rowOne);
rowData.addElement(rowTwo);
rowData.addElement(rowThree);


Vector<String> columnNames = new Vector<String>();
columnNames.addElement("Column One");
columnNames.addElement("Column Two");
columnNames.addElement("Column Three");  
table = new JTable(rowData, columnNames);


//This is where the extra class comes in
Action action = new AbstractAction()
{
    public void actionPerformed(ActionEvent e)
    {
        TableCellListener tcl = (TableCellListener)e.getSource();
        if(tcl.getNewValue() == null || tcl.getNewValue().toString().trim().equals("")){
            table.getModel().setValueAt(tcl.getOldValue(), tcl.getRow(), tcl.getColumn());
        }
        System.out.println("Row   : " + tcl.getRow());
        System.out.println("Column: " + tcl.getColumn());
        System.out.println("Old   : " + tcl.getOldValue());
        System.out.println("New   : " + tcl.getNewValue());
    }
};
new TableCellListener(table, action);

frame.add(table);
JScrollPane scrollPane = new JScrollPane(table);
frame.add(scrollPane, BorderLayout.CENTER);
frame.setSize(700, 240);
frame.setVisible(true);
  }

 private static JTable table;
 }

祝你好运!