HelloWorld from the example offered by Oracle in “Getting Started with JavaFX” on a Windows PC. Transforming the login and password input window using CSS, creating an FXML form, and using CSS in an FXML form. Again, the command line and subtleties that we were not told in the tutorial.
The first section,
Getting Started with JavaFX, describes how to create the simplest JavaFX application that you started using the command line
here . In the second section it is proposed to make a login and password entry window. It is made from the first application
here . As a result, the code has grown somewhat in size.
HelloWorld.javapackage helloworld; 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; import javafx.scene.layout.GridPane; import javafx.geometry.*; import javafx.scene.text.*; import javafx.scene.control.*; import javafx.scene.paint.*; import javafx.scene.layout.HBox; public class HelloWorld extends Application { public static void main(String[] args) { launch(args); } @Override public void start(Stage primaryStage) { primaryStage.setTitle("JavaFX Welcome"); GridPane grid = new GridPane(); grid.setAlignment(Pos.CENTER); grid.setHgap(10); grid.setVgap(10); grid.setPadding(new Insets(25, 25, 25, 25));
The commands for compiling, running, packing in jar and running jar, each in its CMD file, remain the same.
Command line @"C:\Program Files\Java\jdk1.7.0_40\bin\javac" -d out -classpath "C:\Program Files\Java\jre7\lib\jfxrt.jar" src\helloworld\HelloWorld.java @"C:\Program Files\Java\jdk1.7.0_40\bin\java" -classpath "C:\Program Files\Java\jre7\lib\jfxrt.jar;.\out" helloworld.HelloWorld @"C:\Program Files\Java\jdk1.7.0_40\bin\javafxpackager" -createjar -appclass helloworld.HelloWorld -srcdir .\out -outfile HelloWorld -v @"C:\Program Files\Java\jre7\bin\java.exe" -jar HelloWorld.jar @pause
Let's take the third section. The tutorial proposes to use the blank from the second section. So we will do it, only he with us is not Login.java, but HelloWorld.java. It's time to create a CSS file.
')
Ignore those instruction points (in the tutorial) that relate to working with the IDE. In the fourth paragraph, we propose to create a CSS file in the src \ login folder, in our case we get src \ helloworld. Well, for the time being we’ll do it, just call it, since we continue to greet the world, HelloWorld.css. Although it does not matter.
The sixth paragraph tells what changes need to be made to the java code: after the lines
Scene scene = new Scene(grid, 300, 275); primaryStage.setScene(scene);
need to insert
scene.getStylesheets().add (HelloWorld.class.getResource("HelloWorld.css").toExternalForm());
(adjusted for file and class names), right before
primaryStage.show();
In addition, in order for text objects to be somehow controlled by a CSS file, these objects must be given appropriate identifiers. To do this, find the line
scenetitle.setFont(Font.font(“Tahoma”, FontWeight.NORMAL, 20));
and
actiontarget.setFill(Color.FIREBRICK);
and replace them with
scenetitle.setId("welcome-text");
and
actiontarget.setId("actiontarget");
respectively. And it is better not to replace just in case, but to close with a comment, and fix the fix with the line below.
And, of course, you need to fill in a file with style sheets.
HelloWorld.css .root { -fx-background-image: url("background.jpg"); } .label { -fx-font-size: 12px; -fx-font-weight: bold; -fx-text-fill: #333333; -fx-effect: dropshadow( gaussian , rgba(255,255,255,0.5) , 0,0,0,1 ); } #welcome-text { -fx-font-size: 32px; -fx-font-family: "Arial Black"; -fx-fill: #818181; -fx-effect: innershadow( three-pass-box , rgba(0,0,0,0.7) , 6, 0.0 , 0 , 2 ); } #actiontarget { -fx-fill: FIREBRICK; -fx-font-weight: bold; -fx-effect: dropshadow( gaussian , rgba(255,255,255,0.5) , 0,0,0,1 ); } .button { -fx-text-fill: white; -fx-font-family: "Arial Narrow"; -fx-font-weight: bold; -fx-background-color: linear-gradient(#61a2b1, #2A5058); -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.6) , 5, 0.0 , 0 , 1 ); } .button:hover { -fx-background-color: linear-gradient(#2A5058, #61a2b1); }
At once I filled in everything that, according to the text of the third section, it is proposed to stick in gradually, admiring the result - background image, text effects, button effects.
Oh yeah, I also need another image for the background image ... Well, I didn’t download or draw, but I copied the first one. The first one came from the background (ironically, just to the point) from the folder “My Pictures \ Samples of Drawings” - Sunset.jpg. Renamed to background.jpg and put it next to the CSS file.
Compile. Successfully. We start. Does not work! We study the output of errors. Troubling frequently encountered Unknown source, therefore, an unknown source. Plus, there are familiar letters among all this disgrace:
at helloworld.HelloWorld.start(HelloWorld.java:68)
And in the sixty-eighth line, we just pick out the styles from the CSS-file. Which is laid according to the instructions in src \ helloworld. In the context of this “study”, I don’t even want to consider why NetBeans needs this file in the source folder (although I guess). But, since we have never indicated the path to the style file anywhere, it should lie directly next to the person who uses it. The unpacked program is launched from the HelloWorld.class file, which is in out \ helloworld \. Let's go there and transfer, along with the picture.
Now compiled and run. True, the background image is very different from the tutorial, and the red-brick message about the pressed button on the red background is hard to see, but these are trifles, and this can be changed. Another thing is funny - now let's give the command to pack in the jar and try to start the jar-file.
Does not start! And if you run the console command, and not by clicking on the file itself, then you can see errors, and some of them are familiar ... Let's climb into the jar, as if it were an archive. There lies the com \ javafx \ main folder structure, which is provided by the javafxpackager utility, and META-INF with a manifest, which is not very interesting right now. And the helloworld folder is interesting, in which there is no HelloWorld.css, but there is HelloWorld.bss! It turns out that the packer brazenly, without our team, repacked the CSS into a binary form. Check? Let's replace the .css extension with .bss in the sixty-eighth line, compile it, but we will not run it right away, but package and run jar right away.
Now it starts. But, what a shame, does not start from HelloWorld.class! Do not keep the same two sets of sources for different cases. Moreover, bss is recommended for faster loading. Add a command that we write to the css2bss.cmd file:
@"C:\Program Files\Java\jdk1.7.0_40\bin\javafxpackager" -createbss -srcdir .\src\helloworld -outdir .\out\helloworld -srcfiles HelloWorld.css -v @pause
The CSS and background image files are transferred to src \ helloworld \ (as they were demanded from the very beginning), in the source file we leave in the line where getStylesheets () is the .bss extension. Compile. We do bss. We pack in jar. Now running and running from HelloWorld.class, and from HelloWorld.jar. And I propose to figure out what styles are responsible for what, and how they can be changed in different ways. This topic is not directly related to JavaFX.
Well, the fourth section of the tutorial is FXML. The program code changes so much that it is easier to rewrite it. And even create a copy of the project in a nearby folder, for example, GetStartFXML. There you need to copy already five command files and create out and src \ helloworld folders, and put the source in the last one.
HelloWorld.java package helloworld; import javafx.application.Application; import javafx.scene.Scene; import javafx.stage.Stage; import javafx.scene.*; import javafx.fxml.*; public class HelloWorld extends Application { public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) throws Exception { Parent root = FXMLLoader.load(getClass().getResource("fxml_example.fxml")); Scene scene = new Scene(root, 300, 275); stage.setTitle("FXML Welcome"); stage.setScene(scene); stage.show(); } }
Next, you need to collect the file fxml_example.fxml, scattered over the fourth section. Since the data from it will be picked up on the fly, as well as from a CSS file, it is worth making it right next to the HelloWorld.class file that uses it, which does not yet exist. That is, in out \ helloworld, so we will create a folder nested in out on our own, before the first compilation.
fxml_example.fxml <?xml version="1.0" encoding="UTF-8"?> <?import java.net.*?> <?import javafx.geometry.*?> <?import javafx.scene.control.*?> <?import javafx.scene.layout.*?> <?import javafx.scene.text.*?> <GridPane fx:controller="helloworld.FXMLExampleController" xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10" styleClass="root"> <padding><Insets top="25" right="25" bottom="10" left="25"/></padding> <Text id="welcome-text" text="Welcome" GridPane.columnIndex="0" GridPane.rowIndex="0" GridPane.columnSpan="2"/> <Label text="User Name:" GridPane.columnIndex="0" GridPane.rowIndex="1"/> <TextField GridPane.columnIndex="1" GridPane.rowIndex="1"/> <Label text="Password:" GridPane.columnIndex="0" GridPane.rowIndex="2"/> <PasswordField fx:id="passwordField" GridPane.columnIndex="1" GridPane.rowIndex="2"/> <HBox spacing="10" alignment="bottom_right" GridPane.columnIndex="1" GridPane.rowIndex="4"> <Button text="Sign In" onAction="#handleSubmitButtonAction"/> </HBox> <Text fx:id="actiontarget" GridPane.columnIndex="1" GridPane.rowIndex="6"/> <stylesheets> <URL value="@HelloWorld.css" /> </stylesheets> </GridPane>
This file immediately includes working with CSS, but why pull something? Therefore, let's put the newly created HelloWorld.css and background.jpg next. There is still not enough button event handling. In the fourth section it is proposed to use a separate file for this, mentioned in FXML: GridPane fx: controller = "helloworld.FXMLExampleController".
FXMLExampleController.java package helloworld; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.text.Text; public class FXMLExampleController { @FXML private Text actiontarget; @FXML protected void handleSubmitButtonAction(ActionEvent event) { actiontarget.setText("Sign in button pressed"); } }
And of course, do not forget to compile it too, for which we add an additional line to compile.cmd. In addition, I removed the "dog" before the compilation commands to see that both started and worked:
"C:\Program Files\Java\jdk1.7.0_25\bin\javac" -d out -classpath "C:\Program Files\Java\jre7\lib\jfxrt.jar" src\helloworld\HelloWorld.java "C:\Program Files\Java\jdk1.7.0_40\bin\javac" -d out -classpath "C:\Program Files\Java\jre7\lib\jfxrt.jar" src\helloworld\FXMLExampleController.java @pause
Compile. We collect jar. Run the class or run the jar. Works, differences in appearance and behavior from the previous example is not visible. But it turned out to divide the application into a bunch of modules - separately the main class that creates the scene, the form description separately, the event handler separately, the element styles separately. Moreover, the style sheets and the form description can be changed without recompiling the class, for example, rearranging elements in the cells of the GridPane table or changing the background image.
However, although it works, let's look into the jar archive. There, by the way, there is no HelloWorld.css file, but there is a .bss, as in the example from the third section. The fxml_example.fxml mentions HelloWorld.css. However, both class and jar work. Let's, as in the previous example, transfer HelloWorld.css and background.jpg from out \ helloworld to src \ helloworld (leave the FXML file in place). Compile. Making bss from css. We collect jar. We start class, and then we start jar. It works again! But what is it - to her in general, perhaps, without a difference? And let's, since the extension of the stylesheet file does not matter, in fxml_example.fxml we delete it completely? Instead
<stylesheets> <URL value="@HelloWorld.css" /> </stylesheets>
will do
<stylesheets> <URL value="@HelloWorld" /> </stylesheets>
But the program doesn’t really care about the file extension of styles — show only the direction with your finger, and then it will figure it out. Funny, right?
Now there is a testing ground for bullying - you can try all sorts of style substitutions, design, event handling and all that. You can try to run this workpiece not on the desktop, but in the browser - this is mentioned a little in the sixth section of the tutorial. But there is little and no interest, there is a separate manual about deploying applications. I also don’t want to stir up the fifth section, on Habré it was already well said about the visual effects of JavaFX
here , and the examples given in the tutorial do not fit into the framework of the first four sections.
I consider the HelloWorld theme in JavaFX based on jfxpub-overview as exhausted.