{"id":"gui-views-form-and-result","slug":"form-and-result","title":"A form and its result","text":"A common pair of views: a **form**, where the user types something, and a **result**, which shows what the program made of it. The handler of the form's button reads the fields, fills in the result and switches to it.\n\n### A postcard\n\nA holiday app writes postcards. The form has a field for whom the card is for and a text area for the message; the card shows them:\n\n```java\nimport javafx.application.Application;\nimport javafx.scene.Scene;\nimport javafx.scene.control.Button;\nimport javafx.scene.control.Label;\nimport javafx.scene.control.TextArea;\nimport javafx.scene.control.TextField;\nimport javafx.scene.layout.VBox;\nimport javafx.stage.Stage;\n\npublic class Main extends Application {\n\n    @Override\n    public void start(Stage stage) {\n        TextField to = new TextField();\n        to.setPromptText(\"To\");\n        TextArea message = new TextArea();\n        Button preview = new Button(\"Preview\");\n        Scene form = new Scene(new VBox(8, to, message, preview));\n\n        Label greeting = new Label(\"\");\n        Label text = new Label(\"\");\n        Button edit = new Button(\"Edit\");\n        Scene card = new Scene(new VBox(8, greeting, text, edit));\n\n        preview.setOnAction(event -> {\n            greeting.setText(\"Dear \" + to.getText() + \",\");\n            text.setText(message.getText());\n            stage.setScene(card);\n        });\n        edit.setOnAction(event -> stage.setScene(form));\n\n        stage.setScene(form);\n        stage.setTitle(\"Postcard\");\n        stage.show();\n    }\n\n    public static void main(String[] args) {\n        launch(Main.class);\n    }\n}\n```\n\n```window\n{\"events\":[\"type TextField 1 \\\"Ada\\\"\",\"type TextArea 1 \\\"The lake is warm. See you soon!\\\"\",\"click Button \\\"Preview\\\"\"],\"window\":{\"windows\":[{\"title\":\"Postcard\",\"scene\":{\"root\":{\"n\":1,\"type\":\"VBox\",\"spacing\":8,\"children\":[{\"n\":2,\"type\":\"Label\",\"text\":\"Dear Ada,\"},{\"n\":3,\"type\":\"Label\",\"text\":\"The lake is warm. See you soon!\"},{\"n\":4,\"type\":\"Button\",\"text\":\"Edit\",\"onAction\":true}]}}}],\"problems\":[]},\"outline\":\"Window \\\"Postcard\\\"\\n  VBox spacing 8\\n    Label \\\"Dear Ada,\\\"\\n    Label \\\"The lake is warm. See you soon!\\\"\\n    Button \\\"Edit\\\"\"}\n```\n\n- Both scenes are built in `start`. The card's labels start empty: there's nothing to show before the user has written anything.\n- The handler of Preview reads the field and the text area when it runs, so it gets what the user has typed by then (module 49). It sets the card's labels from them, and then shows the card.\n- Edit shows the form again, and the form still holds what was typed, since it's the same scene with the same field and text area. The user can change the message and preview it again.\n\n### Refusing empty input\n\nWith the field empty, the card says `Dear ,`. A form should refuse that and say what's missing, without leaving the form. The form gets an empty label for messages, and the handler checks the field first:\n\n```java\nimport javafx.application.Application;\nimport javafx.scene.Scene;\nimport javafx.scene.control.Button;\nimport javafx.scene.control.Label;\nimport javafx.scene.control.TextArea;\nimport javafx.scene.control.TextField;\nimport javafx.scene.layout.VBox;\nimport javafx.stage.Stage;\n\npublic class Main extends Application {\n\n    @Override\n    public void start(Stage stage) {\n        TextField to = new TextField();\n        to.setPromptText(\"To\");\n        TextArea message = new TextArea();\n        Button preview = new Button(\"Preview\");\n        Label error = new Label(\"\");\n        Scene form = new Scene(new VBox(8, to, message, preview, error));\n\n        Label greeting = new Label(\"\");\n        Label text = new Label(\"\");\n        Button edit = new Button(\"Edit\");\n        Scene card = new Scene(new VBox(8, greeting, text, edit));\n\n        preview.setOnAction(event -> {\n            if (to.getText().trim().isEmpty()) {\n                error.setText(\"Write who the card is for.\");\n            } else {\n                greeting.setText(\"Dear \" + to.getText().trim() + \",\");\n                text.setText(message.getText());\n                error.setText(\"\");\n                stage.setScene(card);\n            }\n        });\n        edit.setOnAction(event -> stage.setScene(form));\n\n        stage.setScene(form);\n        stage.setTitle(\"Postcard\");\n        stage.show();\n    }\n\n    public static void main(String[] args) {\n        launch(Main.class);\n    }\n}\n```\n\n```window\n{\"events\":[\"type TextArea 1 \\\"Greetings from the lake!\\\"\",\"click Button \\\"Preview\\\"\"],\"window\":{\"windows\":[{\"title\":\"Postcard\",\"scene\":{\"root\":{\"n\":1,\"type\":\"VBox\",\"spacing\":8,\"children\":[{\"n\":2,\"type\":\"TextField\",\"text\":\"\",\"promptText\":\"To\"},{\"n\":3,\"type\":\"TextArea\",\"text\":\"Greetings from the lake!\"},{\"n\":4,\"type\":\"Button\",\"text\":\"Preview\",\"onAction\":true},{\"n\":5,\"type\":\"Label\",\"text\":\"Write who the card is for.\"}]}}}],\"problems\":[]},\"outline\":\"Window \\\"Postcard\\\"\\n  VBox spacing 8\\n    TextField \\\"\\\", prompt \\\"To\\\"\\n    TextArea \\\"Greetings from the lake!\\\"\\n    Button \\\"Preview\\\"\\n    Label \\\"Write who the card is for.\\\"\"}\n```\n\n- `trim()` removes the spaces at the ends (module 16), so a field with only spaces counts as empty too.\n- When the field is empty, the handler sets the message and does nothing else: the window stays on the form, and the user can fix it.\n- When the field has a name, the handler empties the message before it switches. Otherwise the old message would still be there when Edit brings the form back.\n\n### Building the result in the handler\n\nThe card above is built once, and the handler only changes the texts of its labels. A handler can also build the result scene itself, each time it runs:\n\n```java\npreview.setOnAction(event -> {\n    Label greeting = new Label(\"Dear \" + to.getText().trim() + \",\");\n    VBox card = new VBox(8, greeting, new Label(message.getText()));\n    stage.setScene(new Scene(card));\n});\n```\n\nEach click makes a new card, with new labels and a new scene. That's handy when the result's shape depends on the input, such as a label for each line the user wrote, and the third challenge below needs it. A view that is built once keeps its state between visits; a view that is built in the handler starts fresh every time.\n","task":"A pet hotel checks pets in. Both scenes are built already, each a VBox with the spacing 8:\n\n- the form: the label `Pet's name`, a text field, the button `Check in` and an empty label for messages\n- the room: an empty label and the button `Next pet`\n\nGive the buttons their handlers:\n\n- **Check in**: when the field is empty (or has only spaces), the message label says `Type the pet's name first.` and the window stays on the form. Otherwise the room's label says which room is ready, like `Room 1 is ready for Rex.` (with the name trimmed), and the window shows the room scene. The rooms are numbered from 1, in the order the pets check in: keep the count in an instance variable of Main.\n- **Next pet**: empties the text field and the message label, and shows the form again.\n\nThe task card shows the window after typing `Rex` and clicking Check in.\n","kind":"code","seed":"import javafx.application.Application;\nimport javafx.scene.Scene;\nimport javafx.scene.control.Button;\nimport javafx.scene.control.Label;\nimport javafx.scene.control.TextField;\nimport javafx.scene.layout.VBox;\nimport javafx.stage.Stage;\n\npublic class Main extends Application {\n\n    @Override\n    public void start(Stage stage) {\n        TextField name = new TextField();\n        Button checkIn = new Button(\"Check in\");\n        Label message = new Label(\"\");\n        Scene form = new Scene(new VBox(8, new Label(\"Pet's name\"), name, checkIn, message));\n\n        Label room = new Label(\"\");\n        Button next = new Button(\"Next pet\");\n        Scene roomScene = new Scene(new VBox(8, room, next));\n\n        stage.setScene(form);\n        stage.setTitle(\"Pet hotel\");\n        stage.show();\n    }\n\n    public static void main(String[] args) {\n        launch(Main.class);\n    }\n}\n","solution":"import javafx.application.Application;\nimport javafx.scene.Scene;\nimport javafx.scene.control.Button;\nimport javafx.scene.control.Label;\nimport javafx.scene.control.TextField;\nimport javafx.scene.layout.VBox;\nimport javafx.stage.Stage;\n\npublic class Main extends Application {\n    private int rooms;\n\n    @Override\n    public void start(Stage stage) {\n        TextField name = new TextField();\n        Button checkIn = new Button(\"Check in\");\n        Label message = new Label(\"\");\n        Scene form = new Scene(new VBox(8, new Label(\"Pet's name\"), name, checkIn, message));\n\n        Label room = new Label(\"\");\n        Button next = new Button(\"Next pet\");\n        Scene roomScene = new Scene(new VBox(8, room, next));\n\n        checkIn.setOnAction(event -> {\n            String pet = name.getText().trim();\n            if (pet.isEmpty()) {\n                message.setText(\"Type the pet's name first.\");\n            } else {\n                this.rooms++;\n                room.setText(\"Room \" + this.rooms + \" is ready for \" + pet + \".\");\n                stage.setScene(roomScene);\n            }\n        });\n        next.setOnAction(event -> {\n            name.clear();\n            message.setText(\"\");\n            stage.setScene(form);\n        });\n\n        stage.setScene(form);\n        stage.setTitle(\"Pet hotel\");\n        stage.show();\n    }\n\n    public static void main(String[] args) {\n        launch(Main.class);\n    }\n}\n","hints":["In Check in's handler, read the name once: `String pet = name.getText().trim();`. If `pet.isEmpty()`, set the message; otherwise count the room, set the room's label and call `stage.setScene(roomScene)`.","The room number changes at each check-in, so it can't be a local variable of `start`: declare `private int rooms;` in the class and add one with `this.rooms++` before you use it."],"tests":[{"name":"Test 1","stdin":"","expect":"","hidden":false,"events":["type TextField 1 \"Rex\"","click Button \"Check in\""],"window":{"windows":[{"title":"Pet hotel","scene":{"root":{"n":1,"type":"VBox","spacing":8,"children":[{"n":2,"type":"Label","text":"Room 1 is ready for Rex."},{"n":3,"type":"Button","text":"Next pet","onAction":true}]}}}],"problems":[]},"outline":"Window \"Pet hotel\"\n  VBox spacing 8\n    Label \"Room 1 is ready for Rex.\"\n    Button \"Next pet\""},{"name":"Test 2","stdin":"","expect":"","hidden":true,"events":["click Button \"Check in\""],"window":{"windows":[{"title":"Pet hotel","scene":{"root":{"n":1,"type":"VBox","spacing":8,"children":[{"n":2,"type":"Label","text":"Pet's name"},{"n":3,"type":"TextField","text":""},{"n":4,"type":"Button","text":"Check in","onAction":true},{"n":5,"type":"Label","text":"Type the pet's name first."}]}}}],"problems":[]},"outline":"Window \"Pet hotel\"\n  VBox spacing 8\n    Label \"Pet's name\"\n    TextField \"\"\n    Button \"Check in\"\n    Label \"Type the pet's name first.\""},{"name":"Test 3","stdin":"","expect":"","hidden":true,"events":["type TextField 1 \"Bella\"","click Button \"Check in\"","click Button \"Next pet\"","type TextField 1 \"  Max  \"","click Button \"Check in\""],"window":{"windows":[{"title":"Pet hotel","scene":{"root":{"n":1,"type":"VBox","spacing":8,"children":[{"n":2,"type":"Label","text":"Room 2 is ready for Max."},{"n":3,"type":"Button","text":"Next pet","onAction":true}]}}}],"problems":[]},"outline":"Window \"Pet hotel\"\n  VBox spacing 8\n    Label \"Room 2 is ready for Max.\"\n    Button \"Next pet\""},{"name":"Test 4","stdin":"","expect":"","hidden":true,"events":["type TextField 1 \"   \"","click Button \"Check in\"","set TextField 1 \"Kiki\"","click Button \"Check in\"","click Button \"Next pet\""],"window":{"windows":[{"title":"Pet hotel","scene":{"root":{"n":1,"type":"VBox","spacing":8,"children":[{"n":2,"type":"Label","text":"Pet's name"},{"n":3,"type":"TextField","text":""},{"n":4,"type":"Button","text":"Check in","onAction":true},{"n":5,"type":"Label","text":""}]}}}],"problems":[]},"outline":"Window \"Pet hotel\"\n  VBox spacing 8\n    Label \"Pet's name\"\n    TextField \"\"\n    Button \"Check in\"\n    Label \"\""},{"name":"Test 5","stdin":"","expect":"","hidden":true,"events":["type TextField 1 \"Bella\"","click Button \"Check in\"","click Button \"Next pet\"","click Button \"Check in\""],"window":{"windows":[{"title":"Pet hotel","scene":{"root":{"n":1,"type":"VBox","spacing":8,"children":[{"n":2,"type":"Label","text":"Pet's name"},{"n":3,"type":"TextField","text":""},{"n":4,"type":"Button","text":"Check in","onAction":true},{"n":5,"type":"Label","text":"Type the pet's name first."}]}}}],"problems":[]},"outline":"Window \"Pet hotel\"\n  VBox spacing 8\n    Label \"Pet's name\"\n    TextField \"\"\n    Button \"Check in\"\n    Label \"Type the pet's name first.\""}],"require":[],"forbid":[],"more":[{"task":"A restaurant books tables online. The form is a VBox with the spacing 8 holding the label `Guests`, a text field, the button `Book` and an empty label for messages. The booked scene is a VBox with the spacing 8 holding an empty label and the button `Change`. Both are built already: write the handlers.\n\n**Book** reads the number of guests from the field and checks it, in this order:\n\n- not a whole number (`Integer.valueOf` throws a NumberFormatException, module 42): the message is `Type the number of guests in digits.`\n- below 1: `At least 1 guest, please.`\n- above 8: `For more than 8 guests, please call us.`\n- otherwise the booked scene's label says `A table for 4 is booked.` (with the number), the message label is emptied, and the window shows the booked scene.\n\nIn the first three cases the window stays on the form. **Change** shows the form again, with the number still in the field. The task card shows the window after typing `4` and clicking Book.\n","kind":"code","seed":"import javafx.application.Application;\nimport javafx.scene.Scene;\nimport javafx.scene.control.Button;\nimport javafx.scene.control.Label;\nimport javafx.scene.control.TextField;\nimport javafx.scene.layout.VBox;\nimport javafx.stage.Stage;\n\npublic class Main extends Application {\n\n    @Override\n    public void start(Stage stage) {\n        TextField guests = new TextField();\n        Button book = new Button(\"Book\");\n        Label message = new Label(\"\");\n        Scene form = new Scene(new VBox(8, new Label(\"Guests\"), guests, book, message));\n\n        Label booked = new Label(\"\");\n        Button change = new Button(\"Change\");\n        Scene bookedScene = new Scene(new VBox(8, booked, change));\n\n        stage.setScene(form);\n        stage.setTitle(\"Table booking\");\n        stage.show();\n    }\n\n    public static void main(String[] args) {\n        launch(Main.class);\n    }\n}\n","solution":"import javafx.application.Application;\nimport javafx.scene.Scene;\nimport javafx.scene.control.Button;\nimport javafx.scene.control.Label;\nimport javafx.scene.control.TextField;\nimport javafx.scene.layout.VBox;\nimport javafx.stage.Stage;\n\npublic class Main extends Application {\n\n    @Override\n    public void start(Stage stage) {\n        TextField guests = new TextField();\n        Button book = new Button(\"Book\");\n        Label message = new Label(\"\");\n        Scene form = new Scene(new VBox(8, new Label(\"Guests\"), guests, book, message));\n\n        Label booked = new Label(\"\");\n        Button change = new Button(\"Change\");\n        Scene bookedScene = new Scene(new VBox(8, booked, change));\n\n        book.setOnAction(event -> {\n            try {\n                int count = Integer.valueOf(guests.getText());\n                if (count < 1) {\n                    message.setText(\"At least 1 guest, please.\");\n                } else if (count > 8) {\n                    message.setText(\"For more than 8 guests, please call us.\");\n                } else {\n                    booked.setText(\"A table for \" + count + \" is booked.\");\n                    message.setText(\"\");\n                    stage.setScene(bookedScene);\n                }\n            } catch (NumberFormatException e) {\n                message.setText(\"Type the number of guests in digits.\");\n            }\n        });\n        change.setOnAction(event -> stage.setScene(form));\n\n        stage.setScene(form);\n        stage.setTitle(\"Table booking\");\n        stage.show();\n    }\n\n    public static void main(String[] args) {\n        launch(Main.class);\n    }\n}\n","hints":["Put the reading and the checks in a `try` block: `int count = Integer.valueOf(guests.getText());` jumps to `catch (NumberFormatException e)` when the text isn't a whole number, and that's where the first message is set.","Inside the `try`, an `if`, `else if`, `else` chain handles below 1, above 8, and the booking. Only the last branch empties the message and calls `stage.setScene(bookedScene)`."],"tests":[{"name":"Test 1","stdin":"","expect":"","hidden":false,"events":["type TextField 1 \"4\"","click Button \"Book\""],"window":{"windows":[{"title":"Table booking","scene":{"root":{"n":1,"type":"VBox","spacing":8,"children":[{"n":2,"type":"Label","text":"A table for 4 is booked."},{"n":3,"type":"Button","text":"Change","onAction":true}]}}}],"problems":[]},"outline":"Window \"Table booking\"\n  VBox spacing 8\n    Label \"A table for 4 is booked.\"\n    Button \"Change\""},{"name":"Test 2","stdin":"","expect":"","hidden":true,"events":["type TextField 1 \"four\"","click Button \"Book\""],"window":{"windows":[{"title":"Table booking","scene":{"root":{"n":1,"type":"VBox","spacing":8,"children":[{"n":2,"type":"Label","text":"Guests"},{"n":3,"type":"TextField","text":"four"},{"n":4,"type":"Button","text":"Book","onAction":true},{"n":5,"type":"Label","text":"Type the number of guests in digits."}]}}}],"problems":[]},"outline":"Window \"Table booking\"\n  VBox spacing 8\n    Label \"Guests\"\n    TextField \"four\"\n    Button \"Book\"\n    Label \"Type the number of guests in digits.\""},{"name":"Test 3","stdin":"","expect":"","hidden":true,"events":["type TextField 1 \"0\"","click Button \"Book\""],"window":{"windows":[{"title":"Table booking","scene":{"root":{"n":1,"type":"VBox","spacing":8,"children":[{"n":2,"type":"Label","text":"Guests"},{"n":3,"type":"TextField","text":"0"},{"n":4,"type":"Button","text":"Book","onAction":true},{"n":5,"type":"Label","text":"At least 1 guest, please."}]}}}],"problems":[]},"outline":"Window \"Table booking\"\n  VBox spacing 8\n    Label \"Guests\"\n    TextField \"0\"\n    Button \"Book\"\n    Label \"At least 1 guest, please.\""},{"name":"Test 4","stdin":"","expect":"","hidden":true,"events":["type TextField 1 \"12\"","click Button \"Book\""],"window":{"windows":[{"title":"Table booking","scene":{"root":{"n":1,"type":"VBox","spacing":8,"children":[{"n":2,"type":"Label","text":"Guests"},{"n":3,"type":"TextField","text":"12"},{"n":4,"type":"Button","text":"Book","onAction":true},{"n":5,"type":"Label","text":"For more than 8 guests, please call us."}]}}}],"problems":[]},"outline":"Window \"Table booking\"\n  VBox spacing 8\n    Label \"Guests\"\n    TextField \"12\"\n    Button \"Book\"\n    Label \"For more than 8 guests, please call us.\""},{"name":"Test 5","stdin":"","expect":"","hidden":true,"events":["click Button \"Book\""],"window":{"windows":[{"title":"Table booking","scene":{"root":{"n":1,"type":"VBox","spacing":8,"children":[{"n":2,"type":"Label","text":"Guests"},{"n":3,"type":"TextField","text":""},{"n":4,"type":"Button","text":"Book","onAction":true},{"n":5,"type":"Label","text":"Type the number of guests in digits."}]}}}],"problems":[]},"outline":"Window \"Table booking\"\n  VBox spacing 8\n    Label \"Guests\"\n    TextField \"\"\n    Button \"Book\"\n    Label \"Type the number of guests in digits.\""},{"name":"Test 6","stdin":"","expect":"","hidden":true,"events":["type TextField 1 \"9\"","click Button \"Book\"","set TextField 1 \"8\"","click Button \"Book\"","click Button \"Change\""],"window":{"windows":[{"title":"Table booking","scene":{"root":{"n":1,"type":"VBox","spacing":8,"children":[{"n":2,"type":"Label","text":"Guests"},{"n":3,"type":"TextField","text":"8"},{"n":4,"type":"Button","text":"Book","onAction":true},{"n":5,"type":"Label","text":""}]}}}],"problems":[]},"outline":"Window \"Table booking\"\n  VBox spacing 8\n    Label \"Guests\"\n    TextField \"8\"\n    Button \"Book\"\n    Label \"\""},{"name":"Test 7","stdin":"","expect":"","hidden":true,"events":["type TextField 1 \"1\"","click Button \"Book\""],"window":{"windows":[{"title":"Table booking","scene":{"root":{"n":1,"type":"VBox","spacing":8,"children":[{"n":2,"type":"Label","text":"A table for 1 is booked."},{"n":3,"type":"Button","text":"Change","onAction":true}]}}}],"problems":[]},"outline":"Window \"Table booking\"\n  VBox spacing 8\n    Label \"A table for 1 is booked.\"\n    Button \"Change\""}],"require":[],"forbid":[]},{"task":"A list of errands. The form is a VBox with the spacing 8 holding a text area, the button `Make list` and an empty label for messages; it's built already. The user writes the day's errands in the text area, one per line.\n\n**Make list** builds a new scene, each time it's clicked: a VBox with the spacing 4 and no padding, holding for each line of the text area a label with `[ ] ` and the line, trimmed, like `[ ] Buy stamps`, in the order of the lines, and at the end a new button `Edit`. Lines that are empty, or have only spaces, get no label. Edit shows the form again. When it builds the list, Make list also empties the message label, so that no old message is left when Edit brings the form back.\n\nWhen no line has any text, Make list stays on the form and the message label says `Write at least one errand.`\n\n`split(\"\\n\")` splits the text into its lines. The task card shows the window after writing `Buy stamps`, `Return the books`, an empty line and `Fix the bike`, and clicking Make list.\n","kind":"code","seed":"import javafx.application.Application;\nimport javafx.scene.Scene;\nimport javafx.scene.control.Button;\nimport javafx.scene.control.Label;\nimport javafx.scene.control.TextArea;\nimport javafx.scene.layout.VBox;\nimport javafx.stage.Stage;\n\npublic class Main extends Application {\n\n    @Override\n    public void start(Stage stage) {\n        TextArea errands = new TextArea();\n        Button make = new Button(\"Make list\");\n        Label message = new Label(\"\");\n        Scene form = new Scene(new VBox(8, errands, make, message));\n\n        stage.setScene(form);\n        stage.setTitle(\"Errands\");\n        stage.show();\n    }\n\n    public static void main(String[] args) {\n        launch(Main.class);\n    }\n}\n","solution":"import javafx.application.Application;\nimport javafx.scene.Scene;\nimport javafx.scene.control.Button;\nimport javafx.scene.control.Label;\nimport javafx.scene.control.TextArea;\nimport javafx.scene.layout.VBox;\nimport javafx.stage.Stage;\n\npublic class Main extends Application {\n\n    @Override\n    public void start(Stage stage) {\n        TextArea errands = new TextArea();\n        Button make = new Button(\"Make list\");\n        Label message = new Label(\"\");\n        Scene form = new Scene(new VBox(8, errands, make, message));\n\n        make.setOnAction(event -> {\n            VBox list = new VBox(4);\n            for (String line : errands.getText().split(\"\\n\")) {\n                if (!line.trim().isEmpty()) {\n                    list.getChildren().add(new Label(\"[ ] \" + line.trim()));\n                }\n            }\n            if (list.getChildren().isEmpty()) {\n                message.setText(\"Write at least one errand.\");\n            } else {\n                Button edit = new Button(\"Edit\");\n                edit.setOnAction(click -> stage.setScene(form));\n                list.getChildren().add(edit);\n                message.setText(\"\");\n                stage.setScene(new Scene(list));\n            }\n        });\n\n        stage.setScene(form);\n        stage.setTitle(\"Errands\");\n        stage.show();\n    }\n\n    public static void main(String[] args) {\n        launch(Main.class);\n    }\n}\n","hints":["In Make list's handler, make a new `VBox(4)` and go through `errands.getText().split(\"\\n\")` with a for-each loop, adding a `new Label(\"[ ] \" + line.trim())` for each line whose trimmed text isn't empty.","If the VBox got no labels, set the message. Otherwise add a new Edit button whose handler calls `stage.setScene(form)`, and show `new Scene(list)`. The inner lambda needs a parameter name other than `event`, such as `click`, since `event` is already the outer lambda's."],"tests":[{"name":"Test 1","stdin":"","expect":"","hidden":false,"events":["set TextArea 1 \"Buy stamps\\nReturn the books\\n\\nFix the bike\"","click Button \"Make list\""],"window":{"windows":[{"title":"Errands","scene":{"root":{"n":1,"type":"VBox","spacing":4,"children":[{"n":2,"type":"Label","text":"[ ] Buy stamps"},{"n":3,"type":"Label","text":"[ ] Return the books"},{"n":4,"type":"Label","text":"[ ] Fix the bike"},{"n":5,"type":"Button","text":"Edit","onAction":true}]}}}],"problems":[]},"outline":"Window \"Errands\"\n  VBox spacing 4\n    Label \"[ ] Buy stamps\"\n    Label \"[ ] Return the books\"\n    Label \"[ ] Fix the bike\"\n    Button \"Edit\""},{"name":"Test 2","stdin":"","expect":"","hidden":true,"events":["click Button \"Make list\""],"window":{"windows":[{"title":"Errands","scene":{"root":{"n":1,"type":"VBox","spacing":8,"children":[{"n":2,"type":"TextArea","text":""},{"n":3,"type":"Button","text":"Make list","onAction":true},{"n":4,"type":"Label","text":"Write at least one errand."}]}}}],"problems":[]},"outline":"Window \"Errands\"\n  VBox spacing 8\n    TextArea \"\"\n    Button \"Make list\"\n    Label \"Write at least one errand.\""},{"name":"Test 3","stdin":"","expect":"","hidden":true,"events":["set TextArea 1 \"  \\n \\n\"","click Button \"Make list\""],"window":{"windows":[{"title":"Errands","scene":{"root":{"n":1,"type":"VBox","spacing":8,"children":[{"n":2,"type":"TextArea","text":"  \n \n"},{"n":3,"type":"Button","text":"Make list","onAction":true},{"n":4,"type":"Label","text":"Write at least one errand."}]}}}],"problems":[]},"outline":"Window \"Errands\"\n  VBox spacing 8\n    TextArea \"  \\n \\n\"\n    Button \"Make list\"\n    Label \"Write at least one errand.\""},{"name":"Test 4","stdin":"","expect":"","hidden":true,"events":["set TextArea 1 \"  Water the plants  \"","click Button \"Make list\"","click Button \"Edit\"","type TextArea 1 \"\\nCall Grandma\\nPay the rent\"","click Button \"Make list\""],"window":{"windows":[{"title":"Errands","scene":{"root":{"n":1,"type":"VBox","spacing":4,"children":[{"n":2,"type":"Label","text":"[ ] Water the plants"},{"n":3,"type":"Label","text":"[ ] Call Grandma"},{"n":4,"type":"Label","text":"[ ] Pay the rent"},{"n":5,"type":"Button","text":"Edit","onAction":true}]}}}],"problems":[]},"outline":"Window \"Errands\"\n  VBox spacing 4\n    Label \"[ ] Water the plants\"\n    Label \"[ ] Call Grandma\"\n    Label \"[ ] Pay the rent\"\n    Button \"Edit\""},{"name":"Test 5","stdin":"","expect":"","hidden":true,"events":["click Button \"Make list\"","type TextArea 1 \"Get a haircut\"","click Button \"Make list\"","click Button \"Edit\""],"window":{"windows":[{"title":"Errands","scene":{"root":{"n":1,"type":"VBox","spacing":8,"children":[{"n":2,"type":"TextArea","text":"Get a haircut"},{"n":3,"type":"Button","text":"Make list","onAction":true},{"n":4,"type":"Label","text":""}]}}}],"problems":[]},"outline":"Window \"Errands\"\n  VBox spacing 8\n    TextArea \"Get a haircut\"\n    Button \"Make list\"\n    Label \"\""}],"require":[],"forbid":[]}]}