100
Architectures and Frameworks for Swing-Based User Interfaces Dan Jacobs [email protected] President and founder, ModelObjects Group http://www.modelobjects.com President and founder, JPlates Inc. http://www.jplates.com Chairman, Boston ACM WebTech Group http://www.acm.org/chapters/webtech

Model-Oriented Architectures and Frameworks for Swing-Based User Interfaces

  • Upload
    sivan

  • View
    47

  • Download
    0

Embed Size (px)

DESCRIPTION

Model-Oriented Architectures and Frameworks for Swing-Based User Interfaces. Dan Jacobs [email protected] President and founder, ModelObjects Group http://www.modelobjects.com President and founder, JPlates Inc. http://www.jplates.com Chairman, Boston ACM WebTech Group - PowerPoint PPT Presentation

Citation preview

Page 1: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

Model-Oriented Architectures and Frameworks for

Swing-Based User Interfaces

Dan [email protected]

President and founder, ModelObjects Grouphttp://www.modelobjects.com

President and founder, JPlates Inc.http://www.jplates.com

Chairman, Boston ACM WebTech Grouphttp://www.acm.org/chapters/webtech

Page 2: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

2

ModelObjects Group

Founded in December 1995 Object-Oriented Software Development Architecture, Design, Implementation Swing User-Interface Development Compilers and Language Tools Multithreaded Server Architectures Web & J2EE Applications IDE Integration and Plug-ins

Page 3: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

3

Seminar Overview

Why build more traditional GUIs? Overview of AWT and Swing Important Design Patterns Levels of Model-View-Controller Model-Oriented UI Architectures Application-Level Controller Logic Effective Event-Handling Strategies Effective Swing Layout Management

Page 4: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

4

Why Build Traditional GUIs?

Most interactive, most expressive Easier to develop (in some ways) Easier to debug, performance-tune, … Better at maintaining user confidence More flexible for managing complexity Integration with other applications Integration with other technologies Disadvantages too

Page 5: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

Overview of AWT and Swing

Page 6: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

6

Overview of AWT and Swing

Swing is built on core of AWT Common event-handling model Lightweight components Powerful graphics operations Fonts, colors, images, printing, etc. Layout managers, container composition

Rich component class library Pluggable Look and Feel Powerful and Extensible

Page 7: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

7

Swing Development Challenges

Mostly single-threaded model Everything happens on event thread

Many large, complex frameworks Hard to know how & where to fit it

Unfamiliar layout and composition The right thing for cross-platform GUIs

API shows signs of age (from JDK1.1) Enormous API, not entirely consistent

Page 8: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

8

AWT/Swing Software Layers

Swing (javax.swing and sub-packages)

J2SE Core Java Packages

JVM and native method libraries

AWT Lightweight Support / Graphics 2D

AWT Component & Container Framework

Platform Operating Systemand Window System

ApplicationCodeJ2SE

Many other standard extensions

Page 9: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

9

Swing Components

Simple Components Button, text-field, check-box, scrollbar,

label, slider, combo-box, spinner, etc. Containers

Panel, scroll-pane, tab-pane, split-pane,dialog, window, popup, etc.

Complex Components Table, tree, menu, file-chooser, etc.

Page 10: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

10

Lightweight Component Model

Platform window system provides: Top-level windows and dialogs Underlying input events Underlying graphics operations

AWT/Swing does the rest: Mapping “flat” events to components Painting, clipping, etc. on window Platform doesn’t see lightweight comps

Page 11: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

11

Inside Swing Components

Internal state management Event handling Painting / Rendering Support for event-listeners Component properties customization Internal composition and layout Built-in recursive support for child

components – events, painting, etc.

Page 12: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

12

Black-Box Component Behavior

Allocate and initialize Configure additional properties Add to parent container Add event listeners Add selection listeners Add property-change listeners Modify properties from listeners

Page 13: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

13

White-Box Customization

Complex object-oriented frameworks Define subclass of component class Override methods as appropriate Call superclass methods as needed Stick to the rules (if you can find them) Requires much deeper knowledge of

AWT and Swing design and internals

Page 14: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

14

Black-Box Component Use

JButton button1 = new JButton("Press Me");

button1.setEnabled(false);

buttonPanel.add(button1);

ActionListener bh = new ButtonHandler(this);

