Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

date/time not getting updated in WebDateField #579

Closed
mokun opened this issue Nov 6, 2019 · 6 comments
Closed

date/time not getting updated in WebDateField #579

mokun opened this issue Nov 6, 2019 · 6 comments

Comments

@mokun
Copy link

mokun commented Nov 6, 2019

I just found out an issue with WebDataField.

See also #257

I can set the date/time to a value INITIALLY as follows :

// Global data member
Date date = new Date(earthClock.getInstant().toEpochMilli());
// Within a method
WebDateField dateField = new WebDateField (date);
DateFormat d = new SimpleDateFormat ("yyyy-MMM-dd  HH:mm a '['z']'", LanguageManager.getLocale ());
dateField.setDateFormat(d);

However, in my app's game loop, I need to constantly update the date/timestamp.

So if I do the following once per frame, it won't work :

date = new Date(earthClock.getInstant().toEpochMilli());
dateField.setDate(date)

OR:

date.setTime(earthClock.getInstant().toEpochMilli());
// dateField.setDate(date);

The only way it works is keeping create a brand new Date each time as follows:

dateField.setDate(new Date(earthClock.getInstant().toEpochMilli()));

@mgarin mgarin self-assigned this Nov 6, 2019
@mgarin mgarin added the bug label Nov 6, 2019
@mgarin mgarin added this to the v1.2.11 milestone Nov 6, 2019
@mgarin
Copy link
Owner

mgarin commented Nov 6, 2019

Thanks for the information!
I'll check that tomorrow and add a fix.

@mgarin
Copy link
Owner

mgarin commented Nov 8, 2019

So if I do the following once per frame, it won't work :

date = new Date(earthClock.getInstant().toEpochMilli());
dateField.setDate(date)

This most certainly works for me, can you provide a small example where it doesn't for you?
Which exact WebLaF version it doesn't work on?

OR:

date.setTime(earthClock.getInstant().toEpochMilli());
// dateField.setDate(date);

This is actually a bad idea, WebDateField cannot possibly know when you change time within the Date object because unfortunately there are no ways to listen to it's changes, so WebDateField obviously won't update displayed date like that.

I personally recommend to never ever reuse Date object and always create a new one, because even if you will change it's time and provide it again into WebDateField - it won't update because of how parameters comparison works. It's "cheap" to create a new one anyway, so there is no reason not to.

@mokun
Copy link
Author

mokun commented Nov 9, 2019

I'm on v1.2.10.

I personally recommend to never ever reuse Date object and always create a new one, because even if you will change it's time and provide it again into WebDateField it won't update because of how parameters comparison works. It's "cheap" to create a new one anyway, so there is no reason not to.

Ok I surely hope there's a way to listen in the changes in the timestamp.

One big problem I found in my app is that if I click on the calendar button on the right of the textfield, it won't open the calendar. OR should I say as soon as it's being opened, since a new Date object is being provided to increment/update the time, the calendar will collapse.

So updating the Date object frequently will totally defeat the purpose of having the WeDateField in that users can see the visual calendar :(

Is there a workaround to keep the calendar object in the open state, while the Date is being updated ?

EDIT:
May be there is a way to temporarily put ON-HOLD the firing of the UI refresh on the calendar component until the mouse cursor exit the calendar or when the calendar is no longer in the popped-out state ?!

mgarin added a commit that referenced this issue Nov 11, 2019
- WebDateField.java - Now creates a copy of provided `Date` and returns a copy of selected day when requested to avoid it's modification
@mgarin
Copy link
Owner

mgarin commented Nov 11, 2019

Ok I surely hope there's a way to listen in the changes in the timestamp.

Not sure what you meant by that.

If you set a new Date instance into the field - it will be recognized, but if you simply change time in Date that was set into it before OR set the same instance of Date you set into the field before - it won't be recognized.

Unfortunately nothing can be done about the first case because Date object doesn't notify anyone about it's time change, you can see that in setTime ( long ) method:

    /**
     * Sets this <code>Date</code> object to represent a point in time that is 
     * <code>time</code> milliseconds after January 1, 1970 00:00:00 GMT. 
     *
     * @param   time   the number of milliseconds.
     */
    public void setTime(long time) {
	fastTime = time;
	cdate = null;
    }

For the second case I've added a small fix that will simply use a new Date instance and return copy of selected Date instance to avoid it being modified from outside.

@mgarin
Copy link
Owner

mgarin commented Nov 12, 2019

@mokun

One big problem I found in my app is that if I click on the calendar button on the right of the textfield, it won't open the calendar. OR should I say as soon as it's being opened, since a new Date object is being provided to increment/update the time, the calendar will collapse.

Is there a workaround to keep the calendar object in the open state, while the Date is being updated ?

Could you provide a small code example of this use-case?

mgarin added a commit that referenced this issue Nov 25, 2019
- WebDateFieldUI.java - Calendar popup will not be closed anymore when date or date format is changed while it's open
@mgarin
Copy link
Owner

mgarin commented Nov 25, 2019

Date field popup will not close anymore when date or date format is changed while it's open. Calendar will properly update to newly provided date as well.

Here is the example I used for testing this problem:

public final class DateCalendarPopupTest
{
    public static void main ( final String[] args )
    {
        SwingTest.run ( new Runnable ()
        {
            @Override
            public void run ()
            {
                final WebDateField dateField = new WebDateField ( new Date () );

                TestFrame.show ( dateField );

                WebTimer.repeat ( 1000, new ActionListener ()
                {
                    @Override
                    public void actionPerformed ( final ActionEvent e )
                    {
                        dateField.setDate ( new Date ( dateField.getDate ().getTime () + 24 * 60 * 60 * 1000 ) );
                    }
                } );
            }
        } );
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants