11

を取り、JTable次のようにモデルで列のクラスタイプを指定すると:

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

その後、ユーザーがテーブルに値を入力しようとするとdouble、Swing は自動的に入力を拒否し、セルのアウトラインを赤に設定します。

誰かがセルに「負または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がどのように拒否を行っているかを調べてみましたが、見つけられないようです。

非整数入力を拒否するのと同じ方法で、非正入力を拒否するにはどうすればよいですか?

4

4 に答える 4

15

はイントロスペクションを使用して、無効な値を持つ特定のサブクラスをprivate static class JTable.GenericEditor構築することによって発生した例外をキャッチします。このような一般的な動作が必要ない場合は、 のサブクラスとして作成することを検討してください。あなたの方法はそれに応じて簡単になります。NumberStringPositiveIntegerCellEditorDefaultCellEditorstopCellEditing()

補遺:RIGHTアラインメントと一般的なエラー コードを使用するように更新されました。

補遺:ユーザーが入力したテキストを検証するためのエディターの使用も参照してください。

ここに画像の説明を入力

    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);
    }
}
于 2011-09-24T13:23:02.833 に答える
2

このコードは、受け入れられた回答を少し改善したものです。ユーザーが値を入力しない場合、別のセルをクリックすると、別のセルを選択できるようになります。受け入れられた解決策では、これは許可されません。

@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()メソッドを呼び出します。

于 2014-03-10T15:28:44.350 に答える
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;
        }
    }
于 2011-09-23T16:59:42.800 に答える
0

そこで、まず、このトピックを理解しやすくするために類推を作成しました。
私たちはペン( editor)を持っています。このペンを書くには、いくらかのインク (componentエディターが使用するもの、コンポーネントの例は などJTextField)JComboBoxが必要です。

次に、これはペンを使用して何かを書きたい場合の特別なペンであり、話す (GUI での入力動作) ことで、何かを書くように伝えます (に書き込みますmodel)。書き出す前に、このペンのプログラムは単語が有効かどうかを評価し (stopCellEditing()メソッドで設定されます)、単語を紙に書き出します ( model)。

セクションに4時間費やしたので、@trashgodの答えを説明したいと思いますDefaultCellEditor

//first, we create a new class which inherit DefaultCellEditor
private static class PositiveIntegerCellEditor extends DefaultCellEditor {
//create 2 constant to be used when input is invalid and valid
    private static final Border red = new LineBorder(Color.red);
    private static final Border black = new LineBorder(Color.black);
    private JTextField textField;

//construct a `PositiveIntegerCellEditor` object  
//which use JTextField when this constructor is called
    public PositiveIntegerCellEditor(JTextField textField) {
        super(textField);
        this.textField = textField;
        this.textField.setHorizontalAlignment(JTextField.RIGHT);
    }
//basically stopCellEditing() being called to stop the editing mode  
//but here we override it so it will evaluate the input before  
//stop the editing mode
    @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;
        }
//if no exception thrown,call the normal stopCellEditing()
        return super.stopCellEditing();
    }

//we override the getTableCellEditorComponent method so that
//at the back end when getTableCellEditorComponent method is  
//called to render the input, 
//set the color of the border of the JTextField back to black 
    @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);
    }
}  

最後に、クラスで次のコード行を使用して、JTable を初期化し、DefaultCellEditor

table.setDefaultEditor(Object.class,new PositiveIntegerCellEditor(new JTextField()));

Object.classエディターを適用する列クラスのタイプを意味します (そのペンを使用する紙の部分。 、および他のクラスにすることができますInteger.class) Double.class
次にnew JTextField()、PositiveIntegerCellEditor() コンストラクター (使用するインクの種類を決定します) を渡します。

私が誤解したことがあれば教えてください。お役に立てれば!

于 2019-07-26T03:37:16.590 に答える