7 GUI Construction P 2 GUI Construction Sources

  • Slides: 55
Download presentation
7. GUI Construction

7. GUI Construction

P 2 — GUI Construction Sources > David Flanagan, Java in Nutshell: 5 th

P 2 — GUI Construction Sources > David Flanagan, Java in Nutshell: 5 th edition, O’Reilly. > David Flanagan, Java Foundation Classes in a Nutshell, O’Reilly > http: //java. sun. com/docs/books/tutorial/uiswing > ant. apache. org © O. Nierstrasz 7. 2

P 2 — GUI Construction Roadmap > Model-View-Controller (MVC) > Swing Components, Containers and

P 2 — GUI Construction Roadmap > Model-View-Controller (MVC) > Swing Components, Containers and Layout Managers > Events and Listeners > Observers and Observables > Jar files, Ant and Javadoc > Epilogue: distributing the game © O. Nierstrasz 7. 3

P 2 — GUI Construction Roadmap > Model-View-Controller (MVC) > Swing Components, Containers and

P 2 — GUI Construction Roadmap > Model-View-Controller (MVC) > Swing Components, Containers and Layout Managers > Events and Listeners > Observers and Observables > Jar files, Ant and Javadoc > Epilogue: distributing the game © O. Nierstrasz 7. 4

P 2 — GUI Construction A Graphical Tic. Tac. Toe? Our existing Tic. Tac.

P 2 — GUI Construction A Graphical Tic. Tac. Toe? Our existing Tic. Tac. Toe implementation is very limited: > single-user at a time > textual input and display We would like to migrate it towards an interactive game: > running the game with graphical display and mouse input © O. Nierstrasz 7. 5

P 2 — GUI Construction Model-View-Controller Version 6 of our game implements a model

P 2 — GUI Construction Model-View-Controller Version 6 of our game implements a model of the game, without a GUI. The Game. GUI will implement a graphical view and a controller for GUI events. The MVC paradigm separates an application from its GUI so that multiple views can be dynamically connected and updated. © O. Nierstrasz 7. 6

P 2 — GUI Construction Roadmap > Model-View-Controller (MVC) > Swing Components, Containers and

P 2 — GUI Construction Roadmap > Model-View-Controller (MVC) > Swing Components, Containers and Layout > > Managers Events and Listeners Observers and Observables Jar files, Ant and Javadoc Epilogue: distributing the game © O. Nierstrasz 7. 7

P 2 — GUI Construction AWT Components and Containers The java. awt package defines

P 2 — GUI Construction AWT Components and Containers The java. awt package defines GUI components, containers and their layout managers. NB: There also many graphics classes to define colours, fonts, images etc. © O. Nierstrasz 7. 8

P 2 — GUI Construction Swing JComponents The javax. swing package defines GUI components

P 2 — GUI Construction Swing JComponents The javax. swing package defines GUI components that can adapt their “look and feel” to the current platform. © O. Nierstrasz 7. 9

P 2 — GUI Construction Swing Containers and Containment Swing Containers may contain other

P 2 — GUI Construction Swing Containers and Containment Swing Containers may contain other Components Jbutton b = new Jbutton(“Push me”); JPanel p = new Jpanel(); p. add(b); © O. Nierstrasz 7. 10

P 2 — GUI Construction Layout Management The Layout Manager defines how the components

P 2 — GUI Construction Layout Management The Layout Manager defines how the components are arranged in a container (size and position). JPanel awt Layout. Managers p = new JPanel(new Border. Layout()); swing Layout. Managers Container content. Pane = frame. get. Content. Pane(); content. Pane. set. Layout(new Flow. Layout()); http: //java. sun. com/docs/books/tutorial/uiswing/layout/using. html © O. Nierstrasz 7. 11

P 2 — GUI Construction An example: Grid. Layout A Grid. Layout places components

P 2 — GUI Construction An example: Grid. Layout A Grid. Layout places components in a grid of cells. > Each component takes up all the space in a cell. > Each cell is the same size Grid. Layout experiment. Layout = new Grid. Layout(0, 2); … comps. To. Experiment. set. Layout(experiment. Layout); comps. To. Experiment. add(new Jbutton(“Button 1”); comps. To. Experiment. add(new Jbutton(“Button 2”); © O. Nierstrasz 7. 12

P 2 — GUI Construction The Game. GUI is a JFrame using a Border.

P 2 — GUI Construction The Game. GUI is a JFrame using a Border. Layout (with a centre and up to four border components), and containing a JButton (“North”), a JPanel (“Center”) and a JLabel (“South”). The central Panel itself contains a grid of squares (Panels) and uses a Grid. Layout. © O. Nierstrasz NB: Game. GUI and Place are the only classes that differ for AWT & Swing 7. 13

P 2 — GUI Construction Laying out the Game. GUI public class Game. GUI

P 2 — GUI Construction Laying out the Game. GUI public class Game. GUI extends JFrame implements Observer { … public Game. GUI(String title) throws Headless. Exception { super(title); game = make. Game(); … this. set. Size(…); add("North", make. Controls()); add("Center", make. Grid()); label = new JLabel(); add("South", label); show. Feed. Back(game. current. Player(). mark() + " plays"); … this. show(); } © O. Nierstrasz Tic. Tac. Toe v 7 -swing 7. 14

P 2 — GUI Construction Helper methods As usual, we introduce helper methods to

P 2 — GUI Construction Helper methods As usual, we introduce helper methods to hide the details of GUI construction. . . private Component make. Controls() { JButton again = new JButton("New game"); . . . return again; } © O. Nierstrasz 7. 15

P 2 — GUI Construction Roadmap > Model-View-Controller (MVC) > Swing Components, Containers and

P 2 — GUI Construction Roadmap > Model-View-Controller (MVC) > Swing Components, Containers and Layout Managers > Events and Listeners > Observers and Observables > Jar files, Ant and Javadoc > Epilogue: distributing the game © O. Nierstrasz 7. 16

P 2 — GUI Construction Interactivity with Events > To make your GUI do

P 2 — GUI Construction Interactivity with Events > To make your GUI do something you need to handle events — An event is typically a user action — a mouse click, key stroke, etc. — The Java Event model is used by Java AWT and Swing (java. awt. AWTEvent and javax. swing. event) © O. Nierstrasz 7. 17

P 2 — GUI Construction Concurrency and Swing > The program is always responsive

P 2 — GUI Construction Concurrency and Swing > The program is always responsive to user interaction, no matter what it is doing. > The runtime of the Swing framework creates threads — you don’t explicitly create them. > The Event Dispatch thread is responsible for event handling. © O. Nierstrasz 7. 18

P 2 — GUI Construction Events and Listeners (I) Instead of actively checking for

P 2 — GUI Construction Events and Listeners (I) Instead of actively checking for GUI events, you can define callback methods that will be invoked when your GUI objects receive events: Hardware events. . . (Mouse. Event, Key. Event, . . . ) . . . are handled by subscribed Listener objects AWT Framework/ Swing Framework Callback methods AWT/Swing Components publish events and (possibly multiple) Listeners subscribe interest in them. http: //java. sun. com/docs/books/tutorial/uiswing/events/index. html © O. Nierstrasz 7. 19

P 2 — GUI Construction Events and Listeners (II) Every AWT and Swing component

P 2 — GUI Construction Events and Listeners (II) Every AWT and Swing component publishes a variety of different events (see java. awt. event) with associated Listener interfaces). Component Events Listener Interface Listener methods JButton Action. Event Action. Listener action. Performed() mouse. Clicked() mouse. Entered() Mouse. Listener Mouse. Event mouse. Exited() mouse. Pressed() mouse. Released() JComponent Mouse. Motion. Listener mouse. Dragged() mouse. Moved() key. Pressed() Key. Event Key. Listener key. Released() key. Typed() . . . © O. Nierstrasz 7. 20

P 2 — GUI Construction Listening for Button events When we create the “New

P 2 — GUI Construction Listening for Button events When we create the “New game” Button, we attach an Action. Listener with the Button. add. Action. Listener() method: private Component make. Controls() { Button again = new Button("New game"); again. add. Action. Listener(new Action. Listener() { public void action. Performed(Action. Event e) { show. Feed. Back("starting new game. . . "); new. Game(); // NB: has access to methods } // of enclosing class! }); return again; } We instantiate an anonymous inner class to avoid defining a named subclass of Action. Listener. © O. Nierstrasz 7. 21

P 2 — GUI Construction Gracefully cleaning up A Window. Adapter provides an empty

P 2 — GUI Construction Gracefully cleaning up A Window. Adapter provides an empty implementation of the Window. Listener interface (!) public class Game. GUI extends JFrame implements Observer { … public Game. GUI(String title) throws Headless. Exception { … this. add. Window. Listener(new Window. Adapter(){ public void window. Closing(Window. Event e) { Game. GUI. this. dispose(); // NB: disambiguate “this”! } }); this. show(); } © O. Nierstrasz 7. 22

P 2 — GUI Construction Listening for mouse clicks We also attach a Mouse.

P 2 — GUI Construction Listening for mouse clicks We also attach a Mouse. Listener to each Place on the board. private Component make. Grid() {. . . Panel grid = new Panel(); grid. set. Layout(new Grid. Layout(3, 3)); places = new Place[3][3]; for (Row row : Row. values()) { for (Column column : Column. values()) { Place p = new Place(column, row); p. add. Mouse. Listener(new Place. Listener(p, this)); . . . return grid; } © O. Nierstrasz 7. 23

P 2 — GUI Construction The Place. Listener Mouse. Adapter is another convenience class

P 2 — GUI Construction The Place. Listener Mouse. Adapter is another convenience class that defines empty Mouse. Listener methods public class Place. Listener extends Mouse. Adapter { private final Place place; private final Game. Gui gui; public Place. Listener(Place my. Place, Game. GUI my. Gui) { place = my. Place; gui = my. Gui; }. . . © O. Nierstrasz 7. 24

P 2 — GUI Construction The Place. Listener. . . We only have to

P 2 — GUI Construction The Place. Listener. . . We only have to define the mouse. Clicked() method: public void mouse. Clicked(Mouse. Event e){. . . if (game. not. Over()) { try { ((GUIplayer) game. current. Player()). move(col, row); gui. show. Feed. Back(game. current. Player(). mark() + " plays"); } catch (Assertion. Exception err) { gui. show. Feed. Back("Invalid move ignored. . . "); } if (!game. not. Over()) { gui. show. Feed. Back("Game over -- " + game. winner() + " wins!"); } } else { gui. show. Feed. Back("The game is over!"); } } © O. Nierstrasz 7. 25

P 2 — GUI Construction Roadmap > Model-View-Controller (MVC) > Swing Components, Containers and

P 2 — GUI Construction Roadmap > Model-View-Controller (MVC) > Swing Components, Containers and Layout Managers > Events and Listeners > Observers and Observables > Jar files, Ant and Javadoc > Epilogue: distributing the game © O. Nierstrasz 7. 26

P 2 — GUI Construction The Observer Pattern > Also known as the publish/subscribe

P 2 — GUI Construction The Observer Pattern > Also known as the publish/subscribe design pattern - to observe the state of an object in a program. > One or more objects (called observers) are registered to observe an event which may be raised in an observable object (the observable object or subject). > The the observable object or subject which may raise an event maintains a collection of observers. © O. Nierstrasz 7. 27

P 2 — GUI Construction Our Board. Game Implementation «interface» JFrame Observable Observer Board.

P 2 — GUI Construction Our Board. Game Implementation «interface» JFrame Observable Observer Board. Game update() Game. GUI game: Board. Game label: Jlabel places: Places[][] * Abstract. Board. Game Tic. Tac. Toe © O. Nierstrasz «interface» Observer Gomuku Observable/Subject 7. 28

P 2 — GUI Construction Observers and Observables A class can implement the java.

P 2 — GUI Construction Observers and Observables A class can implement the java. util. Observer interface when it wants to be informed of changes in Observable objects. An Observable object can have one or more Observers. After an observable instance changes, calling notify. Observers() causes all observers to be notified by means of their update() method. © O. Nierstrasz Observable add. Observer() delete. Observer() notify. Observers(Object) * «interface» Observer update(Observable, Object) 7. 29

P 2 — GUI Construction Adding Observers to the Observable public class Game. GUI

P 2 — GUI Construction Adding Observers to the Observable public class Game. GUI extends JFrame implements Observer {. . . public Game. GUI(String title) throws Headless. Exception { super(title); game = make. Game(); game. add. Observer(this); // notify Game. Gui if state change. . . © O. Nierstrasz 7. 30

P 2 — GUI Construction Observing the Board. Game In our case, the Game.

P 2 — GUI Construction Observing the Board. Game In our case, the Game. GUI represents a View, so plays the role of an Observer of the Board. Game Tic. Tac. Toe: public class Game. GUI extends JFrame implements Observer {. . . public void update(Observable o, Object arg) { Move move = (Move) arg; // Downcast Object type show. Feed. Back("got an update: " + move); places[move. col][move. row]. set. Move(move. player); } }. . . © O. Nierstrasz 7. 31

P 2 — GUI Construction Observing the Board. Game. . . The Board. Game

P 2 — GUI Construction Observing the Board. Game. . . The Board. Game represents the Model, so plays the role of an Observable (i. e. the subject being observed): public abstract class Abstract. Board. Game extends Observable implements Board. Game {. . . public void move(int col, int row, Player p) {. . . set. Changed(); notify. Observers(new Move(col, row, p)); } } © O. Nierstrasz 7. 32

P 2 — GUI Construction Handy way of Communicating changes A Move instance bundles

P 2 — GUI Construction Handy way of Communicating changes A Move instance bundles together information about a change of state in a Board. Game: public class Move { public final int col, row; // NB: public, but final public final Player player; public Move(int col, int row, Player player) { this. col = col; this. row = row; this. player = player; } public String to. String() { return "Move(" + col + ", " + row + ", " + player + ")"; } } © O. Nierstrasz 7. 33

P 2 — GUI Construction Setting up the connections When the Game. GUI is

P 2 — GUI Construction Setting up the connections When the Game. GUI is created, the model (Board. Game), view (Game. Gui) and controller (Place) components are instantiated. The Game. GUI subscribes itself as an Observer to the game ( observable), and subscribes a Place. Listener to Mouse. Events for each Place on the view of the Board. Game. © O. Nierstrasz 7. 34

P 2 — GUI Construction Playing the game Mouse clicks are propagated from a

P 2 — GUI Construction Playing the game Mouse clicks are propagated from a Place (controller) to the Board. Game (model): If the corresponding move is valid, the model’s state changes, and the Game. GUI updates the Place (view). © O. Nierstrasz 7. 35

P 2 — GUI Construction Checking user errors > Assertion failures are generally a

P 2 — GUI Construction Checking user errors > Assertion failures are generally a sign of errors in our program — However we cannot guarantee the user will respect our contracts! — We need special always-on assertions to check user errors public void move(int col, int row, Player p) throws Invalid. Move. Exception { assert this. not. Over(); assert p == current. Player(); user. Assert(this. get(col, row). is. Nobody(), "That square is occupied!"); . . . } private void user. Assert(Boolean condition, String message) throws Invalid. Move. Exception { if (!condition) { throw new Invalid. Move. Exception(message); } } © O. Nierstrasz 7. 36

P 2 — GUI Construction Refactoring the Board. Game Adding a GUI to the

P 2 — GUI Construction Refactoring the Board. Game Adding a GUI to the game affects many classes. We iteratively introduce changes, and rerun our tests after every change. . . > Shift responsibilities between Board. Game and Player (both should be passive!) — — > introduce Player interface, Inactive. Player and Stream. Player classes move get. Row() and get. Col() from Board. Game to Player move Board. Game. update() to Game. Driver. play. Game() change Board. Game to hold a matrix of Player, not marks Introduce GUI classes (Game. GUI, Place. Listener) — Introduce GUIplayer — Place. Listener triggers GUIplayer to move > Board. Game must be observable — Introduce Move class to communicate changes from Board. Game to Observer > Check user assertions! © O. Nierstrasz 7. 37

P 2 — GUI Construction Roadmap > Model-View-Controller (MVC) > Swing Components, Containers and

P 2 — GUI Construction Roadmap > Model-View-Controller (MVC) > Swing Components, Containers and Layout Managers > Events and Listeners > Observers and Observables > Jar files, Ant and Javadoc > Epilogue: distributing the game © O. Nierstrasz 7. 38

P 2 — GUI Construction Jar files We would like to bundle the Java

P 2 — GUI Construction Jar files We would like to bundle the Java class files of our application into a single, executable file — A jar is a Java Archive — The manifest file specifies the main class to execute Manifest-Version: 1. 0 Main-Class: tictactoe. gui. Game. GUI We could build the jar manually, but it would be better to automate the process … (http: //java. sun. com/docs/books/tutorial/deployment/jar/) © O. Nierstrasz 7. 39

P 2 — GUI Construction Ant is a Java-based make-like utility that uses XML

P 2 — GUI Construction Ant is a Java-based make-like utility that uses XML to specify dependencies and build rules. You can specify in a “build. xml”: > the name of a project > the default target to create > the basedir for the files of the project > dependencies for each target > tasks to execute to create targets > You can extend ant with your own tasks > Ant is included in eclipse (Each task is run by an object that implements a particular Task interface. ) (http: //ant. apache. org/manual/index. html) © O. Nierstrasz 7. 40

P 2 — GUI Construction A Typical build. xml <project name="Tic. Tac. Toe. GUI"

P 2 — GUI Construction A Typical build. xml <project name="Tic. Tac. Toe. GUI" default="all" basedir=". "> <!-- set global properties for this build --> <property name="src" value="src"/> <property name="build" value="build"/> <property name="doc" value="doc"/> <property name="jar" value="Tic. Tac. Toe. GUI. jar"/> <target name="all" depends="jar, jdoc"/> <target name="init"> <!-- Create the time stamp --> <tstamp/> <!-- Create the build directory structure used by compile --> <mkdir dir="${build}"/> <copy todir="${build}/tictactoe/gui/images" > <fileset dir="${src}/tictactoe/gui/images" /> </copy> <mkdir dir="${doc}"/> </target> <target name="compile" depends="init"> <!-- Compile the java code from ${src} into ${build} --> <javac srcdir="${src}" destdir="${build}" source="1. 5" target="1. 5" classpath="junit. jar" /> </target> © O. Nierstrasz … 7. 41

P 2 — GUI Construction … <target name="jdoc" depends="init"> <!-- Generate the javadoc -->

P 2 — GUI Construction … <target name="jdoc" depends="init"> <!-- Generate the javadoc --> <javadoc destdir="${doc}" source="1. 5"> <fileset dir="${src}" includes="**/*. java"/> </javadoc> </target> <target name="jar" depends="compile"> <jar jarfile="${jar}” manifest="${src}/tictactoe/gui/manifest-run" basedir="${build}"/> </target> <target name="run" depends="jar"> <java fork="true" jar="${jar}"/> </target> <target name="clean"> <!-- Delete the ${build} directory --> <delete dir="${build}"/> <delete dir="${doc}"/> <delete> <fileset dir=". " includes="Tic. Tac. Toe. GUI. jar"/> </delete> </target> </project> © O. Nierstrasz 7. 42

P 2 — GUI Construction Running Ant % ant jar Buildfile: build. xml init:

P 2 — GUI Construction Running Ant % ant jar Buildfile: build. xml init: [mkdir] Created dir: /Scratch/P 2 -Examples/build [mkdir] Created dir: /Scratch/P 2 -Examples/doc compile: [javac] Compiling 18 source files to /Scratch/P 2 -Examples/build jar: [jar] Building jar: /Scratch/P 2 -Examples/Tic. Tac. Toe. GUI. jar BUILD SUCCESSFUL Total time: 5 seconds Ant assumes that the build file is called build. xml © O. Nierstrasz 7. 43

P 2 — GUI Construction Javadoc > Javadoc generates API documentation in HTML format

P 2 — GUI Construction Javadoc > Javadoc generates API documentation in HTML format for specified Java source files. — Each class, interface and each public or protected method may be preceded by “javadoc comments” between /** and */. — Comments may contain special tag values (e. g. , @author) and (some) HTML tags. © O. Nierstrasz 7. 44

P 2 — GUI Construction Javadoc input package p 2. tictactoe; /** * Minimal

P 2 — GUI Construction Javadoc input package p 2. tictactoe; /** * Minimal interface for Player classes that get moves from user * and forward them to the game. * @author $Author: oscar $ * @version $Id: Player. java, v 1. 5 2005/02/22 15: 08: 04 oscar Exp $ */ public interface Player { /** * @return the char representation of this Player * @see Abstract. Board. Game#to. String */ public char mark(); … } © O. Nierstrasz 7. 45

P 2 — GUI Construction Javadoc output © O. Nierstrasz 7. 46

P 2 — GUI Construction Javadoc output © O. Nierstrasz 7. 46

P 2 — GUI Construction GUI objects in practice. . . Consider using Java

P 2 — GUI Construction GUI objects in practice. . . Consider using Java webstart > Download whole applications in a secure way Consider other GUI frameworks (eg SWT from eclipse) > org. eclipse. swt. * provides a set of native (operating system specific) components that work the same on all platforms. Use a GUI builder > Interactively build your GUI rather than programming it — add the hooks later. (e. g. http: //jgb. sourceforge. net/index. php) © O. Nierstrasz 7. 47

P 2 — GUI Construction Roadmap > Model-View-Controller (MVC) > Swing Components, Containers and

P 2 — GUI Construction Roadmap > Model-View-Controller (MVC) > Swing Components, Containers and Layout Managers > Events and Listeners > Observers and Observables > Jar files, Ant and Javadoc > Epilogue: distributing the game © O. Nierstrasz 7. 48

P 2 — GUI Construction A Networked Tic. Tac. Toe? We now have a

P 2 — GUI Construction A Networked Tic. Tac. Toe? We now have a usable GUI for our game, but it still supports only a single user. We would like to support: > players on separate machines > each running the game GUI locally > with a remote “game server” managing the state of the game © O. Nierstrasz 7. 49

P 2 — GUI Construction The concept © O. Nierstrasz 7. 50

P 2 — GUI Construction The concept © O. Nierstrasz 7. 50

P 2 — GUI Construction Remote Method Invocation RMI allows an application to register

P 2 — GUI Construction Remote Method Invocation RMI allows an application to register a Java object under a public name with an RMI registry on the server machine. A client may look up up the service using the public name, and obtain a local object (stub) that acts as a proxy for the remote server object (represented by a skeleton). © O. Nierstrasz 7. 51

P 2 — GUI Construction Playing the game © O. Nierstrasz 7. 52

P 2 — GUI Construction Playing the game © O. Nierstrasz 7. 52

P 2 — GUI Construction What you should know! The Tic. Tac. Toe game

P 2 — GUI Construction What you should know! The Tic. Tac. Toe game knows nothing about the Game. GUI or Places. How is this achieved? Why is this a good thing? What are models, view and controllers? What is a Container, Component? What does a layout manager do? What are events and listeners? Who publishes and who subscribes to events? How does the Observer Pattern work? Ant javadoc © O. Nierstrasz 7. 53

P 2 — GUI Construction Can you answer these questions? How could you make

P 2 — GUI Construction Can you answer these questions? How could you make the game start up in a new Window? What is the difference between an event listener and an observer? The Move class has public instance variables — isn’t this a bad idea? What kind of tests would you write for the GUI code? © O. Nierstrasz 7. 54

Safety Patterns License http: //creativecommons. org/licenses/by-sa/2. 5/ Attribution-Share. Alike 2. 5 You are free:

Safety Patterns License http: //creativecommons. org/licenses/by-sa/2. 5/ Attribution-Share. Alike 2. 5 You are free: • to copy, distribute, display, and perform the work • to make derivative works • to make commercial use of the work Under the following conditions: Attribution. You must attribute the work in the manner specified by the author or licensor. Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under a license identical to this one. • For any reuse or distribution, you must make clear to others the license terms of this work. • Any of these conditions can be waived if you get permission from the copyright holder. Your fair use and other rights are in no way affected by the above. © Oscar Nierstrasz 55