How to detect if the user changed JDateChooser date and not anything else setting the date property?

user1713059 picture user1713059 · Oct 2, 2012 · Viewed 13k times · Source

I use JDateChooser to edit dates in my form.

Short version: I need to distinguish between user date edit and programmatical property change on a JDateChooser.

Workaround: I've found a protected JDateChooser property named dateSelected which 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.

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).

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.

My existing (simplified) code (netbeans):

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

Answer

user1713059 picture user1713059 · Nov 7, 2012

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 JDateChooser I 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.

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