{"id":"gui-basics-first-window","slug":"first-window","title":"A first window","text":"Every program in this course so far has used the console: it printed lines of text and read the lines you typed, one after another. Most programs that people use every day look different. They open a **window** with text, buttons and fields to type in, and the user clicks and types wherever they like, in any order. That's a **graphical user interface**, or GUI for short. Part 13 builds them with **JavaFX**, a Java library for windows.\n\n### JavaFX in Java Arena\n\nJavaFX isn't part of Java itself: it's a library that a program uses, as the tests of module 26 used JUnit. The Java that runs inside this page can't run the real JavaFX, so Java Arena has a practice version of it, written for this site. It has the classes and methods that these lessons use, under JavaFX's own names, so the code you write here is ordinary JavaFX code. The page then draws the window your program shows. The drawing is approximate: the real JavaFX has its own fonts, colors and sizes.\n\nYou can click the buttons and type in the fields of a window drawn on this page. Each time you do, Java Arena runs your program again from the start, with all your earlier clicks and typing, and draws the window as it is after them. (In this module, clicking a button doesn't do anything yet. Module 49 makes buttons do things.)\n\nOn your own computer, the same code runs with the real JavaFX. Installing it is a separate step, which the MOOC describes in [its section 13.1](https://java-programming.mooc.fi/part-13/1-graphical-user-interfaces). A check runs every model solution of these lessons on the real JavaFX too, and confirms that it shows the same window contents there.\n\n### A program with a window\n\nA bus stop gets a small screen that shows the next bus:\n\n```java\nimport javafx.application.Application;\nimport javafx.scene.Scene;\nimport javafx.scene.control.Label;\nimport javafx.stage.Stage;\n\npublic class Main extends Application {\n\n    @Override\n    public void start(Stage stage) {\n        Label next = new Label(\"Line 4 to Harbor Square: 7:15\");\n        stage.setScene(new Scene(next));\n        stage.setTitle(\"Stop 14\");\n        stage.show();\n    }\n\n    public static void main(String[] args) {\n        launch(Main.class);\n    }\n}\n```\n\n```window\n{\"events\":[],\"window\":{\"windows\":[{\"title\":\"Stop 14\",\"scene\":{\"root\":{\"n\":1,\"type\":\"Label\",\"text\":\"Line 4 to Harbor Square: 7:15\"}}}],\"problems\":[]},\"outline\":\"Window \\\"Stop 14\\\"\\n  Label \\\"Line 4 to Harbor Square: 7:15\\\"\"}\n```\n\nThe examples in these lessons show the window under the code, drawn as the program leaves it, with \"The window as text\" under the drawing (step 2 explains it). Here's the program, part by part:\n\n- `public class Main extends Application`: `Application` is JavaFX's class for a program with windows, and Main inherits from it (module 34). Application is abstract, and its one abstract method is `start`, so Main has to write that method.\n- `public void start(Stage stage)`: a **Stage** is a window. JavaFX makes the program's main window and calls `start` with it. What happens next is up to `start`: this one puts a label into the window, gives the window a title and shows it.\n- `new Label(\"Line 4 to Harbor Square: 7:15\")`: a **label** is a piece of text in a window, for the user to read but not to change.\n- `stage.setScene(new Scene(next))`: a window shows a **Scene**, which holds what's in the window. This scene holds just the label. Step 2 puts more into a scene.\n- `stage.setTitle(\"Stop 14\")` sets the text in the window's title bar.\n- `stage.show()` shows the window. Until then it's hidden: a `start` that never calls `show()` runs to its end, and no window appears.\n- `launch(Main.class)` in `main` starts JavaFX. `launch` is a static method of Application, so Main can call it by its name alone. `Main.class` names the class itself, not an object of it: `launch` creates the Main object, gets the main window ready and calls `start`.\n- Every JavaFX class the program names needs its import. Application, Scene, Label and Stage are in four packages (module 41), all starting with `javafx.`.\n\nJavaFX creates the Main object itself, with the constructor that takes no values. So the class must be `public`, and it must have such a constructor. A class without a constructor of its own has one: Java's default constructor.\n\n### When the program ends\n\nWhere does the program go after `start`? Here each part prints a line, so you can follow it:\n\n```java\nimport javafx.application.Application;\nimport javafx.scene.Scene;\nimport javafx.scene.control.Label;\nimport javafx.stage.Stage;\n\npublic class Main extends Application {\n\n    @Override\n    public void start(Stage stage) {\n        Label next = new Label(\"Line 4 to Harbor Square: 7:15\");\n        stage.setScene(new Scene(next));\n        stage.setTitle(\"Stop 14\");\n        stage.show();\n        System.out.println(\"start: the window is ready\");\n    }\n\n    public static void main(String[] args) {\n        System.out.println(\"main: before launch\");\n        launch(Main.class);\n        System.out.println(\"main: after launch\");\n    }\n}\n```\n\n```window\n{\"events\":[],\"window\":{\"windows\":[{\"title\":\"Stop 14\",\"scene\":{\"root\":{\"n\":1,\"type\":\"Label\",\"text\":\"Line 4 to Harbor Square: 7:15\"}}}],\"problems\":[]},\"outline\":\"Window \\\"Stop 14\\\"\\n  Label \\\"Line 4 to Harbor Square: 7:15\\\"\"}\n```\n\n```output\nmain: before launch\nstart: the window is ready\nmain: after launch\n```\n\n`launch` calls `start`, and then it waits. On your own computer, the window stays open while the user reads, clicks and types, and `launch` returns only when the user closes the window. Then `main` goes on after the call, and the program ends. In Java Arena, a run ends after `start` and the clicks and typing it replays: Java Arena records the window as it is, then closes it for you, so `launch` returns and `main` goes on.\n","task":"The next stop on the line gets a screen too. Fill in the four blanks: Main is a JavaFX application, the window's title is `Stop 15`, it shows the label `Line 4 to Harbor Square: 7:19`, and `main` starts JavaFX. The window it should show is drawn below.\n","kind":"fill","seed":"import javafx.application.Application;\nimport javafx.scene.Scene;\nimport javafx.scene.control.Label;\nimport javafx.stage.Stage;\n\npublic class Main extends [[Application]] {\n\n    @Override\n    public void start(Stage stage) {\n        Label next = new Label(\"Line 4 to Harbor Square: 7:19\");\n        stage.setScene(new Scene(next));\n        stage.[[setTitle]](\"Stop 15\");\n        stage.[[show]]();\n    }\n\n    public static void main(String[] args) {\n        [[launch‖Application.launch]](Main.class);\n    }\n}\n","solution":"import javafx.application.Application;\nimport javafx.scene.Scene;\nimport javafx.scene.control.Label;\nimport javafx.stage.Stage;\n\npublic class Main extends Application {\n\n    @Override\n    public void start(Stage stage) {\n        Label next = new Label(\"Line 4 to Harbor Square: 7:19\");\n        stage.setScene(new Scene(next));\n        stage.setTitle(\"Stop 15\");\n        stage.show();\n    }\n\n    public static void main(String[] args) {\n        launch(Main.class);\n    }\n}\n","hints":["A program with a window extends JavaFX's class for such programs, the one imported from `javafx.application`.","The window's methods are `setTitle` for the title bar and `show` to make it appear. `main` starts JavaFX with `launch(Main.class)`."],"tests":[{"name":"Window","stdin":"","expect":"","hidden":false,"events":[],"window":{"windows":[{"title":"Stop 15","scene":{"root":{"n":1,"type":"Label","text":"Line 4 to Harbor Square: 7:19"}}}],"problems":[]},"outline":"Window \"Stop 15\"\n  Label \"Line 4 to Harbor Square: 7:19\""}],"require":[],"forbid":[],"more":[{"task":"The screen at stop 16 runs without an error, but no window ever appears. Two lines are missing, one in `start` and one in `main`: add them. The window's title is `Stop 16`, and it shows the label `Line 4 to Harbor Square: 7:23`.\n","kind":"code","seed":"import javafx.application.Application;\nimport javafx.scene.Scene;\nimport javafx.scene.control.Label;\nimport javafx.stage.Stage;\n\npublic class Main extends Application {\n\n    @Override\n    public void start(Stage stage) {\n        Label next = new Label(\"Line 4 to Harbor Square: 7:23\");\n        stage.setScene(new Scene(next));\n        stage.setTitle(\"Stop 16\");\n    }\n\n    public static void main(String[] args) {\n\n    }\n}\n","solution":"import javafx.application.Application;\nimport javafx.scene.Scene;\nimport javafx.scene.control.Label;\nimport javafx.stage.Stage;\n\npublic class Main extends Application {\n\n    @Override\n    public void start(Stage stage) {\n        Label next = new Label(\"Line 4 to Harbor Square: 7:23\");\n        stage.setScene(new Scene(next));\n        stage.setTitle(\"Stop 16\");\n        stage.show();\n    }\n\n    public static void main(String[] args) {\n        launch(Main.class);\n    }\n}\n","hints":["Nothing calls `start` yet: JavaFX calls it only after `main` starts JavaFX with `launch(Main.class);`.","Even then, a window stays hidden until `start` calls `stage.show();`."],"tests":[{"name":"Window","stdin":"","expect":"","hidden":false,"events":[],"window":{"windows":[{"title":"Stop 16","scene":{"root":{"n":1,"type":"Label","text":"Line 4 to Harbor Square: 7:23"}}}],"problems":[]},"outline":"Window \"Stop 16\"\n  Label \"Line 4 to Harbor Square: 7:23\""}],"require":[],"forbid":[]},{"task":"Stop 17's screen prints a few lines on its way. A stage that was never given a title has the title `null`. What does the program print?\n","kind":"predict","seed":"import javafx.application.Application;\nimport javafx.scene.Scene;\nimport javafx.scene.control.Label;\nimport javafx.stage.Stage;\n\npublic class Main extends Application {\n\n    @Override\n    public void start(Stage stage) {\n        System.out.println(\"Title: \" + stage.getTitle());\n        stage.setTitle(\"Stop 17\");\n        stage.setScene(new Scene(new Label(\"Line 4 to Harbor Square: 7:27\")));\n        stage.show();\n        System.out.println(\"Title: \" + stage.getTitle());\n    }\n\n    public static void main(String[] args) {\n        System.out.println(\"Starting\");\n        launch(Main.class);\n        System.out.println(\"Closed\");\n    }\n}\n","solution":"import javafx.application.Application;\nimport javafx.scene.Scene;\nimport javafx.scene.control.Label;\nimport javafx.stage.Stage;\n\npublic class Main extends Application {\n\n    @Override\n    public void start(Stage stage) {\n        System.out.println(\"Title: \" + stage.getTitle());\n        stage.setTitle(\"Stop 17\");\n        stage.setScene(new Scene(new Label(\"Line 4 to Harbor Square: 7:27\")));\n        stage.show();\n        System.out.println(\"Title: \" + stage.getTitle());\n    }\n\n    public static void main(String[] args) {\n        System.out.println(\"Starting\");\n        launch(Main.class);\n        System.out.println(\"Closed\");\n    }\n}\n","hints":["`main` runs first. `launch` calls `start`, and `start` runs to its end before `launch` returns.","`launch` returns only when the window is closed, so `Closed` comes after everything `start` prints."],"tests":[{"name":"Output","stdin":"","expect":"Starting\nTitle: null\nTitle: Stop 17\nClosed","hidden":false}],"require":[],"forbid":[],"lines":["Starting","Title: null","Title: Stop 17","Closed"]}]}