具有空值的JTable整数单元格编辑器

时间:2018-07-30 21:16:59

标签: java swing null jtable tablecelleditor

我正在尝试创建“自定义单元格编辑器”,该编辑器仅允许输入0到5000之间的整数值。我找到了一些代码,但是当我尝试用空字符串替换旧值(不为null)时出现了问题(我想将空值放在此处)。我总是看到带有“编辑”和“还原”选项的选项对话框。我尝试过修改方法:getCellEditorValue()stopCellEditing(),但没有成功。我希望它是可读的代码,因为这是我的第一篇文章(我将IntegerCellEditor作为内部类放置在一个文件中)。

你能帮我吗?

我正在使用的代码:

public class IntegerCellEditorFrame extends JFrame{
    private static final long serialVersionUID = 1L;
    public IntegerCellEditorFrame() {
        JTable table = new JTable(new DefaultTableModel(5,1));
        table.getColumnModel().getColumn(0).setCellEditor(new IntegerCellEditor(0,5000));
        setTitle("Test IntegerCellEditor");
        setMinimumSize(new Dimension(300,200));
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        add(table);

}

public static void main(String[] args) {
    EventQueue.invokeLater(() -> {
        IntegerCellEditorFrame frame = new IntegerCellEditorFrame();
        frame.setVisible(true);
    });
}

    class IntegerCellEditor extends DefaultCellEditor{
        private static final long serialVersionUID = 1L;

        JFormattedTextField fTextField;
        NumberFormat integerFormat;
        private Integer minimum, maximum;
        private boolean DEBUG = false;

        IntegerCellEditor(int min, int max) {
            super(new JFormattedTextField());
            fTextField = (JFormattedTextField)getComponent();
            minimum = new Integer(min);
            maximum = new Integer(max);

            //Set up the editor for the integer cells.
            integerFormat = NumberFormat.getIntegerInstance();
            NumberFormatter intFormatter = new NumberFormatter(integerFormat);
            intFormatter.setFormat(integerFormat);
            intFormatter.setMinimum(minimum);
            intFormatter.setMaximum(maximum);

            fTextField.setFormatterFactory(new DefaultFormatterFactory(intFormatter));
            fTextField.setValue(minimum);
            fTextField.setFocusLostBehavior(JFormattedTextField.PERSIST);

            fTextField.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),"check");
            fTextField.getActionMap().put("check", new AbstractAction() {
                private static final long serialVersionUID = 1L;
                public void actionPerformed(ActionEvent e) {
                    if(!fTextField.isEditValid()) { //The text is invalid.
                        if(userSaysRevert()) { //reverted
                            fTextField.postActionEvent(); //inform the editor
                        }
                        } else try {              //The text is valid,
                            fTextField.commitEdit();     //so use it.
                            fTextField.postActionEvent(); //stop editing
                            } catch (java.text.ParseException exc) { }
                        }
                });
            }

        public Object getCellEditorValue() {
            JFormattedTextField ftf = (JFormattedTextField)getComponent();
            Object o = ftf.getValue();
            if(o==null)
                return null;
            if (o instanceof Integer) {
                return o;
            } else if (o instanceof Number) {
                return new Integer(((Number)o).intValue());
            } else {
                if (DEBUG) {
                    System.out.println("getCellEditorValue: o isn't a Number");
                }
                try {
                    return integerFormat.parseObject(o.toString());
                } catch (ParseException exc) {
                    System.err.println("getCellEditorValue: can't parse o: " + o);
                    return null;
                }
            }
        }

        public boolean stopCellEditing() {
            JFormattedTextField ftf = (JFormattedTextField)getComponent();
            if (ftf.isEditValid()) {
                try {
                    ftf.commitEdit();
                } catch (java.text.ParseException exc) { }
            } else { //text is invalid
                if (!userSaysRevert()) { //user wants to edit
                    return false; //don't let the editor go away
                } 
             }
        return super.stopCellEditing();
        }

        protected boolean userSaysRevert() {
            fTextField.selectAll();
            Object[] options = {"Edit","Revert"};
            int answer = JOptionPane.showOptionDialog(
                SwingUtilities.getWindowAncestor(fTextField),
                "Value should be between  "
                + minimum + " and "
                + maximum + ".\n"
                + "You can edit current value "
                + "or revert last correct value.",
                "Value out of range",
                JOptionPane.YES_NO_OPTION,
                JOptionPane.ERROR_MESSAGE,
                null,
                options,
                options[1]);

            if (answer == 1) { //Revert!
                fTextField.setValue(fTextField.getValue());
                return true;
            }
        return false;
        }
    }

}

