Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaFX freezes when the system date/time changed to a day/time in the past

I have a strange problem. I starting my JavaFX program, that draws objects (rectangles, circles and etc.) on the screen using commands sent through a socket. When changing the system clock backwards (e.g. at 11:00 it changes at 9:00), JavaFX does not shows the result (i.e. created object) of executed commands, and the program logic in the background works and prints messages in the console for a received and executed command, but nothing is displayed on the screen. The time is changed by command:

sudo date --set 'time' && sudo hwclock --systohc

The OS is Ubuntu 16.04.4 LTS with kernel release version 3.4.39-s5p4418. This OS works on Smart4418 module.

uname -a output:

Linux 4418Module 3.4.39-s5p4418 #1 SMP PREEMPT Fri Aug 18 14:06:20 HKT 2017 armv7l armv7l armv7l GNU/Linux

Java version:

java version "1.8.0_171"
Java(TM) SE Runtime Environment (build 1.8.0_171-b11)
Java HotSpot(TM) Client VM (build 25.171-b11, mixed mode)

I use JavaFX Embedded SDK is downloaded from Gluon's website.

like image 711
Dev Avatar asked Jul 12 '18 08:07

Dev


2 Answers

Monocle.java in jfxrt.jar uses java/util/Timer.java(JDK1.8) to manage the screen.

Method "MainLoop" in TimerThread(JDK1.8) computes time of execution using the "systemtime".

If the "systemtime" goes backward, this TimerThread freezes.

I fixed it by modifying Monocle.java to call a modified Timer.java, and updating them in jfxrt.jar

like image 173
user10384350 Avatar answered Oct 10 '22 12:10

user10384350


After spending a lot of time searching solution I have found one (I had problem on Raspbian Strech/Buster on RPi3, on Windows 10 everything is working fine). I added "fake" animation to one of my component (which can be hidden) and now UI does not freeze when changing system time. It is only workaround until I find better solution.

final Rotate fakeRotate = new Rotate();
    backButton.getTransforms().add(fakeRotate);

    fakeAnimation = new Timeline(
            new KeyFrame(
                    Duration.hours(24),
                    new KeyValue(
                            fakeRotate.angleProperty(),
                            0.1,
                            Interpolator.LINEAR
                    )
            )
    );

    fakeAnimation.setCycleCount(Animation.INDEFINITE);
    fakeAnimation.play();
like image 45
user4341206 Avatar answered Oct 10 '22 12:10

user4341206