我使用JDateChooser编辑表单中的日期。
短版本:我需要在JDateChooser上区分用户日期编辑和编程属性更改。
解决方法:我发现了一个名为dateSelected的受保护的JDateChooser属性,这正是我所需要的(因为没有getter),所以我可能必须创建自己的扩展JDateChoose类,并为此属性创建一个getter。这里的问题是,我想让这个自定义版本可以从Netbeans Palette中拖动,而我的自定义JDateChooser不会是。
长版本:首先,我从数据库中获取日期,然后使用JDateChooser的setDate()方法在GUI中设置日期。当用户用选择器选择新日期时,我想编辑数据库的日期。为此,我监听JDateChooser对象上的PropertyChange事件(查找"日期"更改)。在数据库中设置新日期后,我想刷新数据(我从数据库中获取整个记录),并从数据库中设置日期(如果有任何错误,它会被设置回数据库中的任何内容)。
问题是,当我从数据库中设置日期时,当用户更改日期时,会触发相同的事件,然后我的"刷新"机制更新JDateChooser字段,我得到无限循环。
我现有的(简化)代码
private void dataStartuChooserPropertyChange(java.beans.PropertyChangeEvent evt) {
if ("date".equals(evt.getPropertyName())) {
JDateChooser wybieraczDat = (JDateChooser) evt.getSource();
updateDatabaseField(wybieraczDat.getDate());
}
}
我会在这里回复自己,因为我有一种疯狂的方式来做这件事(这可能毫无价值,但适合我的需求)。我不会创建一个完整的工作示例,因为我没有时间。还有一些人可能受益。
为了检查日期是由用户选择的还是在JDateChooser的PropertyChangeEvent
中通过程序设置的,我检查了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) {
}
}
}
});
我知道这个问题已经得到了很长时间的回答,但我也想把我的方法也留给研究。
我的方法是在Date选择器中获取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())+"!");
});
iam使用ActionListener
fr.getFirstDate().getCalendarButton().addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
fr.getSeconDate().setEnabled(true);
}
});