Skip to content
Snippets Groups Projects
Commit 6f70ef6a authored by Ryan Le's avatar Ryan Le
Browse files

Guide now shows how to switch between scenes

parent ac5de832
No related branches found
No related tags found
No related merge requests found
Showing
with 154 additions and 38 deletions
File added
File added
File added
......@@ -7,8 +7,7 @@
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="app.HomeController">
<top>
<MenuBar BorderPane.alignment="CENTER">
<menus>
......@@ -40,6 +39,6 @@
<Button mnemonicParsing="false" onAction="#clickRightButton" text="Right Button" BorderPane.alignment="CENTER" />
</right>
<bottom>
<Button mnemonicParsing="false" onAction="#clickBottomButton" text="Reset" BorderPane.alignment="CENTER" />
<Button mnemonicParsing="false" onAction="#switchScreen" text="Switch Screen" BorderPane.alignment="CENTER" />
</bottom>
</BorderPane>
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.layout.AnchorPane?>
<SplitPane dividerPositions="0.5" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" orientation="VERTICAL" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="app.SecondScreenController">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0">
<children>
<Label alignment="CENTER" contentDisplay="CENTER" layoutX="209.0" layoutY="81.0" prefHeight="196.0" prefWidth="598.0" text="This is the second screen!" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children></AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0">
<children>
<Button layoutX="212.0" layoutY="53.0" mnemonicParsing="false" onAction="#switchScreen" prefHeight="296.0" prefWidth="798.0" text="Go Back!" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children></AnchorPane>
</items>
</SplitPane>
File deleted
package app;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.stage.Stage;
import java.awt.event.ActionEvent;
import java.io.IOException;
public class HomeController {
@FXML
private Label middle;
public void clickLeftButton() {
middle.setText("The button on the left was clicked.");
}
public void clickRightButton() {
middle.setText("The button on the right was clicked.");
}
public void clickBottomButton() {
middle.setText("This is the starter text.");
}
public void switchScreen(javafx.event.ActionEvent event) throws IOException {
Parent parent = FXMLLoader.load(getClass().getResource("secondScreen.fxml"));
Scene scene = new Scene(parent);
Stage window = (Stage)((Node)event.getSource()).getScene().getWindow();
window.setScene(scene);
window.show();
}
}
package sample;
package app;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
......@@ -10,7 +10,7 @@ public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
Parent root = FXMLLoader.load(getClass().getResource("home.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 800, 600));
primaryStage.show();
......
package app;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.awt.event.ActionEvent;
import java.io.IOException;
public class SecondScreenController {
public void switchScreen(javafx.event.ActionEvent event) throws IOException {
Parent parent = FXMLLoader.load(getClass().getResource("home.fxml"));
Scene scene = new Scene(parent);
Stage window = (Stage)((Node)event.getSource()).getScene().getWindow();
window.setScene(scene);
window.show();
}
}
......@@ -7,8 +7,7 @@
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="app.HomeController">
<top>
<MenuBar BorderPane.alignment="CENTER">
<menus>
......@@ -40,6 +39,6 @@
<Button mnemonicParsing="false" onAction="#clickRightButton" text="Right Button" BorderPane.alignment="CENTER" />
</right>
<bottom>
<Button mnemonicParsing="false" onAction="#clickBottomButton" text="Reset" BorderPane.alignment="CENTER" />
<Button mnemonicParsing="false" onAction="#switchScreen" text="Switch Screen" BorderPane.alignment="CENTER" />
</bottom>
</BorderPane>
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.layout.AnchorPane?>
<SplitPane dividerPositions="0.5" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" orientation="VERTICAL" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="app.SecondScreenController">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0">
<children>
<Label alignment="CENTER" contentDisplay="CENTER" layoutX="209.0" layoutY="81.0" prefHeight="196.0" prefWidth="598.0" text="This is the second screen!" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children></AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0">
<children>
<Button layoutX="212.0" layoutY="53.0" mnemonicParsing="false" onAction="#switchScreen" prefHeight="296.0" prefWidth="798.0" text="Go Back!" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children></AnchorPane>
</items>
</SplitPane>
package sample;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
public class Controller {
@FXML
private Label middle;
public void clickLeftButton() {
middle.setText("The button the left was clicked.");
}
public void clickRightButton() {
middle.setText("The button the right was clicked.");
}
public void clickBottomButton() {
middle.setText("This is the starter text.");
}
}
......@@ -36,10 +36,12 @@ This tutorial will walk you through creating a basic JavaFX application. The end
7. Click on `JavaFX`.
8. Set the path to `SceneBuilder.exe`. Assuming you installed it to the default location, it *should* be located at `C:\Program Files\SceneBuilder\SceneBuilder.exe`.
9. Click `OK`.
10. IntelliJ should have generated three files within the `src` directory of your project, within a folder called `sample`.
11. Find the file entitled `sample.fxml`.
12. Right click on the file, and click the option that says `Open In SceneBuilder`.
- This is the file that holds all of the code for the look of your application. Now that you've opened it up directly, whenever you make changes within the SceneBuilders, those changes will also be reflected with `sample.fxml` whenever you click save.
10. IntelliJ should have generated three files within the `src` directory of your project, within a package called `sample`.
11. Rename this `sample` package to `app`.
- Make sure all occurrences are renamed to `app`.
12. Find the file entitled `sample.fxml`, and rename it to `home.fxml`.
14. Right click on the file, and click the option that says `Open In SceneBuilder`.
- This is the file that holds all of the code for the look of your application. Now that you've opened it up directly, whenever you make changes within the SceneBuilders, those changes will also be reflected with `home.fxml` whenever you click save.
## Building your first application
......@@ -67,14 +69,15 @@ Now that we have three buttons for input and a label with starter text in it, le
2. Open up the `Inspector` for the middle `Label`.
3. Open up the `Code` panel, and under `Identity`, set the `fx:id` to `middle`, or whatever else you might want to name it.
4. We are also going to have to write some code to change the text. The code that controls everything happening on the GUI should all go into the automatically-created `Controller.java` class.
5. Paste the following stub in your `Controller.java`; we will talk about the different parts of it in a moment.
- But let's rename that to `HomeController.java.`
6. Paste the following stub in your `HomeController.java`; we will talk about the different parts of it in a moment.
```
1 package sample;
1 package app;
2
3 import javafx.fxml.FXML;
4 import javafx.scene.control.Label;
5
6 public class Controller {
6 public class HomeController {
7 @FXML
8 private Label middle;
9
......@@ -99,6 +102,42 @@ On line 8 we are declaring a `Label` object entitled `middle`, and it is annotat
8. In the `Main` subgroup, under `On Action`, type in the name of the function you wish to be called when the button is clicked - in this case, it's just `clickLeftButton`.
9. Do the same for the other two buttons and their respective functions.
10. In order to actually test out your new program, you are going to have to link the GUI to the controller - so on the bottom-left portion of your page, open up the `Controller` panel.
11. In `Controller Class`, type in `sample.Controller` - that's the package name followed by the name of the Controller class.
11. In `Controller Class`, type in `app.HomeController` - that's the package name followed by the name of the Controller class.
12. Now that everything is linked together, you can run the program out of `Main` and see that the label text changes on each button press, exactly as intended.
- You may want to change the resolution of the scene within `Main`, as it is probably a bit too small currently.
### Switching Between Screens (Scenes)
Everything you did just previously was all within the same screen. In many cases, applications are made up of different screens that display different information and have different functionality. As of right now, we have exactly one controller for one view. In order to create an application with multiple screens, or scenes as they are referred to by JavaFX, we are going to need to create new views and new controllers to represent these.
1. Create two new files: `secondScreen.fxml` and `SecondScreenController.java`.
2. Open up `secondScreen.fxml` in the SceneBuilder, and replace the `AnchorPane` with a `SplitPane`.
- The `SplitPane` will start off holding two `AnchorPanes` within them - these elements are essentially open containers that allow you to move elements around with ease, anchoring them to their positions.
3. Put a `Label` in the top pane and a `Button` in the bottom.
4. With `AnchorPanes`, one really useful thing you can do is fit elements to the size of the parent, the `AnchorPane` being the parent. Right click both of the elements you just placed and fit them to their parents.
Now to link these two screens together...
5. Go back to your `HomeController` and paste the following snippet in: we'll walk through it again in a second.
```
public void switchScreen(javafx.event.ActionEvent event) throws IOException {
Parent parent = FXMLLoader.load(getClass().getResource("secondScreen.fxml"));
Scene scene = new Scene(parent);
Stage window = (Stage)((Node)event.getSource()).getScene().getWindow();
window.setScene(scene);
window.show();
}
```
- First, the function finds the resource that you are trying to link to: in this case, it is `secondScreen.fxml`.
- Rather than handle the contents of the function within a `try...catch`, we just tell the function to throw an exception in the case it cannot find the file you are trying to link to, because there is not anything to even do if the window can't be opened properly.
- It creates a scene using that file, and then we do a lot of casting in order to create a window out of the file to pass a scene into. Then we show the new screen.
6. IntelIiJ is smart enough to see that you've just now tried to use a lot of different things without importing them first. Import all the new classes you just used.
7. Change out the `Reset` button for a `Switch Screens` button, and point its action to this new `switchScreen` function.
8. Run the application and verify that you can switch screens by pressing the button.
9. Now, copy and paste the same function into the new `SecondScreenController`, changing out `secondScreen.fxml` for `home.fxml`.
10. Link `secondScreen.fxml` to the `SecondScreenController` as we did previously in Step 11 of "Registering Event Handlers."
11. You should be able to move back and forth between the two scenes now!
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment