【问题标题】:How to detect if the user changed JDateChooser date and not anything else setting the date property?如何检测用户是否更改了 JDateChooser 日期而不是设置日期属性的任何其他内容?
【发布时间】:2012-10-01 22:19:42
【问题描述】:

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

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

解决方法:我找到了一个名为 dateSelected 的受保护 JDateChooser 属性,这正是我所需要的(afaics 没有 getter)所以可能我必须创建自己的扩展 JDateChooser 类并为这个属性做一个吸气剂。这里的问题是我想让这个自定义版本可以从 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());
    }
}

【问题讨论】:

  • 另见Q&A
  • 非常感谢!!我花了几个小时在谷歌上搜索试图让它与动作监听器一起工作。您的代码确实有效。再次感谢!

标签: java swing netbeans jdatechooser


【解决方案1】:

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

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

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) {
            }
        }
    }
});

【讨论】:

    【解决方案2】:

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

    我的方法是在日期选择器中获取 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())+"!");
        });
    

    【讨论】:

      【解决方案3】:

      我正在使用 ActionListener

      fr.getFirstDate().getCalendarButton().addActionListener(new ActionListener() {
              @Override
              public void actionPerformed(ActionEvent e) {
                  fr.getSeconDate().setEnabled(true);
              }
          });
      

      【讨论】:

      • 您能补充更多信息吗?目前尚不清楚这如何回答这个问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-02
      • 1970-01-01
      • 1970-01-01
      • 2021-04-08
      • 2015-12-19
      • 1970-01-01
      相关资源
      最近更新 更多