button1.addActionListener(bh);

Page 15: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

Object-Oriented Design Patterns and Frameworks

Page 16: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

16

Object-Oriented Design Patterns Recognizable patterns that appear over

and over again in good designs. General, reusable solutions to common

design problems. Encapsulate aspects of designs that are

likely to change. Allow independent parts of a design to

work together – maintain loose coupling. Reuse of intellectual effort & experience.

Page 17: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

17

Design Principle: Separation of Independent Concerns

Promote loose coupling and strong object encapsulation

Allow independent parts of application to evolve independently

Hide internal details from parts that should not depend on them

Don’t take it too far – some things are not independent of each other

Page 18: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

18

Object-Adapter Design Pattern Problem: Use an existing class as if it

implemented a new interface, but without modifying the class or the interface.

Analogy: Plug an electric appliance into a different kind of outlet, without changing the appliance, the plug, or the outlet.

Object-Adapter prescribes the relationships between the existing class, the required interface, and a new adapter class.

Reusable concept and approach, but each new kind of adapter uses a new class.

Page 19: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

19

Object Adapter Design Pattern

class OldHairDryer

OldPlug getPlug();boolean getBlowerOn();setBlowerOn(boolean);

interface NewPlugProvider

NewPlug getNewPlug();…

NewPlugAdapterimplements NewPlugProvider

NewPlug getNewPlug() { … }private OldSocket _oldSocket;

references

implements

class NewSocket

plugIn(NewPlug);…

references

Page 20: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

20

Event Listener Design Pattern

More flexible extension of Observer Support for multiple event listeners Event object exposes source, details Listeners implement common interface In Swing’s implementation:

Event sources follow naming conventions Listeners notified by synchronous calls Some event objects are modifiable

Page 21: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

21

Event Listener Design Pattern

FooEventSource

addFooListener(FooListener)removeFooListener(FooListener)

fireFooEvent1()fireFooEvent2()

FooListener

handleFooEvent1(FooEvent)handleFooEvent2(FooEvent)

listeners

FooEvent

getSource()getEventType()

getEventDetails()

ConcreteFooListener

handleFooEvent1(FooEvent)handleFooEvent2(FooEvent)

event-source implements

event

Page 22: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

22

PropertyChangeListener Pattern Special case of Event Listener pattern Central to Java Beans component model Events identify source, property, values Property normally identified by naming

conventions (e.g. getFoo(), setFoo(…)) Class must provide support for

managing PropertyChangeListeners Setter methods, after changing state,

fire PropertyChangeEvents

Page 23: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

23

PropertyChangeListener Pattern

class ChangeHandler implements PropertyChangeListener { public void propertyChange(PropertyChangeEvent event) { Object changeSource = event.getSource(); String propertyName = event.getPropertyName(); Object oldValue = event.getOldValue(); Object newValue = event.getNewValue(); ... }}

…ChangeHandler handler = new ChangeHandler();objectToWatch.addPropertyChangeListener(handler);…doSomethingTo(objectToWatch);

Page 24: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

24

Object-Oriented Frameworks

Typically use many design patterns. Well defined roles to play, frequently

specified by interfaces. Core group of classes orchestrates

common behavior for other roles. Frameworks don’t have to be large or

complex – the fewer roles, the better. Can offer best kind of code reuse.

Page 25: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

Model View Controller Pattern

<a href="dosomething?foo=3&bar=no">Click Here</a>

A Frequently Misunderstood Pattern

Page 26: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

26

Model View Controller Pattern

One of best know (as MVC), least fully-understood design patterns.

Originated in Smalltalk-80 window system library – fully object-oriented.

Innumerable mutants, contortions, and distant cousin spin-off patterns.

Encapsulated object state is not the same thing as the model role.

Page 27: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

27

Model View Controller Pattern

Model• view-independent• object encapsulation• change-event source• first-class object

View• renders model info• change-event listener• gesture-event source• first-class object

Controller• gesture-event listener• updates models• selects alternative views• first-class object

model change events

model state changes

gestureevents

model state

queries

view control

Page 28: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

28

MVC Variant Used in Swing

View and Controller combined into a single look-and-feel (L&F) object.

View-specific state in Component and L&F, view-independent state in Model.

Models are specified by interfaces, and default implementations provided.

Some components rarely expose the model, and support listeners directly.

