(1) introduction to java guis philip johnson collaborative software development laboratory...

Post on 21-Jan-2016

220 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

(1)

Introduction to Java GUIs

Philip JohnsonCollaborative Software Development

Laboratory Information and Computer Sciences

University of HawaiiHonolulu HI 96822

(2)

GUI Design/Implementation

Patterns:•The Listener (Observer-Observable) pattern

•Return of the MVC pattern

Toolkits:•MigLayout (improved API for GUI layout)•UISpec4J (unit testing of GUI)

Packaging:•Manifest file and specifying the main class•Including components in the jar file

(3)

Listener Pattern (Motivation) Question: How can object Foo “communicate” that

its state has changed to objects Bar and Baz?

One approach: direct method invocation.•Class Foo { public void stateChange() { bar.notifyChange(“Foo changed”); baz.notifyChange(“Foo changed”); }}

Issues with this approach:•Object Foo hardwires references to instances it communicates with.

•In this code, every instance of Foo communicates their changes to a single instance of Bar and Baz!

•If a new object (Qux) wants to know about changes to Foo, the code in Foo must change.

(4)

Listeners Listeners provide a more flexible way for instances to communicate with each other.

Approach:•Foo maintains a list of instances who want to be notified when something happens to Foo.

•Foo provides some kind of “addListener” method. Bar and Baz instances add themselves to the list by invoking that method.

•Bar and Baz provide some kind of “notify” method that Foo will invoke on all of the instances in its list when something happens.

(5)

Foo class Foo { private List listeners = new ArrayList();

public void addListener(FooListener object) { listeners.add(object); } private notifyListeners () { for (FooListener listener: listeners) { listener.notify(“Foo changed”); } }

(6)

Bar class Bar implements FooListener {

public Bar () { Foo foo = new Foo(); foo.addListener(this); }

public void notify (String message) { System.out.println (“Foo says: “ + message); }

(7)

Interface FooListener public interface FooListener {

public void notify(String message) { }

}

(8)

Why Listeners are cool Advantages of listener design pattern•Simple to implement.•Instances of Foo don’t know (or care) who or how many instances are listening for its changes.

•Each instance of Foo can have different instances of Bar and Baz attached to it.

Most important advantage:•If a new class Qux wants to listen to Foo, no changes need be made to Foo’s code.

(9)

Java Support for the Listener Design Pattern

(1) All GUI components (Buttons, TextFields, etc.) support a variety of listeners. •If an instance of Class Foo needs to know when a button is pressed, it adds itself as a listener to that button instance.

(2) java.util provides the Observer (interface) and Observable (class) that implement this pattern. •Provides basic machinery to non-GUI code

(10)

GUI example class Foo implements ActionListener { private JButton button = new JButton(“Hi!”);

public Foo () { button.addActionListener(this);}

public void actionPerformed (ActionEvent e) { System.out.println(“Button ‘Hi!’ was pressed!”):

}

(11)

Observer-Observable Example (1)

class Foo extends Observable {

private update() { this.doSomethingThatChangesState(); setChanged(); notifyObservers(“Something Changed”); }

(12)

Observer-Observable Example (2)

class Bar implements Observer {

private Foo foo = new Foo();

public Bar () { this.foo.addObserver(this); }

public void update(Observable obs, Object arg) { System.out.println(“Foo changed!”); }

(13)

The MVC Pattern

(implemented using listeners)

(Observer/Observable)

(GUI)

(14)

Implementing MVC: The Model

Model:•Contains the application state (as usual)

•Implements Observable interface-Allows clients to add Observers (listeners)-When application state changes, Model invokes notifyObservers().-This triggers invocation of all Observer's update() method

(15)

Model <-> View

View- extends Observer- update()-

View "listens"for changes tomodel.

Model- implements Observable- notifyObservers()

(16)

Implementing MVC: The View

View:•Renders the GUI interface on screen.•Two kinds of communication

-Receives updates from model and displays these changes on screen.-Sends user gestures to controller using ActionPerformed methods available in each GUI component.

(17)

View

View- extends Observer- update()- GUI listeners

View "listens"for changes tomodel.

Controller- actionPerformed()-Controller "listens"

for changes toview (user gestures).

Model- implements Observable- notifyObservers()

(18)

Implementing MVC: Controller

Controller:•Listens for user gestures (changes to view)-Updates model in response

(19)

Controller

View- extends Observer- update()- GUI listeners

View "listens"for changes tomodel.

Controller- actionPerformed()- invokes Model APIController "listens"

for changes toview (user gestures).

Model- implements Observable- notifyObservers()

Controller changesmodel state (using method calls)

(20)

Advantages of MVC Most "sample" Java GUIs do not implement the full MVC pattern.•Model and Controller are combined together, no Observer/Observable component.

•This is bad!

As your GUI becomes more sophisticated, the lack of a real MVC design generally makes your code hard to understand, buggy, and hard to change.

Using "real" MVC simplifies scale-up:•multiple updates to View from one Model change•multiple updates to Model from one user gesture•easily support multiple Controllers, multiple Views, multiple Models

(21)

StackMVCgui Model:•The StackModel class•Implements Observable

View:•The View class•Extends Observer•Contains GUI components

Controller:•The Controller class•Listens to GUI components•Invokes StackModel API to change state.

(22)

Layout Managers To specify how your GUI components appear in the window, you use a Layout Manager.

Java provides a set of built-in Layout Managers to support different needs.•The built-in Layout Managers have been criticized as hard to use.

Over the years, “next generation” layout managers have appeared. Two good open source alternatives:•JGoodies•MigLayout (used in StackMVCgui)

(23)

Unit Testing We want to write unit tests that exercise the GUI interface that can be invoked from JUnit.•We want support for this (similar to DbUnit support for databases and HttpUnit support for webapp testing).

Lots of packages available! •JFCUnit •Abbott•UiSpec4J (used in StackMVCgui)

Two basic approaches:•Use API calls on GUI components.•Invoke the GUI manually, generate a “script” that can be re-run later.

(24)

Packaging GUI applications generally want to be “double clickable”.

Easiest way is to:•package code and all required libraries in a single jar file.

•Indicate the main class in the manifest file.

Besides double clicking, can invoke with:•java -jar stackmvcgui.jar

(25)

Concurrency All Java GUI programs are multi-threaded.•Initial thread

-the main program•Event Dispatch thread

-where event-handling code executes•Worker threads

-where time-consuming operations execute

You must take care to make sure that code executes in the correct thread so that•The user interface is responsive•The user interface does not freeze!

(26)

The initial thread This thread runs the main() method.

In typical Java GUI applications, this thread doesn’t do much more than kick off the GUI in the Event Dispatch thread using code like the following:•SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGUI(); }}

(27)

The Event Dispatch ThreadIn general, code invoking Swing methods should execute on the Event Dispatch Thread.

This code should be “short tasks”, such as tasks that respond to button presses and so forth.

Tasks on the Event Dispatch thread must finish quickly, otherwise unhandled events back up and the user interface becomes unresponsive.

(28)

Worker Threads Used to execute long-running tasks.

Each task running on a worker thread uses an instance of SwingWorker (Java SE 6): •Supports a “done” method that runs on the Event Dispatch thread when the task completes.

•Intermediate results can be published to the Event Dispatch thread.

•Other goodies.

See the Java Tutorial on Swing Concurrency for more details.

top related