Java >> Java Program >  >> Java

Hur markerar jag JTable-cellinmatning som ogiltig?

private static class JTable.GenericEditor använder introspektion för att fånga upp undantag genom att konstruera specifika Number underklasser med ogiltig String värden. Om du inte behöver ett sådant generiskt beteende, överväg att skapa PositiveIntegerCellEditor som en underklass till DefaultCellEditor . Din stopCellEditing() metoden skulle vara motsvarande enklare.

Tillägg:Uppdaterad för att använda RIGHT justering och vanlig felkod.

Tillägg:Se även Använda en redigerare för att validera användarinmatad text .

    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);
    }
}

Jag listade ut det. Åsidosätt DefaultCellEditor och returnera false / sätt gränsen till röd om siffran inte är positiv.

Tyvärr, eftersom JTable.GenericEditor är static med default omfattning, jag kan inte åsidosätta GenericEditor att tillhandahålla den här funktionen och måste implementera den igen med några justeringar, såvida inte någon har ett bättre sätt att göra detta, vilket jag skulle vilja höra.

    @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;
        }
    }

Denna kod är en liten förbättring av det accepterade svaret. Om användaren inte anger något värde, klicka på en annan cell skulle tillåta honom att välja en annan cell. Den accepterade lösningen tillåter inte detta.

@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();
}

Denna lösning söker efter tom text. Om texten är tom ringer vi stopCellEditing() metod.


Java-tagg