Page 29: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

29

Swing MVC Example 1 - JButton View supports label, different colors

for disabled, armed, etc., icons for normal and disabled, etc.

Controller responds to mouse press and release, enter and exit, etc.

JButton state includes label, icons, colors, and button-model.

Model includes action-command, enabled, armed, pressed, rollover, selected (e.g. for checkbox), etc.

Page 30: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

30

Swing MVC Example 2 - JList List-model abstracts list of Objects and

change-events for contents of the list. Selection-model independent of model. View defined in terms of cell-renderers

that render individual model elements. Changes to model made by application

code, not by component interactions. Model changes handled by view, model

elements painted by cell-renderers.

Page 31: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

31

Direct Editing Example

class HtmlEmailCheckboxWatcher implements ItemListener { public void itemStateChanged(ItemEvent event) { boolean selected = (event.getStateChange() == ItemEvent.SELECTED); _recipient.setPrefersHtmlEmail(selected); } }

EmailRecipient _recipient;

JCheckBox prefersHtmlCheckbox = new JCheckBox("prefers HTML email"); prefersHtmlCheckBox.addItemListener(new HtmlEmailCheckboxWatcher());

public void editEmailRecipientPreferences(EmailRecipient recipient) { this._recipient = recipient; prefersHtmlCheckbox.setSelected(recipient.getPrefersHtmlEmail()); … }

Page 32: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

32

A Closer Look at Direct Editing Initialize from Model property value. Use listener to change property value. Simple, but deceptively simplistic. Missing numerous important features:

enable/disable logic validation, propagation, transactions apply, reset, undo, redo notification of model changes to listeners

Direct use of model API by UI code

Page 33: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

Model-Oriented Architectures

Model-Oriented Application = Model Objects + Coordinated Uses of Model Objects

Page 34: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

34

Model-Oriented Frameworks

Abstract Class-Level Metadata Model-Oriented Form-Based Editing Application-Level MVC Frameworks for Tables and Trees Master-Detail Relationships Support for Model Class-Hierarchies More Object-Oriented Design Patterns

Page 35: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

35

Abstract Class-Level Metadata Not all so-called models are Beans.

“tagged” hash-tables XML DOM sub-trees LDAP or JNDI entries URLs with query parameters database result-set wrappers

Frequently no built-in validation logic. Rarely any propagation logic. Rarely any change-listener support.

Page 36: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

36

Class-Level Metadata for the UI

May want additional (often extrinsic) properties just for the user interface.

Want controlled, secure exposure of business object internals.

May want higher levels of abstraction than back-end representations.

Want to localize dependencies on back-end representation details.

Page 37: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

37

Model Metadata Framework

ModelObjectAdapter

Object getAspectValue(ModelAspectId)void setAspectValue(ModelAspectId, Object)Object getModelObject()void validateModel() throws ModelValidationException

ModelDescriptor

ModelObjectAdapter makeModelObjectAdapter(Object)ModelAspectAdapter getModelAspectAdapter(ModelAspectId)void addModelObjectValidator(ModelObjectValidator)void validateModel(ModelObjectAdapter)

ModelAspectAdapter*

Object getAspectValue(ModelObjectAdapter)*void setAspectValue(ModelObjectAdapter, Object)*Class getModelAspectType()boolean isReadOnlyAspect()

ModelAspectId

String getName()

modelDescriptor

modelAspectAdapters

ApplicationModel ObjectInstance

ApplicationModel Object

Class(or other metadata)

n

n

1

1

1 1

1 1

11

n

1

class

level in

form

ati

on

inst

an

ce level

Page 38: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

38

Inside ModelObjectAdapterpublic class ModelObjectAdapter { protected final Object _modelObject; protected final ModelDescriptor _modelDescriptor; ... public Object getAspectValue(ModelAspectId aspectId) throws NoSuchAspectException { ModelAspectAdapter modelAspectAdapter = _modelDescriptor.getModelAspectAdapter(aspectId); return modelAspectAdapter.getAspectValue(this, _modelObject); } public void setAspectValue(ModelAspectId aspectId, Object newValue) throws PropertyVetoException, NoSuchAspectException { ModelAspectAdapter modelAspectAdapter = _modelDescriptor.getModelAspectAdapter(aspectId); modelAspectAdapter.setAspectValue(this, _modelObject, newValue); } ...}

