适用于日期的JTable自定义单元格编辑器(HH:mm格式)

时间:2018-03-13 14:39:14

标签: java swing validation input jtable

我正在尝试为jtable创建输入验证程序(格式HH:mm)。我尝试使用KeyListeners和TableModelListener,最后决定最佳解决方案是自定义单元格编辑器。

到目前为止,这是我的代码:

public class DateEditor extends DefaultCellEditor {
    private JFormattedTextField textField;
    private static final DateFormat TIME_FORMAT = new SimpleDateFormat("HH:mm");


public DateEditor() {
    super( new JFormattedTextField() );
    textField = (JFormattedTextField) getComponent();


    textField.setFormatterFactory( new DefaultFormatterFactory( new DateFormatter(TIME_FORMAT) ) );
    textField.setFocusLostBehavior( JFormattedTextField.PERSIST );

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

    public Component getTableCellEditorComponent( JTable table,
                                              Object value, boolean isSelected,
                                              int row, int column ) {
    JFormattedTextField ftf = (JFormattedTextField) super.getTableCellEditorComponent( table, value, isSelected, row, column );
    ftf.setValue( value );
    return ftf;
}

public Object getCellEditorValue() {
    JFormattedTextField ftf = (JFormattedTextField) getComponent();
    Object o = ftf.getValue();
    System.out.println( "trying to parse date: " + o.getClass() );


    if ( o instanceof Date ) {


        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm");
        System.out.println("Datum: " + simpleDateFormat.format(o));

        return simpleDateFormat.format(o);
    }
    else if ( o instanceof String ) {
        try {
            return TIME_FORMAT.parse( o.toString() );
        }
        catch ( ParseException e ) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            return new Date();
        }
    }
    else {
        new RuntimeException( "What type: " + o.getClass() ).printStackTrace();
        return new Date();
    }
}

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() {
    Toolkit.getDefaultToolkit().beep();
    textField.selectAll();
    Object[] options = {"Ändern",
    "Abbrechen"};
    int answer = JOptionPane.showOptionDialog(
            SwingUtilities.getWindowAncestor( textField ),
            "Die Zeit muss im Format hh:mm eingegeben werden",
            "Falsches Eingabeformat",
            JOptionPane.YES_NO_OPTION,
            JOptionPane.ERROR_MESSAGE,
            null,
            options,
            options[1] );

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

如果输入为157:30 ftf.isEditValid()显然为真,编辑后的值为13:30。但它应该是假的,因为157:30不是HH的有效时间:mm。下次我点击同一个单元格时会抛出以下错误:

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: Cannot format given Object as a Date
at java.base/java.text.DateFormat.format(Unknown Source)
at java.base/java.text.Format.format(Unknown Source)
at java.desktop/javax.swing.text.InternationalFormatter.valueToString(Unknown Source)
at java.desktop/javax.swing.JFormattedTextField$AbstractFormatter.install(Unknown Source)
at java.desktop/javax.swing.text.DefaultFormatter.install(Unknown Source)
at java.desktop/javax.swing.text.InternationalFormatter.install(Unknown Source)
at java.desktop/javax.swing.JFormattedTextField.setFormatter(Unknown Source)
at java.desktop/javax.swing.JFormattedTextField.setValue(Unknown Source)
at java.desktop/javax.swing.JFormattedTextField.setValue(Unknown Source)
at DateEditor.getTableCellEditorComponent(DateEditor.java:57)
...
Code-Line 57: ftf.setValue( value );

我需要在代码中更改哪些内容才能进行正确验证?

0 个答案:

没有答案