From Swing to JavaFX

Preview:

DESCRIPTION

JJUG CCC

Citation preview

From Swing To JavaFX

Java in the BoxYuichi Sakuraba

- Migration Guide to JavaFX -

Basics of JavaFX

JavaFXJavaFX

Next Generation Java GUI Library

Functionally Analogous: Swing+Java2D+α

JavaSE8 includes JavaFX3.0

public class Hello extends Application {

}

public static void main(String[] args) { launch(args); }

Start JavaFX Application Thread

@Override public void start(Stage stage) {

}

// Create Container Group container = new Group(); // Create root of Scene Graph Scene scene = new Scene(container, 100, 20); stage.setScene(scene);

// Create label and add it to Scene Graph Label label = new Label("Hello, World!"); container.getChildren().add(label); stage.show(); SceneGraph

Pitfalls

Add to Containerpane.add(comp);pane.getChildren().add(comp);

EventOnly One Event Listener: EventHandler

button.setOnAction( new EventHandler<ActionEvent>() { public void handle(ActionEvent event) { // handling event }});

BindPitfalls

Model

View

ControllerEvent

Observer Pattern

Swing

BindPitfalls

Model

View

Controller

JavaFX Bind

BindPitfalls

Model

View

Controller

JavaFX Bind

// Model objectDoubleProperty xProperty = new DoubleProperty();

Slider slider = new Slider(50, 300, 0);// Bind slider property to model objectxProperty.bind(slider.valueProperty());

Rectangle rect = new Rectangle(50, 10, 50, 30); // Bind model object to x property of rectanglerect.xProperty().bind(xProperty);

Migration Scenarios

Scenario #1 JavaFX in Swing

Scenario #2 Swing to JavaFX w/o FXML

Scenario #3 Swing to JavaFX w/ FXML

JavaFX in Swing

Embed JavaFX scene graph in Swing application

No support for embedding Swing componentsinto JavaFX applications

Use features JavaFX only has with Swing

JavaFX in Swing

Embed JavaFX scene graph in Swing application

No support for embedding Swing componentsinto JavaFX applications

Use features JavaFX only has with SwingWeb

ChartsMediaAnimation

JFXPanelJFXPanelJFXPanel is a Swing component that is compatible with JavaFX

Add scene graph into JFXPanel final JFXPanel fxPanel = new JFXPanel(); jframe.add(fxPanel);

Platform.runLater(new Runnable() { @Override public void run() { AnchorPane root = new AnchorPane(); Scene scene = new Scene(root); root.getChildren().add(new Button("JavaFX Button")); fxPanel.setScene(scene); } });

Swing EDT

JavaFX App Thread

Swing to JavaFX w/o FXML

Rewrite Swing as JavaFX

Same concept, similar usage

Same concept, different usage

New concept

Label, Button, TextField, et al.

Layout

TableView, TreeView, ListView

Swing

JavaFX

Swing

JavaFX

Same concept, similar usage : Button

JButton = new JButton(”Swing”);

button.addActionListener(new ActionListener() { @Override public void actionPerformed(new ActionEvent event) { // handling event } });

Button = new Button(”JavaFX”);

button.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { // handling event } });

Same concept, different usage

: Layout

Swing: Container+LayoutManeger

JPanel panel = new JPanel();panel.setLayout(new BorderLayout());

panel.add(comp, BorderLayout.CENTER);

JavaFX: Container includes layout

BorderPane pane = new BorderPane();

pane.setCenter(comp);

New Concept: Table

Swing: TableModelJavaFX: Bind Java Beans to Column

class Student { ...... } // Java Bean

TableView<Student> table = new TableView<>();

TableColumn col1 = new TableColumn("Name");col1.setCellValueFactory( new PropertyValueFactory<Student, String>("name"));TableColumn col2 = new TableColumn("Grad Year");col2.setCellValueFactory( new PropertyValueFactory<Student, Integer>("gradYear"));

table.setItems(students);table.getColumns().addAll(col1, col2);

class Student {..} // Student has name & gradYear props

TableView<Student> table = new TableView<>();

TableColumn col1 = new TableColumn("Name");col1.setCellValueFactory( new PropertyValueFactory<Student, String>("name"));TableColumn col2 = new TableColumn("Grad Year");col2.setCellValueFactory( new PropertyValueFactory<Student, Integer>("gradYear"));

table.setItems(students);table.getColumns().addAll(col1, col2);

Swing to JavaFX

w/ FXML

FXMLFXML

Use XML to describe GUI structureFXML describes Scene Graph

Schema-lessClass: XML ElementProperty: XML Attribute or Element

FXML read by Java application at run time

<AnchorPane prefHeight="400.0" prefWidth="600.0"> <children> <HBox alignment="CENTER" prefHeight="50.0" prefWidth="572.0" spacing="20.0"> <children> <TextField prefWidth="200.0" style="-fx-font-size: 24;" /> <Button style="-fx-font-size: 24;" text="Load" /> </children> </HBox> <WebView prefHeight="302.0" prefWidth="572.0" /> </children></AnchorPane>

<AnchorPane prefHeight="400.0" prefWidth="600.0"> <children> <HBox alignment="CENTER" prefHeight="50.0" prefWidth="572.0" spacing="20.0"> <children> <TextField prefWidth="200.0" style="-fx-font-size: 24;" /> <Button style="-fx-font-size: 24;" text="Load" /> </children> </HBox> <WebView prefHeight="302.0" prefWidth="572.0" /> </children></AnchorPane>

<AnchorPane prefHeight="400.0" prefWidth="600.0"> <children> <HBox alignment="CENTER" prefHeight="50.0" prefWidth="572.0" spacing="20.0"> <children> <TextField prefWidth="200.0" style="-fx-font-size: 24;" /> <Button style="-fx-font-size: 24;" text="Load" /> </children> </HBox> <WebView prefHeight="302.0" prefWidth="572.0" /> </children></AnchorPane>

<AnchorPane prefHeight="400.0" prefWidth="600.0"> <children> <HBox alignment="CENTER" prefHeight="50.0" prefWidth="572.0" spacing="20.0"> <children> <TextField prefWidth="200.0" style="-fx-font-size: 24;" /> <Button style="-fx-font-size: 24;" text="Load" /> </children> </HBox> <WebView prefHeight="302.0" prefWidth="572.0" /> </children></AnchorPane>

AnchorPane pane = FXMLLoader.load( this.getClass().getResource("browser.fxml"));

ex. browser.fxml

Linking FXML to Java

View

Model

Controller

FXML

Java

Java?

Linking FXML to Java

ModelView ControllerFXML Java Java

fx:id#method

@FXML

<AnchorPane xmlns:fx="http://javafx.com/fxml" fx:controller="contents.BrowserController"> <children> <HBox> <children> <TextField fx:id="textfield" /> <Button onAction="#handleAction" /> </children> </HBox> <WebView fx:id="webview" /> </children></AnchorPane>

<AnchorPane xmlns:fx="http://javafx.com/fxml" fx:controller="contents.BrowserController"> <children> <HBox> <children> <TextField fx:id="textfield" /> <Button onAction="#handleAction" /> </children> </HBox> <WebView fx:id="webview" /> </children></AnchorPane>

<AnchorPane xmlns:fx="http://javafx.com/fxml" fx:controller="contents.BrowserController"> <children> <HBox> <children> <TextField fx:id="textfield" /> <Button onAction="#handleAction" /> </children> </HBox> <WebView fx:id="webview" /> </children></AnchorPane>

public class BrowserController implements Initializable { @FXML private TextField textfield; @FXML private WebView webview; private WebEngine engine; @FXML public void handleAction(ActionEvent event) { engine.load(textfield.getText()); } @Override public void initialize(URL url, ResourceBundle rb) { engine = webview.getEngine(); } }

public class BrowserController implements Initializable { @FXML private TextField textfield; @FXML private WebView webview; private WebEngine engine; @FXML public void handleAction(ActionEvent event) { engine.load(textfield.getText()); } @Override public void initialize(URL url, ResourceBundle rb) { engine = webview.getEngine(); } }

<AnchorPane xmlns:fx="http://javafx.com/fxml" fx:controller="contents.BrowserController"> <children> <HBox> <children> <TextField fx:id="textfield" /> <Button onAction="#handleAction" /> </children> </HBox> <WebView fx:id="webview" /> </children></AnchorPane>

<AnchorPane xmlns:fx="http://javafx.com/fxml" fx:controller="contents.BrowserController"> <children> <HBox> <children> <TextField fx:id="textfield" /> <Button onAction="#handleAction" /> </children> </HBox> <WebView fx:id="webview" /> </children></AnchorPane>

<AnchorPane xmlns:fx="http://javafx.com/fxml" fx:controller="contents.BrowserController"> <children> <HBox> <children> <TextField fx:id="textfield" /> <Button onAction="#handleAction" /> </children> </HBox> <WebView fx:id="webview" /> </children></AnchorPane>

public class BrowserController implements Initializable { @FXML private TextField textfield; @FXML private WebView webview; private WebEngine engine; @FXML public void handleAction(ActionEvent event) { engine.load(textfield.getText()); } @Override public void initialize(URL url, ResourceBundle rb) { engine = webview.getEngine(); } }

public class BrowserController implements Initializable { @FXML private TextField textfield; @FXML private WebView webview; private WebEngine engine; @FXML public void handleAction(ActionEvent event) { engine.load(textfield.getText()); } @Override public void initialize(URL url, ResourceBundle rb) { engine = webview.getEngine(); } }

Tools

Java

FXML

NetBeans

Scene Builder

Conclusion

3 migration scenarios

Not so different from a Component-based UI standpointFXML is a key feature

No mention in this sessionCSS, Animaction, EffectShape, Aysnc task

From Swing To JavaFX

Java in the BoxYuichi Sakuraba

- Migration Guide to JavaFX -

Recommended