📜 ⬆️ ⬇️

Hi, JavaFX! Let's get acquainted?

Introduction


Greetings, habrovchane. Recently I came across a new and interesting Java technology for me - JavaFX. My soul stretches more towards the Russian language than English, so I began to search for Russian-language tutorials using this technology. I was disappointed because there are not enough guides on this topic on the net. I had to study everything myself, reading tedious documentation.
I want to write a series of small guides for those who are just getting acquainted with this technology. Articles will be calculated for beginners and will have a "detail-explaining" character.

This is my first article, a copywriter from me is not very good, so please: do not judge strictly. I am also a beginner as a programmer and, if possible, do not criticize the code for nothing, but I will definitely listen to all the tips and take it into account.

About JavaFX



JavaFX is a fairly young technology that was supposed to come and eclipse the well-known Swing technology. Since its inception, it has undergone many changes and at the moment we have a fairly stable and functional version. I have not worked with SilverLight, but judging by the comments, JavaFX is significantly inferior to the Microsoft product.
I highlight two main advantages of the described technology:


What is it about?


This article will only introduce you to JavaFX. Even the main features of the technology will not be shown here, as this will be in subsequent articles. The article will show you how windows are created, how to make them non-standard forms and ... everything.
')
At the end we will get a window, as in the screenshot below (the black background is my desktop) with one working button.
Screenshots

Mouse hover over the button:


Training


I use the NetBeans development environment, as I consider it quite convenient, beautiful and powerful (all for free). In order not to bother with installing the SDK, I recommend simply downloading NetBeans with the JavaFX platform already installed.
For those who love mouse-clickable programming, there is an additional tool called JavaFX Scene Builder. After you download and install it, go to NetBeans, in the main menu, select “Tools” -> “Options”, then go to the tab “Java” -> “JavaFX”. There you set up the home page for the Scene Builder by selecting the directory with the Builder. Now, after special manipulations, you can develop the design of the form in this editor.

First project


Let's start creating our first application. Select in the main menu “File” -> “Create project”. In the categories presented, select “JavaFX” and on the right - “JavaFX Application”; further everything is standard.
The created class already has some functionality. Below is a code with comments.

Code
import javafx.application.Application; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.layout.StackPane; import javafx.stage.Stage; public class TestClass extends Application { /** * ,     .  main()     Java. */ @Override public void start(Stage primaryStage) { //  . Button btn = new Button(); //    . btn.setText("Say 'Hello World'"); //  . btn.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { System.out.println("Hello World!"); } }); //   / . StackPane root = new StackPane(); //    . root.getChildren().add(btn); // .     (      Swing). Scene scene = new Scene(root, 300, 250); //primaryStage -   . //  . primaryStage.setTitle("Hello World!"); //   primaryStage.setScene(scene); primaryStage.show(); } /** * The main() method is ignored in correctly deployed JavaFX application. * main() serves only as fallback in case the application can not be * launched through deployment artifacts, eg, in IDEs with limited FX * support. NetBeans ignores main(). * * @param args the command line arguments */ public static void main(String[] args) { launch(args); } } 


We create a simple project


Now we proceed to the more difficult part, but also more interesting. Create a small login window in any application. I admit honestly: I “tore” him out of my course project, it doesn’t bear any practical use separately, but on it I want to show some interesting points. The project is implemented on a template MVC.
Link to the archive with the necessary pictures.

Let's get started


Create a package "view". We click PKM on the created package, select “New” -> “Java Class”. Call it what you will; I will call it "EnterScreen".
We inherit it from the class “Application” and implement an abstract method.
Code
 package view; import javafx.application.Application; import javafx.stage.Stage; public class EnterScreen extends Application { @Override public void start(Stage primaryStage) throws Exception { } public static void main(String[] args) { launch(args); } } 



Let's create a field in our class (its purpose will be seen below).
Code
 package view; import javafx.application.Application; import javafx.scene.control.PasswordField; import javafx.scene.control.TextField; import javafx.scene.image.ImageView; import javafx.stage.Stage; import javafx.stage.StageStyle; public class EnterScreen extends Application { Stage mainStage = null; @Override public void start(Stage primaryStage) throws Exception { mainStage = new Stage(StageStyle.TRANSPARENT); } public static void main(String[] args) { launch(args); } } 



I will do all the actions to create the window in one start () method. First, I will create the background of our window and add the fields for entering the login and password. Further, the code with comments:
Code
 package view; import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.control.PasswordField; import javafx.scene.control.TextField; import javafx.scene.image.ImageView; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.StackPane; import javafx.stage.Stage; import javafx.stage.StageStyle; public class EnterScreen extends Application { public Stage mainStage = null; @Override public void start(Stage primaryStage) throws Exception { //      ,         mainStage = new Stage(StageStyle.TRANSPARENT); //   StackPane root = new StackPane(); //screen -  .     . ImageView screen = new ImageView("pict/EnterScreen.png"); //     root.getChildren().add(screen); //   /  AnchorPane anPane = new AnchorPane(); //      root.getChildren().add(anPane); //       TextField login = new TextField("login"); PasswordField password = new PasswordField(); //    login.setPrefSize(179, 24); password.setPrefSize(179, 24); //  :     . //           .   ,    AnchorPane.setLeftAnchor(login,519.0); AnchorPane.setLeftAnchor(password, 519.0); // ,       AnchorPane.setTopAnchor(login, 297.0); AnchorPane.setTopAnchor(password, 347.0); //      anPane.getChildren().add(login); anPane.getChildren().add(password); // .  :  .   :    . :   (   null,    ) Scene scene = new Scene(root, 1024, 768, null); mainStage.setScene(scene); mainStage.show(); } public static void main(String[] args) { launch(args); } } 



Create another package called “pict” and put the pictures there.
This is the working part, only we do not have buttons yet. But there are already two input fields and a non-standard view window.
Create two more packages: “controller” and “model”. In the first, we will have event handlers, and in the second, a small business logic.
Now add an exit button (we will implement the right button).
Code
 package view; import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.control.PasswordField; import javafx.scene.control.TextField; import javafx.scene.image.ImageView; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.StackPane; import javafx.stage.Stage; import javafx.stage.StageStyle; public class EnterScreen extends Application { public Stage mainStage = null; @Override public void start(Stage primaryStage) throws Exception { mainStage = new Stage(StageStyle.TRANSPARENT); StackPane root = new StackPane(); ImageView screen = new ImageView("pict/EnterScreen.png"); root.getChildren().add(screen); AnchorPane anPane = new AnchorPane(); root.getChildren().add(anPane); TextField login = new TextField("login"); PasswordField password = new PasswordField(); login.setPrefSize(179, 24); password.setPrefSize(179, 24); AnchorPane.setLeftAnchor(login,519.0); AnchorPane.setLeftAnchor(password, 519.0); AnchorPane.setTopAnchor(login, 297.0); AnchorPane.setTopAnchor(password, 347.0); anPane.getChildren().add(login); anPane.getChildren().add(password); //      (  ) ImageView rightButton = new ImageView("pict/RightButton.png"); //    - rightButton.setOnMouseEntered(new EnterScreenEvents.OnMouseEnterRB()); rightButton.setOnMouseExited(new EnterScreenEvents.OnMouseExitRB()); rightButton.setOnMouseClicked(new EnterScreenEvents.OnMouseClickedRB(this)); //  - AnchorPane.setLeftAnchor(rightButton, 567.0); AnchorPane.setTopAnchor(rightButton, 420.0); // -   anPane.getChildren().add(rightButton); Scene scene = new Scene(root, 1024, 768, null); mainStage.setScene(scene); mainStage.show(); } public static void main(String[] args) { launch(args); } } 



Our application will not work because no handler classes have been created yet. Well, let's create them. In the “controller” package, create the class EnterScreenEvents. In this class, we will create static inner classes, which will be handlers. All of them will implement the EventHandler interface. Next, follow the following code:

Code
 package controller; import javafx.event.Event; import javafx.event.EventHandler; import javafx.scene.image.ImageView; import view.EnterScreen; public class EnterScreenEvents { public static class OnMouseEntered implements EventHandler{ @Override public void handle(Event event) { ImageView iv = (ImageView) event.getSource(); iv.setImage(resManager.getRightPressedButtonImage()); } } public static class OnMouseExit implements EventHandler{ @Override public void handle(Event event) { ImageView iv = (ImageView) event.getSource(); iv.setImage(resManager.getRightButtonImage()); } } public static class OnMouseClickedRB implements EventHandler{ private EnterScreen ES = null; public OnMouseClickedRB(EnterScreen ES) { this.ES = ES; } @Override public void handle(Event event) { } } } 


Handler classes created. Now we implement the model. In the model we will make a resource manager, which will have static methods for loading images and returning objects with them. Create a “resManager” class in the “model” package and describe it as shown below:
Code
 package model; import javafx.scene.image.Image; public class resManager { public static Image getEnterScreenBackground(){ return new Image("pict/EnterScreen.png"); } public static Image getRightButtonImage(){ return new Image("pict/RightButton.png"); } public static Image getRightPressedButtonImage(){ return new Image("pict/RightPressedButton.png"); } } 


Now the picture button works, but does not close the window yet. Don't forget to change the hard link of the background to the method from the model in the view. Now create a method in the window that can close it. Add the following lines of code to the class:
Code
  public void close() { Platform.runLater(new closing()); } private class closing implements Runnable { @Override public void run() { mainStage.close(); } } 


Why did I arrange the closure that way? I did not find another way, because in other cases an exception is thrown about the lack of privileges of the thread (only the application and platform thread can close the window or perform another operation to change the window state). Do not forget to add the method that closes the window to the mouse click handler.

Conclusion


Here is a small and non-standard login window ready. True, its functionality consists only in that it closes, but it’s not possible to write endlessly here either. If my article is not disgraced in the comments, I will continue the cycle and tell you about the possibilities of technology, which are already deeper and more effective: working with CSS styles, main components, creating effects and animation, and much more.

Thanks for attention. Until next time.

PS> Special thanks to George Tikholaz (XMAITER) for creating the button and the background image.
PSS> Link to the project exported to a ZIP file.

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


All Articles