Monday, 23 April 2018

This week 2/2018 - JavaFX

Long time I was looking for some solution to create simple desktop application. My previous choice was SWT and JFace but I was not satisfied because of its OS dependence and different presentation depending of OS. There were some other problems with windows resizing and tree view updating.
This time when I developed something for desktop, I was looking for something what is supported by all most famous IDE and is OS independent.

I've tried JavaFX and I think it was good choice. Even a few small problems which I list in the end of article.

JavaFX  it has to be successor of Swing library. It was initialized in the end of 2008 as external library. It was included to JDK only since JDK7 update 6. Since JDK8 is a standard part of JDK/JRE and uses the same version numbering. Most common Java IDEs include scene builder GUI. The output of this tool is a fxml file which is more less an equivalent of programmatic scene creation and is updated when fxml is updated. My experience with this GUI in IntelliJ on Linux was not ideal because sometimes of rendering problems but it is helpful tool for beginner and to arrange elements on scene.

The JavaFX thread needs to be run from class extending Application class. Then creation of stage, scene have to be in JavaFX thread. The same is with every action which changes view. To make change from other thread it is required to call async method:
Platform.runLater(Runnable runnable);

Stage (representing a window) and its elements (scene nodes) can be loaded from fxml file and coded in Java as well. Fxml file is a xml file loaded during stage building.
JavaFX allows defining css styles of formulas which can be used in fxml file and java code as well.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.Spinner?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.TreeView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.Pane?>
<AnchorPane prefHeight="400.0" prefWidth="380.0" xmlns="http://javafx.com/javafx/8.0.121" xmlns:fx="http://javafx.com/fxml/1"
            fx:controller="example.TaskListController">
    <children>
        <TreeView fx:id="taskTree" layoutX="6.0" prefHeight="334.0" prefWidth="374.0" AnchorPane.bottomAnchor="65.0"
                  AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0"/>
        <Pane layoutY="338.0" prefHeight="65.0" prefWidth="470.0" AnchorPane.bottomAnchor="0.0">
            <children>
                 <TextField fx:id="taskNameInput" layoutX="70.0" layoutY="1.0" prefHeight="26.0" prefWidth="392.0"
   style="-fx-padding: 0px; -fx-border-insets: 0px; -fx-background-insets: 0px; -fx-control-inner-background:#BBB; -fx-font-size: 10px;"/>
                <CheckBox fx:id="autoClose" selected="true" layoutX="7.0" layoutY="35.0" mnemonicParsing="false" text="auto close"/>
                <Button fx:id="updateButton" layoutX="294.0" layoutY="31.0" mnemonicParsing="false" onAction="#onTaskUpdate" text="update"/>
                <Spinner fx:id="positionSpinner" amountToStepBy="1" max="1000" min="0" prefHeight="26.0"  prefWidth="104.0"/>
                <CheckBox fx:id="moveCheck" layoutX="205.0" layoutY="35.0" mnemonicParsing="false" text="move" onAction="#onMove"/>
            </children>
        </Pane>
    </children>
</AnchorPane>

I don't remember how it was in Swing but JavaFX on every user action creates an event. This is handled by hierarchy of registered by programmer event handlers. Each event has source of event, target and type. Some events can be triggered by other event, ex they change state of observed element.

Another problem was, how to test it? Hopefully there is a TestFX. It resemble a little Selenium - it is possible to find element by xpath query and execute some action. I did only a few such tests and I know that this tool has some problems with dual-screens on linux. I have to turn off one monitor to resolve problem.


Below a few problems which I met:
1. I could set only one icon for all stages.
2. CheckboxTreeItem - chain of calls, I don't know who triggered event (user/previous element in chain)
3. On linux I can't play mp3. I found out that I must install some libraries and after that it doesn't work as well.



No comments:

Post a Comment