Page 39: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

39

HashTable ModelAspectAdapterpublic class HashTableAspectAdapter extends ModelAspectAdapter{ private String _key; public HashTableAspectAdapter(String key) { super(ModelAspectId.forName(key), Object.class); this._key = key; } protected Object getAspectValue (Object modelObject, ModelObjectAdapter objectAdapter) { HashTable hashTable = (HashTable) modelObject; return hashTable.get(_key); } protected void setAspectValue (Object model, Object value, ModelObjectAdapter moa) { … }}

Page 40: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

40

Levels of Validation Text input validation

keystroke at a time, or when losing focus based on logical type of data, not use

Field level validation checked on aspect-value assignment

Object level validation checked on apply, create, delete

Contextual validation consistency or uniqueness constraints may be performed externally (e.g. DBMS)

Page 41: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

41

Validation Failure Feedback

Constrain input to avoid errors disable things that are not applicable offer constrained range or set of choices custom typed chooser components

Change color to indicate problems color of border, background, label, etc.

Use “what’s wrong” tool-tips normal tool-tips explain purpose of field

Alert dialog, status line, message log

Page 42: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

Adapters for Edit Components

Page 43: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

43

Abstract Aspect-Editors/Viewers Generalized “data-bound” controls. Allow any kind of UI component. Allow any kind of application model. Want a uniform abstract interface to:

associate with specific ModelAspectId initialize from model-aspect-value notify when edits have been made provide edited model-aspect-value provide unapplied view-aspect-value

Page 44: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

44

ViewAspectAdapter Features

Conversion between model-aspect-values and view-aspect-values.

Conversion from component-specific events to uniform change-events.

Customizable enabled-for-edit rules. One adapter type for each component

type (sometimes more). Aspect identified by ModelAspectId.

Page 45: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

45

ViewAspectAdapter

ViewAspectAdapter

void setModelAspectValue(Object)Object getModelAspectValue()void setEditable(boolean)addChangeListener(ChangeListener)

EditRule ModelAspectIdViewValueConverter

AWT/Swing Component

Page 46: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

46

