Model-Oriented Architectures and Frameworks for Swing-Based User Interfaces - PowerPoint PPT Presentation

About This Presentation
Title:

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

Description:

... Recognizable patterns that appear over and ... on manageable complexity, but some design patterns are ... and XML documents Data warehouse ... – PowerPoint PPT presentation

Number of Views:260
Avg rating:3.0/5.0
Slides: 101
Provided by: Danie177
Category:

less

Transcript and Presenter's Notes

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


1
Model-Oriented Architectures and Frameworks for
Swing-Based User Interfaces
  • Dan Jacobsdjacobs_at_modelobjects.com
  • 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

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

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

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

5
Overview of AWT and Swing
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

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

8
AWT/Swing Software Layers
Application Code
Many other standard extensions
J2SE
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.

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 doesnt see lightweight comps

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.

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

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

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)

15
Object-Oriented Design Patterns and Frameworks
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.

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
  • Dont take it too far some things are not
    independent of each other

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.

19
Object Adapter Design Pattern
interface NewPlugProvider NewPlug getNewPlug()
class NewSocket plugIn(NewPlug)
references
implements
class OldHairDryer OldPlug getPlug()boolean
getBlowerOn() setBlowerOn(boolean)
NewPlugAdapterimplements NewPlugProvider NewPlug
getNewPlug() private OldSocket
_oldSocket
references
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 Swings implementation
  • Event sources follow naming conventions
  • Listeners notified by synchronous calls
  • Some event objects are modifiable

21
Event Listener Design Pattern
FooEventSource addFooListener(FooListener) remove
FooListener(FooListener) fireFooEvent1() fireFooEv
ent2()
FooListener handleFooEvent1(FooEvent) handleFooEv
ent2(FooEvent)
listeners
event-source
implements
FooEvent getSource() getEventType() getEventDetai
ls()
ConcreteFooListener handleFooEvent1(FooEvent) han
dleFooEvent2(FooEvent)
event
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

23
PropertyChangeListener Pattern
class ChangeHandler implements PropertyChangeListe
ner public void propertyChange(PropertyChang
eEvent event) Object changeSource
event.getSource() String propertyName
event.getPropertyName() Object oldValue
event.getOldValue() Object newValue
event.getNewValue() ...
ChangeHandler handler new
ChangeHandler() objectToWatch.addPropertyChangeL
istener(handler) doSomethingTo(objectToWatch)

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 dont have to be large or complex
    the fewer roles, the better.
  • Can offer best kind of code reuse.

25
Model View Controller Pattern
A Frequently Misunderstood Pattern
lta href"dosomething?foo3barno"gtClick Herelt/agt
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.

27
Model View Controller Pattern
  • Model
  • view-independent
  • object encapsulation
  • change-event source
  • first-class object

model change events
model state changes
model state queries
  • 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

gesture events
view control
28
MVC Variant Used in Swing
  • View and Controller combined into a single
    look-and-feel (LF) object.
  • View-specific state in Component and LF,
    view-independent state in Model.
  • Models are specified by interfaces, and default
    implementations provided.
  • Some components rarely expose the model, and
    support listeners directly.

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.

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.

31
Direct Editing Example
EmailRecipient _recipient JCheckBox
prefersHtmlCheckbox new JCheckBox("prefers HTML
email") prefersHtmlCheckBox.addItemListener(n
ew HtmlEmailCheckboxWatcher()) public void
editEmailRecipientPreferences(EmailRecipient
recipient) this._recipient
recipient prefersHtmlCheckbox.setSelected
(recipient.getPrefersHtmlEmail())
class HtmlEmailCheckboxWatcher implements
ItemListener public void
itemStateChanged(ItemEvent event)
boolean selected
(event.getStateChange() ItemEvent.SELECTED)
_recipient.setPrefersHtmlEmail(selected)

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

33
Model-Oriented Architectures
Model-Oriented Application Model Objects
Coordinated Uses of Model Objects
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

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.

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.

