📜 ⬆️ ⬇️

Javafx inside

JavaOne 2011 announced the release of the final version of JavaFX 2.0. Consider what it consists of and what means it offers.

image


')

Hello JavaFX


Create and run the first application in JavaFX. For this we need the JavaFX 2.0 SDK and the latest Netbeans . You can read about configuring JavaFX in Netbeans at http://netbeans.org/kb/docs/java/javafx-setup.html .

We launch Netbeans, choose from the File / New Project menu, in the dialog we select the JavaFX category and the JavaFX Application project type. A project with a single test form will be created as in the picture below (you can call the project HelloJavaFX or otherwise). Form class code:
package hellojavafx; import javafx.application.*; import javafx.event.*; import javafx.scene.*; import javafx.scene.control.*; import javafx.stage.*; public class HelloJavaFX extends Application { public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage primaryStage) { primaryStage.setTitle("Hello World"); Group root = new Group(); Scene scene = new Scene(root, 300, 250); Button btn = new Button(); btn.setLayoutX(100); btn.setLayoutY(80); btn.setText("Hello World"); btn.setOnAction(new EventHandler<ActionEvent>() { public void handle(ActionEvent event) { System.out.println("Hello World"); } }); root.getChildren().add(btn); primaryStage.setScene(scene); primaryStage.show(); } } 

result:

image

Let's see what we have in the dist folder after compilation. There will be the following files:
- folder web-files - contains images to run as an applet
- HelloJavaFX.html - page with embedded applet of the application
- HelloJavaFX.jar - an application to run with a regular double click
- HelloJavaFX.jnlp - start handle via WebStart

We are interested in the HelloJavaFX.jar application itself. Open it with any archiver (.jar is a regular .zip archive) and look at the manifest. Main startup line:
Main-Class: com/javafx/main/Main
says that a net star com.javafx.main.Main is added to every JavaFX application by Netbeans, which initializes all JavaFX libraries and starts the application itself. The name of the main class is taken from the JavaFX-Application-Class field, in our case this is hellojavafx.HelloJavaFX

Nothing unusual. At the moment, JavaFX is just a set of libraries whose functions can be used from Java code.

JavaFX in Swing


Consider an example of a Swing form with an embedded JavaFX component. Create a new project in Netbeans and add a link to the JavaFX Runtime library to it (by default, it is in the C: \ Program Files \ Oracle \ JavaFX Runtime 2.0 \ lib \ jfxrt.jar) file.

After connecting Runtime, you can embed any JavaFX components using the JFXPanel class. Let's add a text editor with the following code:
 package swingjavafx; import javax.swing.*; import java.awt.event.*; import javafx.embed.swing.*; import javafx.scene.*; import javafx.application.*; import javafx.scene.web.*; import javafx.scene.effect.*; public class SwingJavaFx extends JFrame { HTMLEditor edtr; public SwingJavaFx() { this.setSize(600, 400); this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setLayout(null); JButton b1 = new JButton("Read"); b1.setSize(150, 22); b1.setLocation(10, 10); b1.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { JOptionPane.showMessageDialog(null, edtr.getHtmlText()); } }); this.add(b1); final JFXPanel jfx = new JFXPanel(); jfx.setSize(560, 300); jfx.setLocation(10, 40); this.add(jfx); Platform.runLater(new Runnable() { @Override public void run() { Group root = new Group(); Scene scene = new Scene(root, 400, 300); jfx.setScene(scene); javafx.scene.shape.Rectangle rctngl = new javafx.scene.shape.Rectangle(); rctngl.setTranslateX(20); rctngl.setTranslateY(30); rctngl.setWidth(500); rctngl.setHeight(250); rctngl.setEffect(new Shadow()); root.getChildren().add(rctngl); edtr = new HTMLEditor(); edtr.setHtmlText("Blablabla"); edtr.setTranslateX(20); edtr.setTranslateY(30); edtr.setPrefWidth(500); edtr.setPrefHeight(250); root.getChildren().add(edtr); } }); } public static void main(String[] args) { new SwingJavaFx(); } } 

The result is the following form:

image

As can be seen from the code of the Read button, we can at any time access the data in a text editor. To run such an application, we need to add in the class-path the path to the JavaFX Runtime Library, for example:

java -cp %cp%;"C:\Program Files\Oracle\JavaFX Runtime 2.0\lib\jfxrt.jar";SwingJavaFx.jar swingjavafx.SwingJavaFx

Everything is rather trivial and does not differ from the use of other libraries in Java projects.

JavaFX API


JavaFX features are available on the platform page . The API has a set of classes for drawing primitives, graphs, a set of GUI components with their own design. Finally, a web browser component and a text editor with the possibility of formatting have appeared.

At http://www.oracle.com/technetwork/java/javafx/overview/index.html, you can run the Ensemble demo application (this is an analogue of the Flex Component Explorer ).

image

Binding


Binding (binding) is designed to bind the properties of objects. For example, you can snap the coordinates of the button to the width of the window and as a result, when resizing the form, the attached button will also move.

