3

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());
    }
}
user1713059
  • 1,425
  • 2
  • 17
  • 34
  • See also this [Q&A](http://stackoverflow.com/q/2633323/230513). – trashgod Oct 02 '12 at 03:42
  • THANK YOU VERY MUCH!! I spent hours googling trying to get it to work with action listener. Your code does worked. THANKS AGAIN!! – sg552 Nov 03 '15 at 19:25

3 Answers3

0

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) {
            }
        }
    }
});
user1713059
  • 1,425
  • 2
  • 17
  • 34
0

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.

The interface for 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.

addDateChangedEvent(myDate, (evt) -> {
        System.out.println("Date changed and is now "+new SimpleDateFormat("dd/MM/yyy").format(myDate.getDate())+"!");
    });
Felype
  • 3,087
  • 2
  • 25
  • 36
0

iam using ActionListener

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