37
Model Metadata Framework
ModelObjectAdapter Object getAspectValue(ModelAsp
ectId) void setAspectValue(ModelAspectId,
Object) Object getModelObject() void
validateModel() throws ModelValidationException
Application Model Object Instance
instance level
1
1
n
n
modelDescriptor
1
1
ModelDescriptor ModelObjectAdapter
makeModelObjectAdapter(Object) ModelAspectAdapter
getModelAspectAdapter(ModelAspectId) void
addModelObjectValidator(ModelObjectValidator) void
validateModel(ModelObjectAdapter)
Application Model Object Class (or other metadata)
1
1
1
class level information
modelAspectAdapters
n
ModelAspectAdapter Object getAspectValue(ModelOb
jectAdapter) void setAspectValue(ModelObjectAdapt
er, Object) Class getModelAspectType() boolean
isReadOnlyAspect()
ModelAspectId String getName()
1
1
38
Inside ModelObjectAdapter
public class ModelObjectAdapter protected
final Object _modelObject protected final
ModelDescriptor _modelDescriptor ...
public Object getAspectValue(ModelAspectId
aspectId) throws NoSuchAspectException
ModelAspectAdapter modelAspectAdapter
_modelDescriptor.getModelAspectAdapter(a
spectId) return modelAspectAdapter.getAspe
ctValue(this, _modelObject) public void
setAspectValue(ModelAspectId aspectId, Object
newValue) throws PropertyVetoException,
NoSuchAspectException
ModelAspectAdapter modelAspectAdapter
_modelDescriptor.getModelAspectAdapter(aspectId)
modelAspectAdapter.setAspectValue(this,
_modelObject, newValue) ...
39
HashTable ModelAspectAdapter
public 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)
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)

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 whats wrong tool-tips
  • normal tool-tips explain purpose of field
  • Alert dialog, status line, message log

42
Adapters for Edit Components
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

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.

