Download presentation
Presentation is loading. Please wait.
Published byRandolf Sharp Modified over 8 years ago
1
Today Advanced JavaFX animation and 3D demos from Oracle. Threading. Winter 2016CMPE212 - Prof. McLeod1
2
Oracle Demos 3D Drawing and moving the camera angle: MoleculeSampleDemo. 3D Drawing and sound: XylophoneDemo Complex animation - TreeAnimationDemo Winter 2016CMPE212 - Prof. McLeod2
3
Winter 2016CMPE212 - Prof. McLeod3 Example Program Suppose that we want to have a window that: 1.Has a timer counting seconds. 2.Buttons to start and stop the timer. 3.A TextArea node to store comments, provided one at a time. 4.A Close button to close the window. –No sweat, right? See LoggerNoThreads
4
Winter 2016CMPE212 - Prof. McLeod4 So, What’s the Problem? The program cannot move beyond the timer loop. Events such as paint() calls will not get processed – they just pile up! What’s the solution?
5
Winter 2016CMPE212 - Prof. McLeod5 Multi-Threading In a JavaFX program Application runs on its own thread. Our timing loop is still on the Application thread and is blocking other thread processes. The easiest way is to use the existing animation thread that is already available through the use of the Timeline object. See LoggerTimeline
6
Timeline From yesterday’s lecture: timeline = new Timeline(new KeyFrame(Duration.ZERO, actionEvent -> incrementClock()), new KeyFrame(Duration.millis(1000))); timeline.setCycleCount(Timeline.INDEFINITE); Winter 2016CMPE212 - Prof. McLeod6
7
Timeline, Cont. Use timeline.playFromStart() to start the timer and timeline.stop() to halt it. Invoking Platform.exit() will also stop all Application threads when you exit the program. Winter 2016CMPE212 - Prof. McLeod7
8
Winter 2016CMPE212 - Prof. McLeod8 Multi-Threading, Cont. Suppose you wish to create your own thread instead of piggybacking on an existing thread? Use classes from the javafx.concurrent package. These include Service and Task. Threads based on the Thread class cannot work with the Application thread.
9
Task Task is designed to work with JavaFX applications. It cannot directly access scenegraph nodes on the Application thread, because Node objects are not “thread safe”. It is a one-shot deal. Once the task is finished, you cannot re-start it. It is generic! You must override the T call() method. Winter 2016CMPE212 - Prof. McLeod9
10
Task, Cont. call() contains the process that will run on a separate thread. call() returns a type T, but if it does not return anything then you can return null and use “Void” for the type. Winter 2016CMPE212 - Prof. McLeod10
11
Task, Cont. The class uses “update” methods to update node contents: updateMessage(String message) updateProgress(…) updateTitle(…) updateValue(T value) These are to be bound to specific node properties: Winter 2016CMPE212 - Prof. McLeod11
12
Task, Cont. Binding, example: lblTime.textProperty().bind(myService.messageProperty()); “myService” is a Service object, but use the same syntax to bind a Task property to a node property. Inside the Task call method: updateMessage("" + timeCounter); Winter 2016CMPE212 - Prof. McLeod12
13
Task, Cont. These update calls are immediately “coalesced” on the Application thread. They may not run at once, but will run in the order in which they have been added to the main thread. One way to update multiple nodes is to add a change listener to the bound node which updates the other nodes of interest. Another is to use an AnimationTimer to trigger updates when a frame is drawn. Winter 2016CMPE212 - Prof. McLeod13
14
Task, Cont. If you need to do more to the scenegraph that just update the property of a single node, then consider using: Platform.runLater(Runnable r) The Runnable is a process (which can be a Task, for example) which will be piled onto the Application thread. Winter 2016CMPE212 - Prof. McLeod14
15
Service A Task cannot be re-started. Use a Service instead. Service creates and manages a Task in a way that is compatible with the Application thread. Generic! Override the method: Task createTask() This method creates the Task object for the Service. Winter 2016CMPE212 - Prof. McLeod15
16
Service, Cont. Has many useful methods to monitor and manipulate the task, including: –.cancel()// Stops the task –.cancelled()// Returns true if the task is cancelled –.isRunning()// Returns true if the task is running –.reset()// Resets the service –.restart()// Cancels and re-starts the task –.start()// Starts the task See LoggerThreaded Winter 2016CMPE212 - Prof. McLeod16
17
Winter 2016CMPE212 - Prof. McLeod17 Daemon vs. User Threads A Daemon thread is a system thread usually created by the JVM, but you can invoke setDaemon(true) to make your own thread a Daemon thread instead of a default User thread: Thread th = new Thread(task); th.setDaemon(true); This must be done on the Application thread.
18
Winter 2016CMPE212 - Prof. McLeod18 Daemon vs. User Threads A process is terminated when all user threads have stopped. Then all Daemon threads will be stopped by the JVM. For example, the garbage collector is a Daemon thread. You can use this to have a process that can prevent closing the window even when all other normal threads have halted.
19
Winter 2016CMPE212 - Prof. McLeod19 The Thread Class, Cont. Threads have a priority. This helps the processor decided which thread gets a larger slice of processor time. Threads with a lower priority can be delayed by CPU-intensive threads with a higher priority. Use getPriority() and setPriority(int) methods. Priorities lie between 1 and 10, with 5 being the default. (Use Thread.MAX_PRIORITY, Thread.MIN_PRIORITY and Thread.NORM_PRIORITY.)
20
Winter 2016CMPE212 - Prof. McLeod20 The Thread Class, Cont. Other methods are listed in the API. In particular, sleep(long sleeptime) can put the current thread to sleep for a specified number of milliseconds. This gives other threads a chance to do something. You should always place a sleep() command inside any loops in your thread. sleep() can throw the InterruptedException too. Or you can simply invoke the yield() method to pause the current thread and allow other threads to execute.
21
Multi-Threading, Cont. The thread in a task can be halted (externally!) in two ways: A cancel has been issued. An InterruptedException has been thrown. Inside a loop in your call method, you need to invoke.isCancelled() to see if you need to stop the loop. Put any blocking calls like Thread.sleep() inside a try catch to catch the InterruptedException and use the catch to stop the loop. Winter 2016CMPE212 - Prof. McLeod21
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.