How to best practice update a label in swing vs javafx?
Hello!I'm playing around with swing and javafx and updating a label from a runnable. It looks like you must do it in some other way with JavaFx since I get:
Not on FX application thread; currentThread = Thread-3
I compare these two examples.
First take a look at this swing example.
(It works but perhaps the approach might be wrong from the beginning?)
SWING:
package animationtest;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class SwingTest extends JFrame
{
JLabel label = new JLabel("Hubba");
JButton button = new JButton("Click me");
JPanel panel = new JPanel();
MySwingRunnable myRunnable = new MySwingRunnable(label);
final Thread taskThread = new Thread(myRunnable);
public SwingTest()
{
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
taskThread.start();
}
}
);
panel.add(label);
panel.add(button);
getContentPane().add(panel);
}
public static void main(String[] args) {
final SwingTest swingTest = new SwingTest();
javax.swing.SwingUtilities.invokeLater( new Runnable()
{
public void run()
{
swingTest.setTitle("SwingTest");
swingTest.pack();
swingTest.validate();
swingTest.setVisible(true);
}
});
}
}
package animationtest;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class SwingTest extends JFrame
{
JLabel label = new JLabel("Hubba");
JButton button = new JButton("Click me");
JPanel panel = new JPanel();
MySwingRunnable myRunnable = new MySwingRunnable(label);
final Thread taskThread = new Thread(myRunnable);
public SwingTest()
{
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
taskThread.start();
}
}
);
panel.add(label);
panel.add(button);
getContentPane().add(panel);
}
public static void main(String[] args) {
final SwingTest swingTest = new SwingTest();
javax.swing.SwingUtilities.invokeLater( new Runnable()
{
public void run()
{
swingTest.setTitle("SwingTest");
swingTest.pack();
swingTest.validate();
swingTest.setVisible(true);
}
});
}
}
JAVAFX
package animationtest;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.stage.Stage;
public class JavafxTest extends Application
{
Label label = new Label("Hubba");
Button button = new Button("Click me");
MyJavafxRunnable myRunnable = new MyJavafxRunnable(label);
final Thread taskThread = new Thread(myRunnable);
public void start(final Stage primaryStage)
{
button.setOnAction(new EventHandler<ActionEvent>()
{
@Override
public void handle(ActionEvent event)
{
taskThread.start();
}
}
);
label.setLayoutX(70);
label.setLayoutY(150);
button.setLayoutX(100);
button.setLayoutY(100);
button.setText("Click me");
final Group root = new Group();
root.getChildren().add(button);
root.getChildren().add(label);
Platform.runLater(new Runnable() {
@Override
public void run() {
primaryStage.setTitle("Javafx test");
primaryStage.setScene(new Scene(root, 300, 250));
primaryStage.show();
}
});
}
public static void main(final String[] args) {
launch(args);
}
}
package animationtest;
import javafx.scene.control.Label;
public class MyJavafxRunnable implements Runnable{
Label label;
public MyJavafxRunnable(Label label)
{
this.label = label;
}
@Override
public void run() {
for(int i = 0; i < 1000000; i++)
{
label.setText( "no. " + i);
//label.invalidate();
}
}
}
If I do it right in swing I guess it is supposed to be done in some other way with javafx?
Best regards
Fredrik