如何使用键盘编辑JDateChooser表格单元格

时间:2013-11-19 21:43:35

标签: java swing jtable tablecelleditor jdatechooser

在我的Java面板中,我有一个JTable,其中两列使用JDateChooser对象,来自包com.toedter.calendar,通过自定义单元格编辑器。与使用文本框或其他简单组件的单元格不同,您可以在不必事先单击单元格的情况下键入该单元格,此功能在日期选择器单元格中不存在。就我目前的理解而言,这是因为我的自定义编辑器将JDateChooser对象作为组件返回(通过getTableCellEditorComponent方法)。由于JDateChooser的父类是JPanelaccording to the API),因此它正在尝试编辑,当然,您无法在JPanel中输入文字。有没有办法检测用户何时选中日期选择器单元并尝试在其中键入日期?

P.S。我确实通过请求关注日期选择器的文本字段来管理一种变通方法,但问题是你键入的第一个键没有出现在单元格中;它只是开始编辑单元格。如果可能的话,我希望它表现得如此,以便您可以切换到单元格,例如,键入“1”,并在其中显示“1”,就像使用常规文本字段单元格一样。

2 个答案:

答案 0 :(得分:2)

  

显然它已在更高版本中删除,API从未被删除   改变。

你是对的,我注意到API已经过时,因为它来自1.2.1版本,JCalendar的最新版本是1.4我猜他们没有时间更新在线API的版本,但随库更新的javadoc已更新。事情getSpinner()不再可用,因此我的前任suggestion无法访问。

无论如何,我决定自己尝试DateCellEditor使用JDateChooser,除了我遇到与你时相同的行为,我没有太多麻烦。开始输入单元格。似乎焦点转移到JDateChooser顶级组件(正如你所说它可能是JPanel)。所以我利用AncestorListener API将焦点转移到了日期编辑器。 @camickr在this post中详细解释了这种方法。

这就是我所做的:

public class DateCellEditor extends AbstractCellEditor implements TableCellEditor {

    JDateChooser editor;

    public DateCellEditor() {
        editor = new JDateChooser();
        editor.setLocale(Locale.ENGLISH);
        editor.setDateFormatString("MM/dd/yyyy");
        editor.setFocusable(false); // Key #1

        JComponent editorComponent = (JComponent)editor.getDateEditor();
        editorComponent.addAncestorListener(new AncestorListener() { // Key #2

            @Override
            public void ancestorAdded(AncestorEvent event) {
                ((JComponent)editor.getDateEditor()).requestFocusInWindow();
            }

            @Override
            public void ancestorRemoved(AncestorEvent event) {}

            @Override
            public void ancestorMoved(AncestorEvent event) {}

        });
    }

    ....
}

这里有两个关键因素:

  1. 使editor无法集中注意力。这样您就可以避免将焦点自动转移到作为其一部分的顶级容器中。
  2. 使用AncestorListener API。
  3. 以下是完整的单元格编辑器实现:

    import com.toedter.calendar.JDateChooser;
    import java.awt.Component;
    import java.awt.event.MouseEvent;
    import java.util.EventObject;
    import java.util.Locale;
    import javax.swing.AbstractCellEditor;
    import javax.swing.JComponent;
    import javax.swing.JTable;
    import javax.swing.event.AncestorEvent;
    import javax.swing.event.AncestorListener;
    import javax.swing.table.TableCellEditor;
    
    public class DateCellEditor extends AbstractCellEditor implements TableCellEditor {
    
        JDateChooser editor;
        int clickCountToStart = 2;
    
        public DateCellEditor() {
            editor = new JDateChooser();
            editor.setLocale(Locale.ENGLISH);
            editor.setDateFormatString("MM/dd/yyyy");
            editor.setFocusable(false);
    
            JComponent editorComponent = (JComponent)editor.getDateEditor();
            editorComponent.addAncestorListener(new AncestorListener() {
    
                @Override
                public void ancestorAdded(AncestorEvent event) {
                    ((JComponent)editor.getDateEditor()).requestFocusInWindow();
                }
    
                @Override
                public void ancestorRemoved(AncestorEvent event) {}
    
                @Override
                public void ancestorMoved(AncestorEvent event) {}
    
            });
        }
    
        @Override
        public Object getCellEditorValue() {
            return editor.getDate();
        }    
    
        @Override
        public boolean isCellEditable(EventObject anEvent) {
            if (anEvent instanceof MouseEvent) {
                return ((MouseEvent)anEvent).getClickCount() >= clickCountToStart;
            }
            return true;
        }
    
        @Override
        public boolean shouldSelectCell(EventObject anEvent) {
            return true;
        }
    
        @Override
        public boolean stopCellEditing() {
            fireEditingStopped();
            return true;
        }
    
        @Override
        public void cancelCellEditing() {
            fireEditingCanceled();
        }
    
    
    
    
        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
            if(value instanceof java.util.Date){
                editor.setDate((java.util.Date)value);
                table.setRowHeight((int)editor.getPreferredSize().getHeight());
                //This last one is optional. It fits the row height to the JDateChooser preferred height.
            }
            return editor;
        }
    }
    

答案 1 :(得分:0)

datepicker.getEditor().setEditable(true);