2011-09-23 88 views
9

如果我参加一个JTable并在其上的指定模型列的CLASSTYPE如下:如何将JTable单元格输入标记为无效?

DefaultTableModel model = new DefaultTableModel(columnNames, 100) { 
     @Override 
     public Class<?> getColumnClass(int columnIndex) { 
      return Integer.class; 
     }}; 

然后,每当用户试图进入一个double值到表中,摇摆自动拒绝输入,并设置单元格的轮廓红。

我希望在某人向单元格输入'负数或0'输入时发生同样的效果。我有这样的:

@Override 
    public void setValueAt(Object val, int rowIndex, int columnIndex) { 
     if (val instanceof Number && ((Number) val).doubleValue() > 0) { 
       super.setValueAt(val, rowIndex, columnIndex); 
      } 
     } 
    } 

这阻止细胞接受任何非正面的价值观,但它好好尝试设置颜色为红色和离开细胞为可编辑。

我试图寻找JTable如何在默认情况下进行拒绝,但我似乎无法找到它。

我如何使它拒绝非积极输入与拒绝非积分输入相同?

谢谢

回答

14

private static class JTable.GenericEditor用内省赶上通过构建特定Number子类无效String值引发的异常。如果您不需要此类通用行为,请考虑创建PositiveIntegerCellEditor作为DefaultCellEditor的子类。你的stopCellEditing()方法会相应更简单。

附录:更新为使用RIGHT对齐和常见错误代码。

附录:另请参阅Using an Editor to Validate User-Entered Text

enter image description here

private static class PositiveIntegerCellEditor extends DefaultCellEditor { 

    private static final Border red = new LineBorder(Color.red); 
    private static final Border black = new LineBorder(Color.black); 
    private JTextField textField; 

    public PositiveIntegerCellEditor(JTextField textField) { 
     super(textField); 
     this.textField = textField; 
     this.textField.setHorizontalAlignment(JTextField.RIGHT); 
    } 

    @Override 
    public boolean stopCellEditing() { 
     try { 
      int v = Integer.valueOf(textField.getText()); 
      if (v < 0) { 
       throw new NumberFormatException(); 
      } 
     } catch (NumberFormatException e) { 
      textField.setBorder(red); 
      return false; 
     } 
     return super.stopCellEditing(); 
    } 

    @Override 
    public Component getTableCellEditorComponent(JTable table, 
     Object value, boolean isSelected, int row, int column) { 
     textField.setBorder(black); 
     return super.getTableCellEditorComponent(
      table, value, isSelected, row, column); 
    } 
} 
+0

感谢这更清洁。我确实回去更新我的代码,使其不那么通用,因为我只是试图在一个特定的地方使用它,我可以控制它的使用。 – Cuga

+0

另请参阅此[备选](http://stackoverflow.com/a/13510756/230513)。 – trashgod

+0

@trashgod +1 hey trashgod使用documentFilter替代不要让用户类型是个好主意吗? – nachokk

2

我想通了。覆盖DefaultCellEditor并返回false /将边框设置为红色,如果给定的数字不是正数。

不幸的是,因为JTable.GenericEditor是static瓦特/ default范围,我无法覆盖GenericEditor提供此功能,并有重新实现它瓦特/一些调整,除非有人做的更好的办法这个,我想听听。

@SuppressWarnings("serial") 
    class PositiveNumericCellEditor extends DefaultCellEditor { 

     Class[] argTypes = new Class[]{String.class}; 
     java.lang.reflect.Constructor constructor; 
     Object value; 

     public PositiveNumericCellEditor() { 
      super(new JTextField()); 
      getComponent().setName("Table.editor"); 
      ((JTextField)getComponent()).setHorizontalAlignment(JTextField.RIGHT); 
     } 

     public boolean stopCellEditing() { 
      String s = (String)super.getCellEditorValue(); 
      if ("".equals(s)) { 
       if (constructor.getDeclaringClass() == String.class) { 
        value = s; 
       } 
       super.stopCellEditing(); 
      } 

      try { 
       value = constructor.newInstance(new Object[]{s}); 
       if (value instanceof Number && ((Number) value).doubleValue() > 0) 
       { 
        return super.stopCellEditing(); 
       } else { 
        throw new RuntimeException("Input must be a positive number."); 
       } 
      } 
      catch (Exception e) { 
       ((JComponent)getComponent()).setBorder(new LineBorder(Color.red)); 
       return false; 
      } 
     } 

     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; 
       } 
       constructor = type.getConstructor(argTypes); 
      } 
      catch (Exception e) { 
       return null; 
      } 
      return super.getTableCellEditorComponent(table, value, isSelected, row, column); 
     } 

     public Object getCellEditorValue() { 
      return value; 
     } 
    } 
+0

+1 [通用](http://en.wikipedia.org/wiki/Generic_programming)。您可以尝试将[Class Literal as Runtime-Type Token](http://download.oracle.com/javase/tutorial/extra/generics/literals.html)传递给构造函数,但这并不是特别简单。 – trashgod

1

此代码是公认的答案的一个小的提升。如果 用户没有输入任何值,则单击其他单元格应允许他选择另一个单元格。接受的解决方案不允许 允许。

@Override 
public boolean stopCellEditing() { 

    String text = field.getText(); 

    if ("".equals(text)) { 
     return super.stopCellEditing(); 
    } 

    try { 
     int v = Integer.valueOf(text); 

     if (v < 0) { 
      throw new NumberFormatException(); 
     }    
    } catch (NumberFormatException e) { 

     field.setBorder(redBorder); 
     return false; 
    } 

    return super.stopCellEditing(); 
} 

此解决方案检查空文本。如果是空文本,我们称之为stopCellEditing()方法。