1 个答案:

答案 0 :(得分:0)

最后,我找到了必须进行更改的地方。我附上了更新的代码。

public class IntegerCellEditorFrame extends JFrame{
 private static final long serialVersionUID = 1L;
 public IntegerCellEditorFrame() {
     JTable table = new JTable(new DefaultTableModel(5,1));
     table.getColumnModel().getColumn(0).setCellEditor(new IntegerCellEditor(0,5000));
     setTitle("Test IntegerCellEditor");
     setMinimumSize(new Dimension(300,200));
     setDefaultCloseOperation(EXIT_ON_CLOSE);
     add(table);

 }

 public static void main(String[] args) {
     EventQueue.invokeLater(() -> {
             IntegerCellEditorFrame frame = new IntegerCellEditorFrame();
             frame.setVisible(true);
     });
 }


    class IntegerCellEditor extends DefaultCellEditor{
        private static final long serialVersionUID = 1L;

        JFormattedTextField fTextField;
        NumberFormat integerFormat;
        private Integer minimum, maximum;
        private boolean DEBUG = false;

        IntegerCellEditor(int min, int max) {
            super(new JFormattedTextField());
            fTextField = (JFormattedTextField)getComponent();
            minimum = new Integer(min);
            maximum = new Integer(max);

            //Set up the editor for the integer cells.
            integerFormat = NumberFormat.getIntegerInstance();
            NumberFormatter intFormatter = new NumberFormatter(integerFormat);
            intFormatter.setFormat(integerFormat);
            intFormatter.setMinimum(minimum);
            intFormatter.setMaximum(maximum);

            fTextField.setFormatterFactory(new DefaultFormatterFactory(intFormatter));
            fTextField.setValue(minimum);
            fTextField.setFocusLostBehavior(JFormattedTextField.PERSIST);

            fTextField.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),"check");
            fTextField.getActionMap().put("check", new AbstractAction() {
                private static final long serialVersionUID = 1L;
                public void actionPerformed(ActionEvent e) {
                    if(!fTextField.isEditValid()) { //The text is invalid.
                        if(fTextField.getText().isEmpty()) {
                            fTextField.setValue(null);
                             fTextField.postActionEvent();
                            }    else if(userSaysRevert()) { //reverted
                                    fTextField.postActionEvent(); //inform the editor
                                }
                        } else try {              //The text is valid,
                            fTextField.commitEdit();     //so use it.
                            fTextField.postActionEvent(); //stop editing
                          } catch (java.text.ParseException exc) { }
                        }
                });
            }

        public Object getCellEditorValue() {
            JFormattedTextField ftf = (JFormattedTextField)getComponent();
            Object o = ftf.getValue();
            if(o==null)
                return null;
            if (o instanceof Integer) {
                return o;
            } else if (o instanceof Number) {
                return new Integer(((Number)o).intValue());
            } else {
                if (DEBUG) {
                    System.out.println("getCellEditorValue: o isn't a Number");
                }
                try {
                    return integerFormat.parseObject(o.toString());
                } catch (ParseException exc) {
                    System.err.println("getCellEditorValue: can't parse o: " + o);
                    return null;
                }
            }
        }

        public boolean stopCellEditing() {
            JFormattedTextField ftf = (JFormattedTextField)getComponent();
            if (ftf.isEditValid()) {
                try {
                    ftf.commitEdit();
                } catch (java.text.ParseException exc) { }
            } else { //text is invalid
                if (!userSaysRevert()) { //user wants to edit
                    return false; //don't let the editor go away
                } 
             }
        return super.stopCellEditing();
        }

        protected boolean userSaysRevert() {
            fTextField.selectAll();
            Object[] options = {"Edit","Revert"};
            int answer = JOptionPane.showOptionDialog(
                SwingUtilities.getWindowAncestor(fTextField),
                "Value should be between  "
                + minimum + " and "
                + maximum + ".\n"
                + "You can edit current value "
                + "or revet last correct value.",
                "Value out of range",
                JOptionPane.YES_NO_OPTION,
                JOptionPane.ERROR_MESSAGE,
                null,
                options,
                options[1]);

            if (answer == 1) { //Revert!
                fTextField.setValue(fTextField.getValue());
                return true;
            }
        return false;
        }
    }

}