Consider an example:
 package bindingjavafx; import javafx.application.*; import javafx.event.*; import javafx.scene.*; import javafx.scene.control.*; import javafx.stage.*; import javafx.beans.binding.*; import javafx.beans.value.*; public class BindingJavaFX extends Application { public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage primaryStage) { primaryStage.setTitle("Hello World"); Group root = new Group(); final Scene scene = new Scene(root, 300, 250); final Button btn = new Button(); btn.setLayoutX(100); btn.setLayoutY(80); btn.setText("Hello World"); btn.setOnAction(new EventHandler<ActionEvent>() { public void handle(ActionEvent event) { System.out.println("Hello World"); } }); final DoubleBinding db = scene.widthProperty().subtract(150); db.addListener(new javafx.beans.value.ChangeListener< Number>() { public void changed(ObservableValue<? extends Number> ov, Number t, Number t1) { btn.setLayoutX(db.getValue()); } }); root.getChildren().add(btn); primaryStage.setScene(scene); primaryStage.show(); } } 


Result:

image

Line with code
final DoubleBinding db = scene.widthProperty().subtract(150);
creates a db variable and binds its value to the width of the form minus 150 pixels. Unfortunately, we cannot simply bind the coordinates of a button to this variable (of type btn.layoutX.bind (db); which would be obvious and convenient). Therefore, you should add a Listener to the created variable, in which you update the coordinates of the button:
 db.addListener(new javafx.beans.value.ChangeListener< Number>() { public void changed(ObservableValue<? extends Number> ov, Number t, Number t1) { btn.setLayoutX(db.getValue()); } }); 


In addition, the binding imposes additional restrictions - if you bind a property to a variable, you cannot change it by simple assignment, an exception will be thrown while the application is running.

The API code itself is over-bloated, for example, the SimpleDoubleProperty class has an inheritance hierarchy of six classes and implements nine interfaces. This is a new understanding of the characteristics of simple.

As a result, a good idea does not look very attractive. Lots of code, implicit errors. Although a simple and clear implementation of binding is available for many languages ​​and libraries, including Swing .

Using CSS


Interface design can be set using CSS. To do this, create a description of the styles, for example:
 .cssbutton { -fx-font: 16px "Serif"; -fx-padding: 10; -fx-background-color: #CCFF99; -fx-effect: dropshadow( one-pass-box , black , 12 , 0.0 , 1 , 1 ); } 

- cssbutton style sets the font, indents, fill and shadow effect. Next you need to connect the stylesheet to the scene:

scene.getStylesheets().add("cssjavafx/style.css");

and add a style to the component by name:

btn.getStyleClass().add("cssbutton");

The button will look something like this:

image

A description of the properties available in CSS can be found on the documentation page .

It is not very clear why it is generally necessary to set styling. Everything that can be set with styles can be done in the code, in CSS you cannot use variables or calculations, you cannot create new properties, styles are difficult to debug.

Using FXML


Form layout can be specified in a separate FXML file and loaded from the application when the application starts. This approach is used in many development environments.

Netbeans proposes to create a project with the JavaFX FXML Application type for this purpose. An initial form of approximately the following content will be created:
 package fxmljavafx; import java.net.*; import java.util.*; import javafx.event.*; import javafx.fxml.*; import javafx.scene.control.*; public class Sample implements Initializable { @FXML private Label label; @FXML private void handleButtonAction(ActionEvent event) { System.out.println("You clicked me!"); label.setText("Hello World!"); } @Override public void initialize(URL url, ResourceBundle rb) { // } } 


The @FXML annotation is used to designate variables and functions available when loading from an FXML file. The file itself looks like this:

 <?xml version="1.0" encoding="UTF-8"?> <?import java.lang.*?> <?import javafx.scene.*?> <?import javafx.scene.control.*?> <?import javafx.scene.layout.*?> <AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml" fx:controller="fxmljavafx.Sample"> <children> <Button id="button" layoutX="126" layoutY="90" text="Click Me!" onAction="#handleButtonAction" fx:id="button" /> <Label id="label" layoutX="126" layoutY="120" minHeight="16" minWidth="69" prefHeight="16" prefWidth="69" fx:id="label" /> </children> </AnchorPane> 


As you can see in the example, both the handleButtonAction method and the label property specified in the code are used inside the FXML form description.

Loading an FXML form when the application starts is called like this:
 Parent root = FXMLLoader.load(getClass().getResource("Sample.fxml")); stage.setScene(new Scene(root)); stage.show(); 


There is no advantage to creating such a GUI. There is no visual editor, and editing both the Java code and the FXML description is equally costly to edit with your hands.

Visual editor


There is a form factor in Visual Studio for VB and C #, in Adobe Flex, in Oracle JBuilder there is an excellent editor for Swing. For JavaFX, the visual editor was announced 2 years ago. You can even watch a video with him on the page http://www.flickr.com/photos/douglasbullard/3609213630/in/photostream/ .

But so far there has been no public release and it is not known when it will be.

A spoon of honey in a tar barrel


The overall assessment is most likely unsatisfactory. Demo applications slow down, the appearance of components is inferior to Macintosh Aqua, Adone Flex or Microsoft Metro. The first version of JavaFX appeared back in 2008, but Sun was never able to bring the technology to the mind.

However, a lot has been said about JavaFX at the latest JavaOne. Let's hope that Oracle will send developers with the iron hand in the right direction and make them finally issue a working tool with promises.

Source: https://habr.com/ru/post/130057/


All Articles