2

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

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

4

2 回答 2

2

显然它在以后的版本中被删除了,并且 API 从未改变过。

你是对的,我注意到API已经过时了,因为它来自 1.2.1 版本,而JCalendar的最新版本是 1.4 我猜他们没有时间更新 API 的在线版本,但是 javadoc 与库已更新。问题是getSpinner()不再可用,因此我之前的建议无法实现。

无论如何,我决定自己尝试DateCellEditor使用JDateChooser,并且我没有遇到太多麻烦来使它工作,除非我遇到了与您开始输入单元格时相同的行为。似乎焦点已转移到JDateChooser顶级组件(如您所说,它可能是 a JPanel)。所以我利用AncestorListener API 将焦点转移到日期编辑器。@camickr在这篇文章中很好地解释了这种方法。

这是我所做的:

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. 使用AncestorListenerAPI。

这是完整的单元格编辑器实现:

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;
    }
}
于 2013-11-20T19:14:37.103 回答
0
datepicker.getEditor().setEditable(true);
于 2014-05-15T11:05:22.417 回答