2011-09-23 56 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()方法。

相關問題