45
ViewAspectAdapter
EditRule
ModelAspectId
ViewValueConverter
ViewAspectAdapter void setModelAspectValue(Object
) Object getModelAspectValue() void
setEditable(boolean) addChangeListener(ChangeListe
ner)
AWT/Swing Component
46
Inside JTextFieldAdapter
public class JTextFieldAdapter extends
ViewAspectAdapter implements
DocumentListener public JTextFieldAdapter(Mo
delAspectId modelAspectId,
JTextField textField, EditRule editRule,
ViewValueConverter
valueConverter,
ModelEditMediator editMediator)
super(modelAspectId, editRule, valueConverter,
editMediator) this._textField
textField textField.getDocument().addDocu
mentListener(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()
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

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(getDisplayI
con(recipient)) return result
JList recipientsList new JList(allEmailRecip
ients) recipientsList.setCellRenderer(new
EmailRecipientCellRenderer())
recipientsList.addListSelectionListener(...)
49
Connecting Models to Views
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.

51
ModelEditMediator
ModelObjectAdapter
Model Aspect Adapters
User Interface Component
ModelEditMediator
View Aspect Adapters
Model Descriptor
apply, reset, undo, redo editModelObject(ModelObje
ctAdapter) editModelAsNewObject(ModelObjectAdapter
) addModelEditListener(ModelEditListener) addModel
EditFailureListener()
Model-Object Propagator
Model-Object Validators
Edit Rule
View Value Converter
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.

53
Edit, Apply, and Validate Logic
ModelObjectAdapter
ModelDescriptor and ModelAspectAdapters
PropertyChangeEvents and UndoableModelEditEvents
ModelAspectValidators
ModelEditMediator and collected model-aspect
values
Application Model Object
ViewAspectAdapters and ViewValueConverters
ModelObjectValidators and ModelObjectPropagator
Swing Components and Swing Models
ModelEditListeners and ModelEditFailureListeners
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

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.

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

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

model change events
model state changes and method calls
model state queries
  • 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

initiator events
view control
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.

59
Type-Specific Model-Edit-Forms
ModelEditForm getEditTypeKey()
View
Controller
Model
Form Container Edit Components
ModelEditMediator
ModelDescriptor getEditTypeKey()
ModelAspectAdapters
ViewAspectAdapters
60
Organizing Models in Views
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

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.

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.getSelectionM
odel().addListSelectionListener(...) attendeesTa
ble.getModelListTableModel().setContents(getAllAtt
endees())
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.

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()

66
Using Model-Oriented Trees
class 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 lt 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()

67
Coordinating Tables and Forms
TableFormMediator selectionChanged(SelectionEvent
) getDeleteRowAction() getNewInstanceAction()
ModelEditFormManager getEditTypeKey(Object
model) editModelObject(Object model) createAndEdit
NewInstance()
ModelTable
ModelEditForms
ModelObjectFactory
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.editMode
lObject(null, activeForm.getEditTypeKey())
// get selected model-object from selected row
index int row _table.getSelectedRow()
if ((row gt 0) (row lt _tableModel.getRowCount()
)) // edit the model-object in the
appropriate edit-form _editedRowModel
_tableModel.getRowModel(row) Object
editTypeKey _formManager.getEditTypeKey(_editedR
owModel) _formManager.editModelObject(_ed
itedRowModel, editTypeKey)
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

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

71
Model-Oriented Data Flow
TableFormMediator
External to Java Model Translation
EditFormManager
EditForm
External Data (XML / DBMS)
ModelEditMediator
72
Application-Level MVC
  • Application Model
  • view-independent
  • model-change source
  • defines app behavior
  • high-level abstraction

model change events
model state changes and method calls
model state queries
  • 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

initiator events
view control
73
Event-Handling Tips Patterns
74
Event Handling Strategies
  • Configure UI Components with Actions
  • Self-enabling Actions
  • Relay-Actions Action Wrappers
  • ActionListeners without Inner Classes
  • Failure Listeners / Exception Handlers
  • Swings Single-Thread Restriction
  • Long-Running Operations

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,

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

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çades Actions
    are enabled.
  • Chain-of-Responsibility Pattern for configurable
    properties.
  • Chain-reaction of ActionListeners and
    ActionEvents.

78
RelayActions Action Wrappers
public class RelayAction extends AbstractAction
implements ActionListener, PropertyChangeListen
er 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(_a
llowEnable _targetAction.isEnabled())
...
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.

80
MethodProxyActionListener
/ MethodProxyActionListener adapts any
public instance method that takes an
ActionEvent parameter to the ActionListener
interface. / public class MethodProxyActionListe
ner 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"))
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

82
Swings 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.

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.

84
Inside CancelableThread 1
public CancelableThread(Runnable innerRunnable)
this._innerRunnable innerRunnable publ
ic 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)
85
Inside CancelableThread 2
public 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
86
Swing Layout Manager Tips
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

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.

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.

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.

91
Setting the Table
92
LayoutManager Responsibilities
  • Help compute Containers 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
  • Dont change containers size or position
  • Components provide own preferred sizes
  • Frequently using their own layout managers

93
Phases of Container Layout
  • Compute Windows preferred size
  • Compute child preferred sizes (recursive)
  • Combine using windows layout manager
  • Assign the Windows 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

94
Layout Roles and Methods
Component Dimension getPreferredSize() Insets
getInsets()
LayoutManager Dimension preferredLayoutSize(Conta
iner) void layoutContainer(Container)
implements
extends
Container / JComponent void doLayout() Component
getComponent(int index) void revalidate()
Concrete LayoutManager
layout
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()

96
Containers and Layout Managers
public 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(Contain
er container) container.getComponent(i
).getPreferredSize() public void
layoutContainer(Container container)
Dimension containerSize container.getSize()
Insets containerInsets container.getInsets(
) child.setBounds(childX,
childY, childWidth, childHeight)
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.

98
Custom Layout Managers
  • Container-owned or sharable.
  • Compute preferred-size abstractly.
  • Containers current size doesnt matter.
  • Use preferred sizes of current children.
  • Dont forget the containers insets.
  • Layout container concretely.
  • Dont change the containers size, position, etc.
  • Assign sizes and positions to all children.
  • Dont invalidate layout of anything else.
  • Dont forget the containers insets.
  • How to handle excess/insufficient space.
  • Stretch, align, squash, abbreviate, etc.

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.

100
Questions and Discussion
Write a Comment
User Comments (0)
About PowerShow.com