Inside JTextFieldAdapterpublic class JTextFieldAdapter extends ViewAspectAdapter implements DocumentListener{ public JTextFieldAdapter(ModelAspectId modelAspectId, JTextField textField, EditRule editRule, ViewValueConverter valueConverter, ModelEditMediator editMediator) { super(modelAspectId, editRule, valueConverter, editMediator); this._textField = textField; textField.getDocument().addDocumentListener(this); } public void setEditable(boolean editable) { _textField.setEditable(editable); } public void setViewAspectValue(Object viewVal) { _textField.setText((viewVal == null) ? "" : viewVal.toString()); } public void insertUpdate(DocumentEvent event) { fireChangeEvent(); }

Page 47: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

47

Prefer Renderers to Converters

Many Swing models support Objects Lists, Trees, Tables, Combo-Boxes, etc.

Can convert between application models and strings (for example) May require cumbersome lookup logic

Can render model aspects instead Swing model can hold the app model Custom renderer extracts selected info

Page 48: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

48

Example Custom Cell Renderer

class EmailRecipientCellRenderer extends DefaultListCellRenderer{ public Component getListCellRendererComponent (JList list, Object val, int index, boolean select, boolean focus) { EmailRecipient recipient = (EmailRecipient) val; JLabel result = (JLabel) super. getListCellRendererComponent (list, recipient.getDisplayName(), index, select, focus); result.setIcon(getDisplayIcon(recipient)); return result; }}

JList recipientsList = new JList(allEmailRecipients); recipientsList.setCellRenderer(new EmailRecipientCellRenderer()); recipientsList.addListSelectionListener(...);

Page 49: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

Connecting Models to Views

Page 50: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

50

Connecting Models to Views Connect aspect-adapters on each side. Handle change notifications from view. Collect edited model-aspect values. Support apply and reset actions. Special treatment for new objects. Perform validation and report errors. Update the edited model-object. Notify listeners of changes, errors, etc.

Page 51: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

51

ModelEditMediator

ModelObjectAdapter

View AspectAdapters

Model AspectAdapters

ModelDescriptor

Model-ObjectPropagator

Model-ObjectValidators

Edit RuleView ValueConverter

User InterfaceComponent

ModelEditMediatorapply, reset, undo, redoeditModelObject(ModelObjectAdapter)editModelAsNewObject(ModelObjectAdapter)addModelEditListener(ModelEditListener)addModelEditFailureListener(…)

Page 52: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

52

ModelEditMediator Apply Logic Apply-action enabled on “new” or change. Changed aspect-ids collected during edit. Collect model-aspect-values to assign.

all editable view-aspect-adapters for new model Assign values through ModelObjectAdapter. Run model-object validators & propagator. Undo changes (non-new only) on failure. Notify edit-listeners, failure-listeners, etc. On success, reset view and actions.

Page 53: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

53

Edit, Apply, and Validate Logic

Swing Components andSwing Models

ViewAspectAdaptersand ViewValueConverters

ModelEditMediator andcollected model-aspect values

PropertyChangeEvents andUndoableModelEditEvents

ModelObjectAdapterModelDescriptor andModelAspectAdapters

ModelObjectValidators andModelObjectPropagator

Application Model Object

ModelEditListeners andModelEditFailureListeners

ModelAspectValidators

Page 54: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

54

Reset, Undo, and Redo Logic

Reset is same as starting over re-initialize all view-aspect-adapters clear all pending changes and actions

When new model-aspect values are assigned, undo information collected Aspect-id, old-value, new-value Swing undo framework helps a lot

Undo/Redo information recorded and managed on a per-object basis

Page 55: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

55

Multi-Part Forms

Some models have a lot of aspects. Organize into logical groups of aspects. Tabbed-folder organization, wizards, … Complex view, still just one model. Creation “wizards” delay apply logic. Dependencies between values of fields. Want to use same logic for complex

and simple forms.

Page 56: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

56

Summary of Concepts So Far MVC: Model View Controller

event-listeners, view-independent model lower-level events to higher-level actions

Class-level metadata and model adapters uniform, flexible, extensible, powerful delegation to model-aspect-adapters

Adapters for UI components too manipulated with model-aspect-values

Edit-Mediator provides common behavior independent of both model and view “form-level” controller component

Page 57: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

57

Application-Level MVC

Application Model• view-independent• model-change source• defines app behavior• high-level abstraction

Application View• render model aspects• model-change listener• fires initiator-events• organizes models

App Controller• initiator-event listener• update app models• use app-model API• select alternative views

model change events

model state changes andmethod calls

initiatorevents

model state

queries

view control

Page 58: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

58

Application-Level MVC

Initiator-events from apply, reset, undo, redo, create, delete actions.

Application Models presented to UI with abstract metadata and adapters.

Almost everything done in Swing is part of the Application View.

ModelEditMediator provides sound foundation for Application Controllers.

Page 59: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

59

Type-Specific Model-Edit-Forms

ModelEditForm

getEditTypeKey()

Form Container &Edit Components

ModelEditMediatorModelDescriptor

getEditTypeKey()

ModelAspectAdaptersViewAspectAdapters

View Controller Model

Page 60: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

Organizing Models in Views

Page 61: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

61

Model-Oriented Tables & Trees

Organize for Select, Add, Delete Display view-oriented model aspects Adapt models to rows, sub-trees, etc. Import and export of model objects

Use internal representation in application Queries, filtering, sorting, etc. Refresh, caching, & performance issues Concurrent access to external data

Page 62: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

62

Model-Oriented Tables ModelListTableModel

Subclass of AbstractTableModel Manages an ArrayList of model-objects Model-object per row, aspect per column Keeps track of sorting state

ModelTableColumnAdapter Façade and Factory for TableColumn getColumnValue(Object model, int row) Helps manage headers, sorting, widths,

custom cell-renderers, etc.

Page 63: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

63

Using Model-Oriented Tables

ModelTableColumnAdapter firstNameColumnAdapter = new ExprTableColumnAdapter("firstName", // property name "First Name", // column header label false, // editable String.class, // type for sorting, etc. 40, 120, 400); // min, normal, max widths...ModelTableColumnAdapter[] modelColumnAdapters = { firstNameColumnAdapter, lastNameColumnAdapter, ...};

ModelTable attendeesTable = new ModelTable(SeminarAttendee.class, modelColumnAdapters);attendeesTable.getSelectionModel().addListSelectionListener(...);

attendeesTable.getModelListTableModel().setContents(getAllAttendees());

Page 64: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

64

Using Model-Oriented Tables

Create with custom column adapters. Customize rendering by column.

Register selection listener. Configure to support column sorting. Load with collection of model objects. Add new items to table-model. Delete items from table model. Load table from external data source.

Page 65: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

65

Model-Oriented Trees Each node responsible for computing

its own children, when asked. ModelTreeNode supports structural

hierarchy of application model objects. One-level-deep option for getting

expansion indicators right. Simple, powerful refresh logic based

on child-nodes computation. Basic tree-cell-renderer configuration:

getNodeIcon(…), getNodeString(…)

Page 66: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

66

Using Model-Oriented Treesclass JavaClassTreeNode extends ModelTreeNode { public JavaClassTreeNode(Class javaClass) { this._javaClass = javaClass; } public List computeChildren() { ArrayList children = new ArrayList(); Method[] methods = _javaClass.getMethods(); for (int i = 0, n = methods.length; i < n; i++) children.add(new JavaMethodTreeNode(methods[i]); ... return(children); } public Icon getNodeIcon(boolean expanded, boolean selected, …) { if (_javaClass.isInterface()) return INTERFACE_ICON; ... } public String getNodeString(boolean expanded, boolean selected, …) { return _javaClass.getName(); }}

Page 67: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

67

Coordinating Tables and Forms

TableFormMediator

selectionChanged(SelectionEvent)getDeleteRowAction()

getNewInstanceAction()

ModelTable

ModelEditFormManager

getEditTypeKey(Object model)editModelObject(Object model)

createAndEditNewInstance()

ModelEditForms ModelObjectFactory

Page 68: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

68

Inside TableFormMediator

public void valueChanged(ListSelectionEvent listSelectionEvent) { // overrule selection change if changes would be lost if (_formManager.hasUnappliedChanges() && !handleUnappliedChanges()) { revertSelection(_editedRowModel); return; }

// clear model from current edit-form EditForm activeForm = _formManager.getActiveEditForm(); if (activeForm != null) _formManager.editModelObject(null, activeForm.getEditTypeKey());

// get selected model-object from selected row index int row = _table.getSelectedRow(); if ((row >= 0) && (row < _tableModel.getRowCount())) { // edit the model-object in the appropriate edit-form _editedRowModel = _tableModel.getRowModel(row); Object editTypeKey = _formManager.getEditTypeKey(_editedRowModel); _formManager.editModelObject(_editedRowModel, editTypeKey); }}

Page 69: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

69

Application-MVC Controllers Specify initiator events and sources

Action events, model-edit events, etc. Specify responses to initiator events

Update application model state Call application model methods Import, export, and sync models

Specify what the UI should do next Translate handled initiator events into

application behavior

Page 70: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

70

An Example Editor Application External XML

Internal Java XJX framework

Several tables Different Tabs Many subclasses Counts in Tabs

Consistent UI Same behavior Early feedback

Page 71: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

71

Model-Oriented Data Flow

External Data(XML / DBMS)

Externalto JavaModel

Translation

TableFormMediator

EditFormManager

EditForm

ModelEditMediator

Page 72: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

72

Application-Level MVC

Application Model• view-independent• model-change source• defines app behavior• high-level abstraction

Application View• edit model aspects• render model objects• organize model objects• fire initiator-events

App Controller• initiator-event listener• update app models• use app-model API• select alternative views

model change events

model state changes andmethod calls

initiatorevents

model state

queries

view control

Page 73: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

Event-Handling Tips & Patterns

Page 74: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

74

Event Handling Strategies

Configure UI Components with Actions Self-enabling Actions Relay-Actions & Action Wrappers ActionListeners without Inner Classes Failure Listeners / Exception Handlers Swing’s Single-Thread Restriction Long-Running Operations

Page 75: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

75

Actions as Abstract Initiators Associate Actions with

Buttons, toolbar-buttons, menu-items, … When Action enabled, components too

Listeners register with Actions Same Action fired from different places

Actions can configure UI components Label, icon, mnemonic, accelerator, …

Extend AbstractAction for even more Component initialization, enable logic, …

Page 76: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

76

Self-Enabling Actions Important to enable/disable Actions

appropriately. Can use a different tool-tip when

Action not enabled, to say why not. Views can use central action-manager

with self-enabling Actions. Encapsulate common enable logic:

Number and types of selections Selected object state – property values

Page 77: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

77

RelayActions & Action Wrappers

In a Façade, want to relay events from within, with façade as source.

May want more control over when façade’s Actions are enabled.

Chain-of-Responsibility Pattern for configurable properties.

Chain-reaction of ActionListeners and ActionEvents.

Page 78: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

78

RelayActions & Action Wrapperspublic class RelayAction extends AbstractAction implements ActionListener, PropertyChangeListener{ public RelayAction(Action targetAction) { this._allowEnable = true; setTargetAction(targetAction); // register self as listener } public void propertyChange(PropertyChangeEvent event) { if ("enabled".equals(event.getPropertyName()) setEnabledInternal(); } public void setEnabled(boolean allowEnable) { this._allowEnable = allowEnable; setEnabledInternal(); } private void setEnabledInternal() { super.setEnabled(_allowEnable && _targetAction.isEnabled()); } ...

Page 79: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

79

Action Listeners without Inner Classes

Use reflection to make a call to a method that takes an ActionEvent.

Encapsulate the Method call & other state in an ActionListener subclass.

Create instances of ActionListener subclass instead of many subclasses.

Listeners implemented in terms of methods in classes that uses them.

Page 80: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

80

MethodProxyActionListener/** * MethodProxyActionListener adapts any public instance method that * takes an ActionEvent parameter to the ActionListener interface. */public class MethodProxyActionListener implements ActionListener { public MethodProxyActionListener(Object instance, String methodName) throws NoSuchMethodException { _instance = instance; _method = this.findMethod(instance.getClass(), methodName); } public void actionPerformed(ActionEvent event) { try { _method.invoke(_instance, new Object[] { event }); } catch (Exception e) { // InvocationTargetException or IllegalAccessException rethrowAsRuntimeExceptionOrError(e); } } ...

someAction.addActionListener (new MethodProxyActionListener(handlerObj, "handleSomeAction"));

Page 81: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

81

Failure-Event Listeners

Usually to report errors, not fix them. Multiple event-listeners possible. Failure-event has all the details. Event may be delivered long after

exception has been handled internally. Variation: attempt to fix problem

e.g. repair broken connection, try again listeners should mark the event for retry

Page 82: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

82

Swing’s Single-Thread Design

Most Swing components and models are not thread-safe (by design).

Intended to be used and modified only on event-dispatch-thread.

To update components & models from another thread, use invokeLater(…).

invokeLater(Runnable) puts a special kind of event on the event-queue.

Page 83: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

83

Long Running Activities Use separate, cancelable threads.

Respond promptly to cancel requests. Disable appropriate parts of UI. Use events and listeners to notify:

Start and end of thread execution Use cancelable-thread-manager

Manage threads, coordinate cancel, etc. Relay events to general listeners

Use invokeLater to handle completion.

Page 84: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

84

Inside CancelableThread – 1public CancelableThread(Runnable innerRunnable) { this._innerRunnable = innerRunnable;}

public void run() { this.started = true; Throwable throwable = null; try { fireThreadStarted(_innerRunnable, this); _innerRunnable.run(); } catch (RuntimeException e) { throwable = e; } catch (ThreadDeath t) { throwable = t; } finally { this.completed = true; // notify about thread completion two different ways synchronized (this) { this.notify(); } fireThreadCompleted(_innerRunnable, this, throwable); }}

Page 85: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

85

Inside CancelableThread – 2public void cancel() { _cancelled = true; // mark thread as cancelled this.interrupt(); // interrupt active wait calls}

public boolean terminate(int maxWaitMillis, boolean forceTermination) { if (!this.isAlive()) return true; this.cancel(); // request termination politely try { this.join(maxWaitMillis); // wait for termination or timeout } catch (InterruptedException e) { // safe to ignore here } if (!this.isAlive()) return true; if (forceTermination) this.stop(); // force hostile termination return false;}

Page 86: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

Swing Layout Manager Tips

Page 87: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

87

Swing Layout Manager Basics

Purpose and rationale Layout Manager Conceptual Model

Relative 2D constraints Constraints propagate bottom-up

Layout Roles & Responsibilities Important API Creating new Layout Managers

Page 88: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

88

Layout Manager Rationale Best (maybe only) way to build cross-

platform user interfaces. Size and shape of components based

on configured properties. Labels, icons, borders, fonts, children, …

Containers should try to respect preferred sizes of child components.

Expressing multiple levels of constraints sounds harder than it is.

Page 89: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

89

Expressing Systems of Constraints in a 2-Dimensional Space

Layout Managers solve constraints. Flexible constraints usually relative. Easy to learn how to set the table:

Absolute relative positioning Absolute relative (preferred) sizes Absolute relative spacing Absolute relative orientation

Good layout managers add clarity.

Page 90: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

90

Users of Layout Managers Programmers

Code clarity and succinctness Choice of special-purpose alternatives Able to collaborate with other objects

Visual Layout Tools General-purpose visual metaphor Visual representation of constraints Often too complex to use by hand

Special-purpose layouts can wrap and delegate to general-purpose layouts.

Page 91: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

91

Setting the Table

Page 92: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

92

LayoutManager Responsibilities Help compute Container’s preferred size

In terms of components’ preferred sizes In terms of insets, spacing, is-visible In terms of specified constraints (e.g. top)

Assign sizes and positions to components Using same constraints as above Don’t change container’s size or position

Components provide own preferred sizes Frequently using their own layout managers

Page 93: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

93

Phases of Container Layout Compute Window’s preferred size

Compute child preferred sizes (recursive) Combine using window’s layout manager

Assign the Window’s size and position Layout each child component

Assign size and position to each child Ask the child to perform layout on itself

Layout each child component Assign size and position to each child Ask the child to perform layout on itself

Page 94: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

94

Layout Roles and Methods

Component

Dimension getPreferredSize()Insets getInsets()

Container / JComponent

void doLayout()Component getComponent(int index)

void revalidate()

LayoutManager

Dimension preferredLayoutSize(Container)void layoutContainer(Container)

Concrete LayoutManager

extends implements

layout

Page 95: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

95

Import Swing Layout API Important LayoutManager methods:

Dimension preferredLayoutSize(Container) void layoutContainer(Container) void addLayoutComponent(String*, Component) void removeLayoutComponent(Component)

Container methods (and others): void setLayout(LayoutManager) void setBounds(int x, int y, int w, int h) void doLayout() Dimension getPreferredSize() int getVisibleRowCount() (in JList) invalidate(), validate(), revalidate()

Page 96: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

96

Containers and Layout Managerspublic class Container extends Component { public void setLayout(LayoutManager layout) { this._layout = layout; } public Dimension getPreferredSize() { return _layout.preferredLayoutSize(this); } public void doLayout() { _layout.layoutContainer(this); } …

public class AnyLayout implements LayoutManager { public Dimension preferredLayoutSize(Container container) { … container.getComponent(i).getPreferredSize() … } public void layoutContainer(Container container) { Dimension containerSize = container.getSize(); Insets containerInsets = container.getInsets(); … child.setBounds(childX, childY, childWidth, childHeight); …

Page 97: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

97

Swing Layout Rules of Thumb Only LayoutManagers call setBounds()

(except for top-level windows). Almost never call setPreferredSize(). Implement Scrollable as appropriate. Break things down into simpler parts.

Use sub-containers with their own layouts Encapsulate common uses of complex

layout managers. revalidate() when composition changes.

Page 98: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

98

Custom Layout Managers Container-owned or sharable. Compute preferred-size abstractly.

Container’s current size doesn’t matter. Use preferred sizes of current children. Don’t forget the container’s insets.

Layout container concretely. Don’t change the container’s size, position, etc. Assign sizes and positions to all children. Don’t invalidate layout of anything else. Don’t forget the container’s insets.

How to handle excess/insufficient space. Stretch, align, squash, abbreviate, etc.

Page 99: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

99

Summary and Review User interfaces are for expressing

intentions and maintaining confidence. Check for and report success & problems.

Mature user interfaces exhibit two levels of Model-View-Controller. Application models and controllers should

be almost independent of user interface. Good frameworks maximize reuse and

minimize effort. Complex operations same for many apps. Roles the same for many apps.

Page 100: Model-Oriented Architectures and Frameworks for  Swing-Based User Interfaces

GBCACM PDS April 30, 2005

Dan Jacobs http://www.modelobjects.com

100

Questions and Discussion