600 likes | 635 Views
GUI in Java. Using JavaFX Applications. Outline. What is GUI Creating an Application Window controls and layouts (arrangements; panes) Activating Buttons in an Application Window making it do something What are polymorphism and inheritance?. What is a GUI?. Graphical User Interface
E N D
GUI in Java Using JavaFX Applications
Outline • What is GUI • Creating an Application Window • controls and layouts (arrangements; panes) • Activating Buttons in an Application Window • making it do something • What are polymorphism and inheritance?
What is a GUI? • Graphical User Interface • a graphical way to use the program • windows, icons, menus, pointing (WIMP) • Lots less typing for theuser • Lots less things for themto remember • see options by looking File Edit Help _ X Open Save —— Exit Mrph Blah Yuck Eeew Gross Dpbl Xvgl
Differences • Different kinds of objects involved • Scanner in console • text fields and buttons in app • Interaction is different • console needs you to enter numbers in order • can change numbers and recalculate in app
Similarities • Purpose of program is the same • calculate a final course grade for this course • Input is the same • user provides component grades • assignments, labs, tests, exam • Steps for doing calculation the same • read the numbers • calculate the result • show the result
A Slightly Simpler GUI • Program opens up a window like this: • What can we do with it? • can enter numbers into the first and second number boxes • can click the “Add” button to put their sum into the result box • can click the “Done” button to end the program
Creating an Application • New Project > JavaFX > JavaFX Application • We will call our program AdderApplication • NetBeans generates an Application • you can run it right away: • Click the button • “Hello World!ˮ printed inoutput window
Application Code • It’s a bit complicated! • import commands: • extends keyword • I’ll explain this soon • start method • lots of code in it • main method • one line of code • Most code is in the start method
The Method main • Applications have a main method public static void main(String[] args) { launch(args);} • don’t change it! • starts the GUI by calling launch method • more about the launch method later
The Method start • Sets up the GUI @Override public void start(Stage primaryStage) {Pane pane = makePane();Scene scene = new Scene(pane);primaryStage.setScene(scene);primaryStage.setTitle(MY_TITLE);primaryStage.show(); } • you can use this version of start • need to write makePane() and define MY_TITLE
Scene is the inside of the window Stage has a Scene in it Stage and Scene • Two data types in JavaFX: • Stage is a window • primaryStage is the main window
Pane is the arrangement of items in the window Scene has a Pane in it Scene and Pane • Pane is another data type in JavaFX: • Scene is inside of the window
Controls are the bits the user interacts with Pane has controls in it Pane and Controls • Lots of controls in JavaFX: • Pane is the arrangementof items in the window
Our Controls • We have three kinds of controls in our Scene • Labels: bits of text that don’t do anything • TextFields: boxes for users to type in • Buttons: things for users to click • something should happen after they get clicked • we’ll worry about that later • Other applications may need other things • CheckBoxes, RadioButtons, MenuBar, Menus, …
Creating a Label • Like Scanners, need to be imported, created • import javafx.scene.control.Label; • no other kind of Label will work with an Application • tell constructor the text for the new Label Label instructions; instructions = new Label("Enter two numbers to add up:"); Label num1Label = new Label("First Number:"); Label num2Label = new Label("Second Number:"); Label result = new Label("Result:");
Creating a TextField • Same as for Label • import javafx.scene.control.TextField; • no other kind of TextField will work here • tell constructor text to start in TextField • or leave blank if the field starts blank TextField num1Field = new TextField("0"); TextField num2Field = new TextField("0"); TextFieldresultField = new TextField("0"); • note that text is a String, not an int or double
Creating a Button • Same as for Label and TextField: • import javafx.scene.control.Button; • no other kind of Button will work here • tell constructor text to put in Button Button addButton = new Button("Add"); Button doneButton = new Button("Done");
Creating a Look for Controls • We have a lot of controls in our window • Labels, TextFields, Buttons • Want them to look alike • and default sizes are pretty small • Make a method to create and style them Label result = makeLabel("result"); TextField num1Field = makeNumberField("0"); Button addButton = makeButton("Add");
Styling a Control • Can set multiple properties for a control • font and alignment, for example • need to import Font and Pos • want number fields to be 18-point monospaced, and right-aligned private static TextFieldmakeNumberField(String text) {TextField result = new TextField(text);result.setFont(new Font("Monospaced", FONT_SIZE));result.setAlignment(Pos.CENTER_RIGHT); return result;}
Exercises • Write the methods makeButton and makeLabel • they should use a FONT_SIZE font • don't bother setting an alignment • Buttons will be centred, which is good • Labels will be left-aligned, which is good
Our Arrangement • Laid out as a grid: • two columns, five rows, numbered from zero • JavaFX has a class called GridPane Column 0 1 Row 0 1 2 3 4
Creating a Grid Layout • Create the GridPane GridPane root = new GridPane(); • Add each object to its column and row root.add(instructions, 0, 0); root.add(num1Label, 0, 1); root.add(num1Field, 1, 1); … root.add(addButton, 0, 4); root.add(doneButton, 1, 4); Need to import javafx.scene.layout.GridPane;
Spreading over Multiple Cells • Make instructions go all the way across the top • currently stuck in top-left cell of grid (0, 0) • want to make it go across two columns • but still only one row • add number of columns and rows to add(…) root.add(instructions, 0, 0, 2, 1);// 2 columns, 1 row
Styling the GridPane • Add space around the outside root.addSetPadding(new Insets(15, 25, 15, 25)); • need to import javafx.geometry.Insets • Add space between rows and columns root.setHgap(15); root.setVgap(10); • Center buttons GridPane.setHalignment(addButton, HPos.CENTER);
Making it Work • Clicking the Buttons does nothing • no action associated with the button • Sample application had an example: btn.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { System.out.println("Hello World!"); } }); • We can make that simpler!
Use Lambda Expression • NetBeans has a yellow light-bulb suggestion: • This … can be changed into a lambda expression • Do that! It’ll look much simpler! btn.setOnAction((ActionEvent event) -> { System.out.println("Hello World!"); }); • quicker and easier magic formula! • uses hyphen + greater-than sign as an arrow • put what you want the Button to do in the braces
The done Button’s Action • Want to end the program • could use System.exit(0); • better to use Platform.exit(); • for later, when you make this Application Awesome! doneButton.setOnAction((ActionEvent event) -> { Platform.exit(); }); • need to import javafx.application.Platform • also javafx.event.ActionEvent, if you deleted it before • NOTjava.awt.ActionEvent!
The add Button’s Action • Needs to add the numbers from the two input TextFields and put answer in result TextField • TextFields give you a String, not an int/double String num1Text = num1Field.getText(); • need to translate into an int: Integer.parseInt int num1 = Integer.parseInt(num1Text); • then need to change int to String: Integer.toString String sumText = Integer.toString(sum); • and put that String into the result resultField.setText(sumText);
The add Button’s Action • All together: addButton.setOnAction((ActionEvent event) -> { int num1, num2, sum; String num1Text, num2Text, sumText; num1Text = num1Field.getText(); num2Text = num2Field.getText(); num1 = Integer.parseInt(num1Text); num2 = Integer.parseInt(num2Text); sum = num1 + num2; sumText = Integer.toString(sum); resultField.setText(sumText); });
The add Button’s Action • Better to put all that in a method • method needs to be told the three TextFields addButton.setOnAction((ActionEvent event) -> { addUp(num1Field, num2Field, resultField); }); • addUp method created in AdderApplication • does all the things we did on the previous slide • Run the program and watch it add up numbers
Weird Stuff • Stuff we used but didn’t explain: public class AdderApplication extends Application { public static void main(String[] args) { launch(args);} private Pane makePane() {GridPane root = new GridPane(); … return root;} } What does this mean? Where is launch? How can we return a GridPane when it says we’re going to return a Pane?
Inheritance • Inheritance • a way of using code that’s been written before • without copying it (copying is bad) • being a special version of another class • a self-driving car is a special kind of car • or a more specific kind of another class • a Nova Scotian is a specific kind of Canadian • Explains all the stuff on previous slide
Special Kinds of Panes • More than one kind of Pane in JavaFX • GridPane is one • StackPane is another • also BorderPane, FlowPane, HBox and VBox • Classes arranged in a hierarchy • GridPane is a subclass of Pane • Pane is the superclass of GridPane
JavaFX Pane Hierarchy (part) BorderPane Pane is the superclass FlowPane Pane GridPane These are the subclasses Arrows point from subclass to superclass HBox StackPane VBox
Has vs. Is • A Scene has a Pane in it • a Pane is a part of a Scene • A GridPaneis a Pane • it’s not in a Pane • it’s a special kind of Pane • The Pane a Scene has can be a GridPane • this Scene has a GridPane in it • the other Scene has a StackPane in it
“Is a” Means… • A GridPane is a Pane • any method that returns a Pane … • such as makePane() • … can return a GridPane … • … because a GridPaneis a Pane • any method that expects to be given a Pane … • such as the Scene constructor • … can be given a GridPane … • … because a GridPaneis a Pane
Variables and Objects • Scanner object goes into a Scanner variable Scanner kbd = new Scanner(System.in); • Pane object goes into a Pane variable Pane pane1 = new Pane(); • But GridPanes are Panes, so… Pane pane2 = new GridPane(); • NOTE: Can’t go the other way! • a Pane isn’t necessarily a GridPane GridPane pane3 = new Pane();
Declaring Inheritance • Need to tell Java about inheritance • my class inherits from this other class • e.g. GridPane inherits from Pane • Use the extends keyword public class GridPane extends Pane { • says that GridPane is a Pane public class AdderApplication extends Application { • says …?
The Application Class • Application class knows how to do GUIs • AdderApplication extends Application tells Java that our AdderApplication is a GUI • in particular, an Application • (there are other kinds of GUIs) • (no GUI is not a data type in Java) • Better yet – inheritance gets you stuff • AdderApplication inherits methods
Inheriting Methods • If B extends A, then B is an A • Thus, B can do anything A can do • because B is an A • Our AdderApplication can do anything an Application can do • because it is an Application • The things A can do are its public methods • and B gets all of them!
Inheriting Methods public class A { public void doThis() { System.out.println(“Hello!”); } } public class B extends A {} public class MyProg { public static void main(String[] args) { A anA = new A(); B aB = new B(); anA.doThis(); // prints Hello! aB.doThis(); // prints Hello! (!) } }
Adding Methods to Subclass • B is a subclass of A (B extends A) • B can do anything A can do • because B is a A • But B could do more • just have to tell Java extra things B can do • declare them just like any other method
Adding Methods public class A { public void doThis() { System.out.println(“Hello!”); } } public class B extends A { public void doThat() { System.out.println(“Bye!”); } } anA.doThis(); // prints “Hello!” aB.doThis(); // prints “Hello!” aB.doThat(); // prints “Bye!” anA.doThat(); // error!
Inheriting Application Methods • Every public method that Application has… • …AdderApplication gets (automatically) • don’t even need to say you want it! • Application has a launch method … • knows how to start up a GUI • … so AdderApplication has it, too! • it’s static, so we can call it from main • we do, and it starts up the GUI
The launch and start Methods • The launch method calls the start method • start is the method we use to build our GUI • every Application must have a start method • more about this later • In order to get our GUI to do what we want, we need to write our own start method • start method needs to declared correctly • use @Override notation to get Java to check • just like the toString method we saw before
Adding Methods • Of course, we add our own methods to our AdderApplication • makePane, makeLabel, makeNumberField, … • We call them when we need them • from our start method • also in the addButton event handler • more on that soon
Inheritance in JavaFX • JavaFX uses a lot of inheritance • there is a data type called Control • a TextField is a Control • a Label is a Control • a Button is a Control • But it’s much more complicated than that! • lots more types of controls • arranged in a deep hierarchy
JavaFX Control Hierarchy (part) MenuBar TextInputControl TextField Control PasswordField Label Labelled ButtonBase Arrows point from subclass to superclass A Button is a ButtonBase A ButtonBase is a Labelled A Labelled is a Control Button CheckBox RadioButton ToggleButton
Inheriting from Subclasses? • You can inherit from classes that inherit • a TextField is a TextInputControl • a TextInputControl is a Control • thus a TextFieldis a Control • Inherit all your super-class’s methods … • … including all the methods it inherited • TextField inherits all Control’s public methods TextInputControl Control TextField