Download presentation
Presentation is loading. Please wait.
1
Lecture 18 CS
2
GUIs Other than JOptionPane methods, everything we have done so far has involved command-line input and output. Practically all consumer-oriented software today uses Graphical User Interfaces (GUIs, pronounced "gooeys") An attractive and easy to use UI makes a bigger impression on the typical consumer than elegant program logic or even performance does. Consumers buy sizzle, not steak. Bill Gates is the richest person in the world, but Richard Stallman can’t afford a razor Java is heavily used in several types of GUI-based applications Web apps Android apps BluRay interface
3
GUIs When you started taking CS classes, you probably expected to use GUIs right away. There are several reasons we don’t do it that way Traditions in the field; most instructors and textbook authors started programming before GUIs were popular To the CS way of thinking, there is no point in having a great GUI if you don’t know how to program any functionality GUI design shades into graphic arts and psychology rather than strictly CS and requires different skills Finally, modern GUI construction uses OOP principles heavily, so you have to learn those first
4
GUIs GUIs are usually built using frameworks or toolkits that provide customizable GUI components. You do not have to write the code to define what a dialog box or a radio button looks like. You will call methods of GUI classes that have already done this and send the arguments that define the specifics you want. GUIs are introduced in Java using the Java FX library. JavaFX code is platform-independent, but your GUIs may look a little different from platform to platform. The basic principles of JavaFX are very similar in most other types of GUI programming you will encounter. When you learn server-side web programming in CS320, or Android programming, you will build on this material.
5
JavaFX JavaFX is designed for networked applications.
Until recently, Java GUI construction was usually taught using Swing, a toolkit for desktop GUI apps. Java does not have much market share in the desktop app market, so Swing has become outmoded.
6
JavaFX If you use Eclipse with JavaFX on the computers in our labs, include a main() like this one: public static void main(String[] args){ Application.launch(args); } On your own computer, you can install the Eclipse add-on e(fx)clipse. With this, main() is unnecessary for JavaFX. You will also not need main() to compile and run from a command line in current versions of Java. In the lab, you may also need to set the build path to use an “alternate JRE.” Right click on the project, then choose build path/ configure build path / libraries. Highlight the JRE System Library, click Edit, then choose “alternate JRE.” Choose a JRE8 (or later) JRE. This is just a bug in Eclipse.
7
JavaFX On your own computer, install e(fx)clipse, a plug in for Eclipse, if necessary. If you do not see the “JavaFX application” option when creating a project or if you get an error message in the line of code that includes “extends Application”, this is probably the problem. I needed to add e(fx)clipse with Eclipse Luna in Windows 8.1, but the Eclipse Kepler package for Fedora Linux 20 included it already. Your results may vary. Here is how to add a plug-in to Eclipse in Windows. If these instructions don’t work in your OS, look for instructions on Stack Overflow. If that doesn’t work, ask me in the lab or come to my office hours. Help/Find New Software Enter search text (“JavaFX”) Find the software you want If an “install” button is present, click it. This should work for e(fx)clipse. Otherwise, follow a link from the search results for download and install instructions
8
JavaFX start(Stage primaryStage) is the starting point of a JavaFX application. Your start() overrides one from javafx.application.Application primaryStage is created automatically Even with e(fx)clipse, Eclipse does not always see start() correctly as a starting point. You may have to type the name of the package and class in Run Configurations:
9
JavaFX There are many types of UI components, which are implemented as classes in the JavaFX API. I will describe a few of them, but mostly just use them when necessary. From this point on, we will be using too many API classes to explain them all in advance. You will soon learn how to figure out how to use classes you see in examples, based on conventions and documentation; this is a key skill in OOP.
10
JavaFX The window in which JavaFX GUI components are placed is an object of class Stage. JavaFX developers are afflicted with the Java habit of giving things campy names. Don’t say I didn’t warn you. Stage has many setter methods like setTitle() and setWidth(). Experiment with these as you work. Individual UI components, like Labels and Buttons, are called controls You can set up multiple Stages and swap them in and out; we will cover that later.
11
JavaFX Each Stage has a Scene which holds the controls
You can put controls like buttons directly into the Scene, but most Scenes hold objects of subclasses of Pane. These serve as containers for the controls. The first Pane we will try out is the StackPane. This is a container which stacks the components it holds in back-to-front order. The constructor for Scene takes a parameter that is a reference to the root of the scene graph, eg the Stack Pane. You can add UI controls directly to the StackPane but there are other containers you can use to get more control over layout. Once you have the Scene constructed, use Stage.setScene() to make the particular Stage use the Scene Stage.show() makes the Stage actually appear
12
JavaFX JavaFX offers two different ways to code the UI
Both controls and functionality coded in Java. This is the way we will initially work, because it is the most straightforward way. XML description of the controls, with Java code to define how they work. We will try this method a little later. Although we will not cover it in depth, it is similar to the way most (not all) web and mobile GUI programming works. I recommend you study this in more detail on your own this summer.
13
Hello World in JavaFX import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.layout.StackPane; import javafx.scene.text.Text; import javafx.stage.Stage; public class Hello extends public void start(Stage primaryStage) { primaryStage.setTitle("Hello World!"); Text txt = new Text("Hello, World!"); StackPane root = new StackPane(); root.getChildren().add(txt); Scene sc = new Scene(root, 300, 250); primaryStage.setScene(sc); primaryStage.show(); }
14
JavaFX StackPane stacks components in “back to front” order according to when they are added to the Pane. Run this and then reverse the order of the two root.getChildren() lines and run it again: public class Hello extends Application{ @Override public void start(Stage primaryStage) { primaryStage.setTitle("Hello World!"); Text txt = new Text("Hello, World!"); Button b = new Button("Click me!"); StackPane root = new StackPane(); root.getChildren().add(txt); root.getChildren().add(b); Scene sc = new Scene(root, 300, 250); primaryStage.setScene(sc); primaryStage.show(); } Note that Text has a transparent background, so you can see through it to the button
15
JavaFX You may see many alternatives when importing JavaFX classes. Look at them carefully for the right ones for JavaFx. In the example below, java.awt.Button would not be correct.
16
JavaFX Group is another type of Pane that renders its components using specified x and y coordinates. Experiment with the values of the parameters in this code: @Override public void start(Stage primaryStage) { Group g = new Group(); Rectangle r = new Rectangle(); r.setWidth(200); r.setHeight(100); r.setFill(Color.RED); r.setX(50); r.setY(50); Circle c = new Circle(); c.setRadius(100); c.setFill(Color.GREEN); c.setCenterX(300); c.setCenterY(300); g.getChildren().add(r); g.getChildren().add(c); Scene sc = new Scene(g, 750, 750); primaryStage.setScene(sc); primaryStage.show(); }
17
JavaFX Architecture A JavaFX user interface is based on a scene graph, which is a tree, much like an html document. To review, the CS conception of a tree looks like this: Other than the root, each node has one parent Each node may have one or more children A node with no children is called a leaf All nodes are said to be contained within the root
18
JavaFX Architecture In JavaFX, the root of the scene graph tree is the pane.
19
Styling Each node in the scene graph has an id, size, and a style class. The style class is actually a list of Strings that are the names of CSS classes. This capability is new and is limited. The CSS properties are specific to JavaFX, but they are usually named after standard css properties and prefixed with "fx-" Oracle’s documentation of the CSS properties is preliminary, but I won’t make you do anything too obscure with these in this class. Most of you have basic familiarity with CSS from CS120 or an equivalent class/ experience. If you have not used CSS before, this will not be a great hurdle, but come to my office hours.
20
Styling @Override public void start(Stage primaryStage) { StackPane s = new StackPane(); Scene sc = new Scene(s, 300, 300); sc.getStylesheets().add("styles/style.css"); Label l = new Label("Hello"); l.getStyleClass().add("arthur"); l.getStyleClass().add("beatrice"); s.getChildren().add(l); primaryStage.setScene(sc); primaryStage.show(); }
21
Styling Contents of style.css .arthur{ -fx-background-color: #FFFF00;
-fx-text-fill: #00DDFF; } .beatrice{ -fx-font-size: 500%; Contents of style.css
22
Styling This setup separates the presentation from the content, which makes it much easier to change them separately. public class Hello extends Application { @Override public void start(Stage primaryStage) { StackPane s = new StackPane(); Scene sc = new Scene(s, 300, 300); sc.getStylesheets().add("styles/style.css"); Label l = new Label("Hello"); boolean am = getAm(); if(am) l.getStyleClass().add("amstyle"); else l.getStyleClass().add("pmstyle"); s.getChildren().add(l); primaryStage.setScene(sc); primaryStage.show(); } private boolean getAm(){ LocalDateTime d = LocalDateTime.now(); if(d.getHour() < 12) return true; else return false;
23
Styling .amstyle{ -fx-background-color: #FFFF00; -fx-text-fill: #00DDFF; -fx-font-size: 300%; } .pmstyle{ -fx-background-color: #FF00FF; -fx-text-fill: #00FF00; -fx-font-size: 400%;
24
Events Our programs so far have asked for input at times directed by the code, then handled the input when given. Typically, a main loop controls the timing of requests for input. GUI programs must handle events that are user-directed and may occur at any time. GUI actions, such as button clicks, raise Events. In OOP, an event is implemented as an object of some class. In JavaFX, these are instances of subclasses of the EventObject class.
25
Event Handlers Event handlers specify which events the program will respond to and what to do when they occur In JavaFX, these implement the EventHandler interface and are parameterized by subclasses of Event, such as ActionEvent. You can add EventHandlers to may different types of GUI components EventHandlers must implement the method handle(Event event) You can create an Event Handler object in many different ways Code a class in a separate file and instantiate an object Code an inner class and instantiate an object Code an anonymous class and instantiate an object separately Code an anonymous class and instantiate a one-of-a-kind object all at once
26
Separate EventHandler Class
import javax.swing.JOptionPane; import javafx.event.Event; import javafx.event.EventHandler; public class MyClickHandler<ActionEvent> implements public void handle(Event event) { JOptionPane.showMessageDialog(null, "Thanks!"); }
27
Separate EventHandler Class
public class Hello extends Application public void start(Stage primaryStage) { StackPane s = new StackPane(); Scene sc = new Scene(s, 300, 300); Button b = new Button(); b.setText("Click Me!"); EventHandler<Event> handler = new MyClickHandler<Event>(); b.addEventHandler(MouseEvent.MOUSE_CLICKED, handler); s.getChildren().add(b); primaryStage.setScene(sc); primaryStage.show(); }
28
Inner EventHandler Class
public class Hello extends Application public void start(Stage primaryStage) { StackPane s = new StackPane(); Scene sc = new Scene(s, 300, 300); Button b = new Button(); b.setText("Click Me!"); EventHandler<Event> handler = new MyClickHandler<Event>(); b.addEventHandler(MouseEvent.MOUSE_CLICKED, handler); s.getChildren().add(b); primaryStage.setScene(sc); primaryStage.show(); } private class MyClickHandler<ActionEvent> implements EventHandler<Event>{ public void handle(Event event) { JOptionPane.showMessageDialog(null, "Thanks!");
29
Anonymous EventHandler Class with Variable
public class Hello extends Application public void start(Stage primaryStage) { StackPane s = new StackPane(); Scene sc = new Scene(s, 300, 300); Button b = new Button(); b.setText("Click Me!"); // “anonymous” because we never name the class EventHandler<Event> handler = new EventHandler<Event>(){ public void handle(Event event) { JOptionPane.showMessageDialog(null, "Thanks!"); } }; b.addEventHandler(MouseEvent.MOUSE_CLICKED, handler); s.getChildren().add(b); primaryStage.setScene(sc); primaryStage.show();
30
Anonymous Class with Anonymous Object
public class Hello extends Application public void start(Stage primaryStage) { StackPane s = new StackPane(); Scene sc = new Scene(s, 300, 300); Button b = new Button(); b.setText("Click Me!"); b.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<Event>(){ public void handle(Event event) { JOptionPane.showMessageDialog(null, "Thanks!"); } }); s.getChildren().add(b); primaryStage.setScene(sc); primaryStage.show();
31
Anonymous Class with Anonymous Object
Open parenthesis begins parameter list for addEventhandler() Beginning of method call Call to EventHandler constructor b.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<Event>(){ @Override public void handle(Event event) { JOptionPane.showMessageDialog(null, "Thanks!"); } ); This idiom may be hard to get used to, but it is very common in many different GUI programming frameworks. There will certainly be a question on the final exam that requires you to understand it. Open curly brace begins definition of anonymous class Close curly brace ends definition of anonymous class Semicolon ends addEventhandler() statement Close parenthesis ends parameter list for addEventhandler()
32
GridPane GridPane is a Pane that allows you to specify the relative location of controls using row and column numbers Column numbers are listed first
33
ClickCounter This application uses GUI components and EventHandlers in a slightly more complex way: Place a grid of buttons on a GridPane Place a Label into in an Hbox (one-row Pane) indicating how many buttons are currently clicked Attach EventHandlers to each button that track whether the button is currently clicked or not clicked and update the count displayed on the Label Add both Panes to a BorderPane Notice the use of String.valueOf() to convert numeric values to Strings for display in labels
34
Click Counter public class ClickCounter extends Application { private int public void start(Stage primaryStage) throws Exception { BorderPane bp = new BorderPane(); bp.getStyleClass().add("grid"); GridPane gp = new GridPane(); Label clickedLabel = new Label("Buttons Clicked: "); clickedLabel.getStyleClass().add("clickedLabel"); Label numClickedLabel = new Label("0"); numClickedLabel.getStyleClass().add("clickedLabel"); HBox clickedCounterBox = new HBox(); clickedCounterBox.getStyleClass().add("clickedBox"); clickedCounterBox.getChildren().add(clickedLabel); clickedCounterBox.getChildren().add(numClickedLabel); Scene sc = new Scene(bp); sc.getStylesheets().add("styles/style.css"); numClicked = 0; for (int rowCounter = 0; rowCounter < 10; rowCounter++) for (int colCounter = 0; colCounter < 10; colCounter++) { }
35
Click Counter Button b = new Button("Unclicked"); b.setMinWidth(150); b.getStyleClass().add("button"); b.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<Event>() { Boolean clicked = public void handle(Event event) { if (clicked == true) { clicked = false; b.setText("Unclicked"); numClicked--; } else { clicked = true; b.setText("Clicked"); numClicked++; } numClickedLabel.setText(String.valueOf(numClicked)); }); gp.add(b, colCounter, rowCounter); bp.setTop(clickedCounterBox); bp.setBottom(gp); primaryStage.setScene(sc); primaryStage.show();
36
CSS .pane{ -fx-font-size: 250%; -fx-padding: 20px; } .grid{ -fx-font-size: 200%; .clickedLabel{ -fx-background-color: #00FFFF; .clickedBox{ -fx-alignment: center;
37
Event Handling with Setters
JavaFX can also handle events using setter methods from the various Node classes, like this: Label l = new Label("Click Me!"); l.setOnMouseClicked(new public void handle(MouseEvent event) { JOptionPane.showMessageDialog(null, "Thanks!"); } });
38
Event Handling with Lambda Expressions
Simple event handling works well with lambda expressions, a feature that is commonly used in functional programming and has recently been introduced to Java. A Lambda expression is equivalent to an anonymous method (Liang says an anonymous class) Here is a sample; e is the parameter name for the event, which is passed into the lambda expression.. Later we will get information from the event objects. Label l = new Label("Click Me!"); l.setOnMouseClicked(e -> { JOptionPane.showMessageDialog(null, "Thanks!"); } );
39
Tuning GUI Appearance There are at least two good ways to find details on how to adjust the appearance of JavaFX GUIs: Google a phrase like "JavaFX background color" and see what you find. Oracle documentation has the most info, but StackOverflow.com usually has the most practical answers Use Eclipse's context-sensitive help:
40
Event Methods Event contains various methods you can use to get information about events. This example uses a few of them. public void start(Stage primaryStage) { VBox v = new VBox(); Button b = new Button("Click Me!"); Label l = new Label(); b.setOnMouseClicked(e -> { String info = "Source: " + e.getSource() + "\n" + "Event Type: " + e.getEventType() + "\n" + "Button: " + e.getButton() + "\n"; l.setText(info); } ); v.getChildren().add(b); v.getChildren().add(l); Scene sc = new Scene(v, 300, 300); primaryStage.setScene(sc); primaryStage.show();
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.