3

我使用JDateChooser编辑表单中的日期。

简短版:我需要区分JDateChooser 上的用户日期编辑编程属性更改。

解决方法:我找到了一个名为dateSelected的受保护 JDateChooser 属性,这正是我需要的(afaics 没有 getter),所以我可能必须创建自己的扩展 JDateChooser 类并为此属性创建一个 getter。这里的问题是我想让这个自定义版本可以从 Netbeans Palette 中拖动,而我的自定义 JDateChooser 不会。

长版: 首先我从数据库中获取日期,然后使用 JDateChooser 的 setDate() 方法在 GUI 中设置日期。当用户使用选择器选择新日期时,我想编辑数据库的日期。为此,我在 JDateChooser 对象上侦听 PropertyChange 事件(寻找“日期”更改)。在数据库中设置新日期后,我想刷新数据(我从数据库中获取整个记录)并从数据库中设置日期(如果有任何错误,它会被设置回数据库中的任何内容在这一刻)。

问题是,当我从数据库设置日期时,当用户更改日期时会触发相同的事件,然后我的“刷新”机制更新 JDateChooser 字段并且我得到无限循环。

我现有的(简化的)代码(netbeans):

private void dataStartuChooserPropertyChange(java.beans.PropertyChangeEvent evt) {
    if ("date".equals(evt.getPropertyName())) {
        JDateChooser wybieraczDat = (JDateChooser) evt.getSource();
        updateDatabaseField(wybieraczDat.getDate());
    }
}
4

3 回答 3

0

我会在这里回复自己,因为我犯了一种疯狂的做法(这可能毫无价值,但对我的需要来说很好)。我不会创建一个完整的工作示例,因为我没有时间。还有一些人可能会受益。

要检查日期是由用户选择还是在JDateChooserPropertyChangeEvent中以编程方式设置,我检查了名为. 在我做了任何需要的事情(修改数据库)之后,我将此字段设置回,因为否则即使日期再次以编程方式更改,它也会保留。示例(未优化,丑陋,仅用于演示我所做的)代码如下。JDateChooserdateSelectedfalsetrue

JDateChooser aDateChooserInstance = new JDateChooser();

// Listen for property changes
aDateChooserInstance.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
    public void propertyChange(java.beans.PropertyChangeEvent evt) {
        // If the 'date' property was changed...
        if ("date".equals(evt.getPropertyName())) {
            JDateChooser aDateChooser = (JDateChooser) evt.getSource();
            boolean isDateSelectedByUser = false;
            // Get the otherwise unaccessible JDateChooser's 'dateSelected' field.
            try {
                // Get the desired field using reflection
                Field dateSelectedField = JDateChooser.class.getDeclaredField("dateSelected");
                // This line makes the value accesible (can be read and/or modified)
                dateSelectedField.setAccessible(true);
                isDateSelectedByUser = dateSelectedField.getBoolean(aDateChooser);
            } catch (Exception ignoreOrNot) {
            }

            // Do some important stuff depending on wether value was changed by user
            if (isDateSelectedByUser) {
                importantStuff();
            }

            // Reset the value to false
            try {
                Field dateSelectedField = JDateChooser.class.getDeclaredField("dateSelected");
                dateSelectedField.setAccessible(true);
                isDateSelectedByUser = dateSelectedField.setBoolean(aDateChooser, false);
            } catch (Exception ignoreOrNot) {
            }
        }
    }
});
于 2012-11-07T02:46:23.533 回答
0

我看到这个问题已经得到了很长的回答,但我也想把我的方法留给研究。

我的方法是在日期选择器中获取 JTextField,然后获取它的文档,在其中连接一个事件,检查日期是否更改并且有效,然后调用用户指定的 lambda 表达式。

lambda的接口:

public interface IDateChooserChangedEvent {
    public void run(DocumentEvent evt);
}

注册事件的函数。

public static void addDateChangedEvent(JDateChooser dt, IDateChooserChangedEvent evt) {
    ((JTextField)dt.getDateEditor()
            .getUiComponent())
                .getDocument()
                    .addDocumentListener(new DocumentListener() {
                        Date lastDate = dt.getDate();
                        @Override
                        public void insertUpdate(DocumentEvent e) {
                            if(dt.getDate != null && !dt.getDate().equals(lastDate)) {
                                SwingUtilities.invokeLater(()->
                                    evt.run(e));
                                lastDate = dt.getDate();
                            }
                        }
                        @Override
                        public void removeUpdate(DocumentEvent e) {
                        }
                        @Override
                        public void changedUpdate(DocumentEvent e) {
                        }
                    });

以及事件的 Lambda 样式注册。

addDateChangedEvent(myDate, (evt) -> {
        System.out.println("Date changed and is now "+new SimpleDateFormat("dd/MM/yyy").format(myDate.getDate())+"!");
    });
于 2015-03-27T14:57:53.597 回答
0

我正在使用 ActionListener

fr.getFirstDate().getCalendarButton().addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            fr.getSeconDate().setEnabled(true);
        }
    });
于 2016-03-29T17:14:38.973 回答