java 如何检测用户是否更改了 JDateChooser 日期而不是其他任何设置日期属性的内容?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12681933/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to detect if the user changed JDateChooser date and not anything else setting the date property?
提问by user1713059
I use JDateChooserto edit dates in my form.
我使用JDateChooser来编辑表单中的日期。
Short version: I need to distinguish between user date editand programmatical property changeon a JDateChooser.
简短版本:我需要区分JDateChooser 上的用户日期编辑和编程属性更改。
Workaround: I've found a protected JDateChooser property named dateSelectedwhich is exactly what I need (afaics there is no getter) so probably I'd have to make my own extended JDateChooser class and make a getter for this property. The problem here is that I want to have this custom version to be draggable from the Netbeans Palette and my custom JDateChooser won't be.
解决方法:我找到了一个名为dateSelected的受保护的 JDateChooser 属性,这正是我需要的(afaics 没有 getter),所以可能我必须创建自己的扩展 JDateChooser 类并为该属性创建一个 getter。这里的问题是我想让这个自定义版本可以从 Netbeans Palette 拖动,而我的自定义 JDateChooser 不会。
Long version:First I get a date from my database and I use the JDateChooser's setDate() method to set the date in the GUI. I want to edit database's date when user picks a new date with the chooser. To do that i listen for a PropertyChange event on the JDateChooser object (looking for the "date" change). After settig the new date in the database, I want to refresh the data (I get the whole record from the database) and I set the date from the database (if there was any error, it gets set back to whatever is in the database at the moment).
长版本:首先,我从我的数据库中获取一个日期,然后使用 JDateChooser 的 setDate() 方法在 GUI 中设置日期。当用户使用选择器选择新日期时,我想编辑数据库的日期。为此,我侦听 JDateChooser 对象上的 PropertyChange 事件(寻找“日期”更改)。在数据库中设置新日期后,我想刷新数据(我从数据库中获取整个记录)并从数据库中设置日期(如果有任何错误,它会被设置回数据库中的任何内容)眼下)。
The problem is that when I set the date from the database, the same event is fired whe user changes date and then my "refresh" mechanism updates the JDateChooser field and I get infinite loop.
问题是,当我从数据库中设置日期时,当用户更改日期然后我的“刷新”机制更新 JDateChooser 字段时会触发相同的事件,并且我得到无限循环。
My existing(simplified) code(netbeans):
我现有的(简化的)代码(netbeans):
private void dataStartuChooserPropertyChange(java.beans.PropertyChangeEvent evt) {
if ("date".equals(evt.getPropertyName())) {
JDateChooser wybieraczDat = (JDateChooser) evt.getSource();
updateDatabaseField(wybieraczDat.getDate());
}
}
采纳答案by user1713059
I will reply to myself here because I fould a crazy way of doing this (which potentially can be worthless, but is fine for my needs). I will not create a complete working example because I dont have the time. Still some1 may benefit.
我会在这里回复自己,因为我采用了一种疯狂的方式来做这件事(这可能毫无价值,但对我的需求来说很好)。我不会创建一个完整的工作示例,因为我没有时间。还有一些人可能会受益。
To check wether date was chosen by user or set programatically in a PropertyChangeEvent
of a JDateChooserI check a JDateChooser
's private field called dateSelected
. After I do whatever is needed (modifying database) I set this field back to false
because otherwise it would stay true
even if date was changed programatically again. Sample (unoptimized, ugly, only to demonstrate what I did) code below.
要请检查是否日期是由用户选择或在编程设定PropertyChangeEvent
一个的JDateChooser我查了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) {
}
}
}
});
回答by Felype
I see this question is long answered, but I'd like to leave my approach for research too.
我看到这个问题已经得到了很长时间的回答,但我也想离开我的研究方法。
My approach is getting the JTextField within the Date chooser, then getting its document, hooking up an event in it, checking if the date did change and is valid and then calling the user specified lambda expression.
我的方法是在日期选择器中获取 JTextField,然后获取其文档,在其中连接一个事件,检查日期是否确实更改并且有效,然后调用用户指定的 lambda 表达式。
The interface for lambda:
lambda 的接口:
public interface IDateChooserChangedEvent {
public void run(DocumentEvent evt);
}
A function to register the event.
注册事件的函数。
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) {
}
});
And a Lambda-styled registration for the event.
以及一个 Lambda 风格的事件注册。
addDateChangedEvent(myDate, (evt) -> {
System.out.println("Date changed and is now "+new SimpleDateFormat("dd/MM/yyy").format(myDate.getDate())+"!");
});
回答by Dimas Naresh
iam using ActionListener
我正在使用 ActionListener
fr.getFirstDate().getCalendarButton().addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
fr.getSeconDate().setEnabled(true);
}
});