0% found this document useful (0 votes)
32 views95 pages

Writing A Large Application in The Real World Based On The Java™ Foundation Class/Swing (JFC/Swing) API

Almost anyone can write a small GUI application We will learn how to write a large GUI application that is both well built and easy to use. Using the JFC / Swing API alone is too low-level Hard to use the API in a consistent way different programmers will create different looks applications can look very different.

Uploaded by

Don Camillo
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
32 views95 pages

Writing A Large Application in The Real World Based On The Java™ Foundation Class/Swing (JFC/Swing) API

Almost anyone can write a small GUI application We will learn how to write a large GUI application that is both well built and easy to use. Using the JFC / Swing API alone is too low-level Hard to use the API in a consistent way different programmers will create different looks applications can look very different.

Uploaded by

Don Camillo
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 95

Writing a Large Application in the Real World Based on the Java Foundation Class/Swing (JFC/Swing) API

Trey Roby Senior Computer Scientist California Institute of Technology


Session 1703

Why You Are Here?

Almost anyone can write a small GUI application We will learn how to write a large GUI application that is both well built and easy to use

Session 1703

Learning Objectives
Improve your skills with large GUI applications by:
Understanding the key design elements Knowing where to start your program Knowing how to finish your program

Session 1703

Speakers Qualifications
Large GUI-based applications for 12 years Java AWT and JFC/Swing technology for 4 years OO Development for 10 years

Session 1703

Large GUI Applications

Like a towering sky-scraper, large applications have a deep foundation...

Session 1703

What Well Cover


1. Developing a GUI Infrastructure 2. Building applications around Actions 3. Polishing the application 4. Installing on multiple platforms

Session 1703

Design Goals for a Deep Foundation


Homogenous Extensible Complete

Session 1703

Homogenous
Consistent behavior Consistent layout

Session 1703

Extensible
Easy to add more features Re-usable core components

Session 1703

Complete
Application appears finished All the implied features are there
Drag & drop Tool tips Toolbars Help

Installs easily

10

Session 1703

Homogeneous Developing a GUI Infrastructure

Session 1703

The Challenge
The JFC/Swing API alone is too low-level Hard to use the JFC/Swing API in a consistent way
Different programmers will create different looks

Applications can look very different

12

Session 1703

What a GUI Infrastructure Package IS


Classes that complement JFC/Swing objects Classes that combine JFC/Swing objects Classes that build JFC/Swing objects
Look & Feel adjustments made in one place

13

Session 1703

What a GUI Infrastructure Package IS NOT


A replacement for JFC/Swing technology A layer on top of JFC/Swing technology

14

Session 1703

Using a GUI Infrastructure PackageThe Big Picture


Application Code

GUI Infrastructure

JFC/Swing
15 Session 1703

Warning Signs of a Poor GUI Infrastructure


Over-used ActionListeners You lay out every individual swing object Frequent GridBagLayout code 70%80% of dialog code interacts with the JFC/Swing API

16

Session 1703

You Have a Solid GUI Infrastructure If You


Have predefined, re-usable components Use very few ActionListener Never create an OK button for a dialog Never write code for simple number validation

17

Session 1703

You Have a Solid GUI Infrastructure If You


Rarely write code to new basic components
JButton JMenuItem JCheckBox JTextField JRadioButton

Dont use default renderers for JTables

18

Session 1703

GUI Infrastructure Package


Application Code

GUI Infrastructure

JFC/Swing
19 Session 1703

GUI Infrastructure Package


Application Code

Dialogs Utilities

GUI Infrastructure Numeric Table Actions Entry Utilities

JFC/Swing
20 Session 1703

GUI Infrastructure Package


Application Code

Dialogs Utilities

GUI Infrastructure Numeric Table Actions Entry Utilities

Actions
JFC/Swing

21

Session 1703

Extensible Part 1 Building Around Actions

Session 1703

Actions Role in an Application


Functions

Action Action

Action Action Action Action Action Action Action

Application Code
Action Action Action

Data Structures

Start With Actions

GUI Infrastructure

JFC/Swing
23 Session 1703

What Is an Action?
Defines actionPerformed() Adds property Handling
addPropertyChangeListener() removePropertyChangeListener() putValue() getValue()
<<interface>>

ActionListener
<<interface>>

Action

Implements everything but actionPerformed()

AbstractAction

24

Session 1703

Actions Two-Way Communication


One Action could have many Buttons Action is an ActionListener on the Button Buttons adds a PropertyChangeListener to the Action The button will reflect Action property changes
Text Tooltip

25

Session 1703

Actions Two-Way Communication Example

Button1Action

26

Session 1703

Actions Two-Way Communication Example

PropertyChangeListener notifies Button when something has changed ActionListener Notifies Action when button is pushed

Button1Action Button1Action

27

Session 1703

Examples of Actions
Raise a Dialog Undo/Redo Cut, Copy, Paste Save Show parts of the User Interface Etc.

28

Session 1703

Writing an Action
Defines actionPerformed() Adds 6 more methods Implements everything but actionPerformed() Implements actionPerformed() to raise a dialog
29 Session 1703

<<interface>>

ActionListener
<<interface>>

Action AbstractAction

MyDialogAction

Example

NAME

ACCELERATOR_KEY

SHORT_DESCRIPTION

30

Session 1703

Example

ActionListener()

PropertyChangeListener()

MyDialogAction
31 Session 1703

Action to Raise a Dialog (1)


public class MyDialogAction extends AbstractAction { private MyDialog _dialog; public MyDialogAction(JFrame f) { putValue(NAME, Show My Dialog); putValue(SHORT_DESCRIPTION, Show my special dialog); putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke( d, Event.ALT_MASK )); _dialog= new MyDialog(f); } public void actionPerformed(ActionEvent ev) { _dialog.setVisible(true); } }
32 Session 1703

Action to Raise a Dialog (2)


public class MyDialogAction extends AbstractAction { private MyDialog _dialog; public MyDialogAction(JFrame f) {

} public void actionPerformed(ActionEvent ev) { } }


33 Session 1703

Action to Raise a Dialog (3)


public class MyDialogAction extends AbstractAction { private MyDialog _dialog; public MyDialogAction(JFrame f) {

} public void actionPerformed(ActionEvent ev) { } }


34 Session 1703

Action to Raise a Dialog (4)


public class MyDialogAction extends AbstractAction { private MyDialog _dialog; public MyDialogAction(JFrame f) {

} public void actionPerformed(ActionEvent ev) { } }


35 Session 1703

Action to Raise a Dialog (5)


public class MyDialogAction extends AbstractAction { private MyDialog _dialog; public MyDialogAction(JFrame f) {

} public void actionPerformed(ActionEvent ev) { _dialog.setVisible(true); } }


36 Session 1703

Action to Raise a Dialog (6)


public class MyDialogAction extends AbstractAction { private MyDialog _dialog; public MyDialogAction(JFrame f) {

Adding Properties

} public void actionPerformed(ActionEvent ev) { _dialog.setVisible(true); } }


37 Session 1703

Action to Raise a Dialog (7)


public class MyDialogAction extends AbstractAction { private MyDialog _dialog;

Adding Properties

public MyDialogAction(JFrame f) { putValue(NAME, Show My Dialog);

} public void actionPerformed(ActionEvent ev) { _dialog.setVisible(true); } }


38 Session 1703

Action to Raise a Dialog (8)


public class MyDialogAction extends AbstractAction { private MyDialog _dialog;

Adding Properties

public MyDialogAction(JFrame f) { putValue(NAME, Show My Dialog); putValue(SHORT_DESCRIPTION, Show my special dialog);

} public void actionPerformed(ActionEvent ev) { _dialog.setVisible(true); } }


39 Session 1703

Action to Raise a Dialog (9)


public class MyDialogAction extends AbstractAction { private MyDialog _dialog;

Adding Properties

public MyDialogAction(JFrame f) { putValue(NAME, Show My Dialog); putValue(SHORT_DESCRIPTION, Show my special dialog); putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke( d, Event.ALT_MASK )); } public void actionPerformed(ActionEvent ev) { _dialog.setVisible(true); } }
40 Session 1703

Action to Raise a Dialog (10)


public class MyDialogAction extends AbstractAction { private MyDialog _dialog; public MyDialogAction(JFrame f) { putValue(NAME, Show My Dialog); putValue(SHORT_DESCRIPTION, Show my special dialog); putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke( d, Event.ALT_MASK )); _dialog= new MyDialog(f); Create the Dialog } public void actionPerformed(ActionEvent ev) { _dialog.setVisible(true); } }
41 Session 1703

Action to Raise a Dialog (11)


public class MyDialogAction extends AbstractAction { private MyDialog _dialog; public MyDialogAction(JFrame f) { putValue(NAME, Show My Dialog); putValue(SHORT_DESCRIPTION, Show my special dialog); putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke( d, Event.ALT_MASK )); _dialog= new MyDialog(f); } public void actionPerformed(ActionEvent ev) { _dialog.setVisible(true); Every button push } }
42 Session 1703

Extensible Part 2 Extending Action and Using Property Files

Session 1703

Lets Make Actions Even Cooler


Actions do manage properties, but
Using putValue() is tedious Every Action has the same type of code

Add property files!

44

Session 1703

Expanding Property Use


Properties are named pieces of information java.util.Properties manages properties
Maintains a database of properties Reads properties from a file

45

Session 1703

Property File Example


myDialog.Name= Show My Dialog myDialog.ShortDescription= Show my \ special dialog myDialog.Accelerator=ctrl-d

These lines are in a property file e.g., actions.prop

46

Session 1703

Adding Loaded Properties to AbstractAction


AbstractActionno way to load properties We need a Subclass to
1. Add properties loading 2. Look for certain property types 3. Convert any necessary properties

47

Session 1703

PropDBSingleton Class
PropDB
getInstance() getProperty() load()

java.util.Properties
getProperty() load()

Singleton Class Queries a property with a key Add more properties from a file

48

Session 1703

Actions Role in Application

Application Code
1. Load Properties 2. Build Actions
Action Action Action Action Action Action Action Action Action Action Action Action

Property File Property File Property File

49

Session 1703

New ClassGeneralAction
Subclass of AbstractAction Add Property Loading

50

Session 1703

GeneralAction
Defines actionPerformed() Adds 6 more methods Implements everything but actionPerformed() Adds property loading but does not implement actionPerformed()
51 Session 1703

<<interface>>

ActionListener
<<interface>>

Action AbstractAction

GeneralAction

General Action Code (1)


public abstract class GeneralAction extends AbstractAction { public GeneralAction(String command) PropDB prop= PropDB.getInstance(); {

String s= prop.getProperty(command + "." + SHORT_DESCRIPTION); if (s != null) putValue(Action.SHORT_DESCRIPTION, s); s= prop.getProperty(command + "." + Action.NAME); if (s != null) putValue(Action.NAME, s); // // -- now do mnemonic, accelerator, etc // } }
52 Session 1703

General Action Code (2)


public abstract class GeneralAction extends AbstractAction { public GeneralAction(String command) {

Command parameter is the base name for properties

} }
53 Session 1703

General Action Code (3)


public abstract class GeneralAction extends AbstractAction { public GeneralAction(String command)
{

PropDB prop= PropDB.getInstance();

Get the Singleton property class

} }
54 Session 1703

General Action Code (4)


public abstract class GeneralAction extends AbstractAction { public GeneralAction(String command) PropDB prop= PropDB.getInstance(); {

String s= prop.getProperty(command + "." + SHORT_DESCRIPTION);

Get the SHORT_DESCRIPTION property

} }
55 Session 1703

General Action Code (5)


public abstract class GeneralAction extends AbstractAction { public GeneralAction(String command) PropDB prop= PropDB.getInstance(); {

String s= prop.getProperty(command + "." + SHORT_DESCRIPTION); if (s != null) putValue(SHORT_DESCRIPTION, s);

If the property exists, then add it to the Actions properties


} }
56 Session 1703

General Action Code (6)


public abstract class GeneralAction extends AbstractAction { public GeneralAction(String command) PropDB prop= PropDB.getInstance(); {

String s= prop.getProperty(command + "." + SHORT_DESCRIPTION); if (s != null) putValue(SHORT_DESCRIPTION, s); s= prop.getProperty(command + "." + NAME); if (s != null) putValue( NAME, s);

Do the same thing with NAME


} }
57 Session 1703

General Action Code (7)


public abstract class GeneralAction extends AbstractAction { public GeneralAction(String command) PropDB prop= PropDB.getInstance(); {

String s= prop.getProperty(command + "." + SHORT_DESCRIPTION); if (s != null) putValue(SHORT_DESCRIPTION, s); s= prop.getProperty(command + "." + NAME); if (s != null) putValue( NAME, s); // // -- now do mnemonic, accelerator, etc

Do the same thing with


} }
58 Session 1703

LONG_DESCRIPTION, SMALL_ICON, ACCELERATOR_KEY, MNEMONIC_KEY

GeneralAction Becomes New Base Class


<<interface>> ActionListener <<interface>> Action AbstractAction

MyDialogAction

59

Session 1703

GeneralAction Becomes New Base Class


<<interface>> ActionListener <<interface>> Action AbstractAction

GeneralAction
MyDialogAction

60

Session 1703

MyDialogAction Now Extends GeneralAction (1)


public class MyDialogAction extends GeneralAction { private MyDialog _dialog; public MyDialogAction(JFrame f) { super(myDialog); _dialog= new MyDialog(f); }

public void actionPerformed(ActionEvent ev) { _dialog.setVisible(true); } }

61

Session 1703

MyDialogAction Now Extends GeneralAction (2)


public class MyDialogAction extends GeneralAction { private MyDialog _dialog; public MyDialogAction(JFrame f) { super(myDialog); _dialog= new MyDialog(f); } myDialog to GeneralAction

public void actionPerformed(ActionEvent ev) { _dialog.setVisible(true); } }

62

Session 1703

MyDialogAction Now Extends GeneralAction (3)


public class MyDialogAction extends GeneralAction { private MyDialog _dialog; public MyDialogAction(JFrame f) { super(myDialog); _dialog= new MyDialog(f); }

Short!!! Same!!!

public void actionPerformed(ActionEvent ev) { _dialog.setVisible(true); } }

63

Session 1703

Property File ExampleAgain


myDialog.Name= Show My Dialog myDialog.ShortDescription= Show my \ special dialog myDialog.Accelerator=ctrl-d

This is the command name

64

Session 1703

ExampleUsing Property Files

MyDialogAction

Property File
65 Session 1703

Many Actions From Generalaction


<<interface>>

Action AbstractAction GeneralAction

CopyAction

DeleteAction

EnableAllAction

66

Session 1703

Many Actions
Action Action Action Action Action Action Action Action Action Action

Application Code
Action Action Action

Lots of Actions!!!

GUI Infrastructure

JFC/Swing
67 Session 1703

Can We Improve Startup Time?


Dialogs actions are slow to create Slow actions affect start-up time We need lazy initialization

68

Session 1703

LazyBuildAction
<<interface>>

Action AbstractAction GeneralAction LazyBuildAction build() activate()


69 Session 1703

Abstract: Does not define actionPerformed()

Abstract: Defines actionPerformed() Adds abstract methodsbuild() & activate()

LazyBuildAction
New abstract methods
build() activate()

public void actionPerformed(ActionEvent ev) { if (!_built) { Build the first time build(); _built= true; } activate(); }
70 Session 1703

LazyBuildAction
New abstract methods
build() activate()

public void actionPerformed(ActionEvent ev) { if (!_built) { build(); _built= true; } Activate every time activate(); }
71 Session 1703

Who Uses LazyBuildAction?


<<interface>>

Action AbstractAction GeneralAction MyDialogAction These guys are Finethey dont create a dialog

EnableAllAction DeleteAction CopyAction

72

Session 1703

Who Uses LazyBuildAction?


<<interface>>

Action AbstractAction GeneralAction LazyBuildAction MyDialogAction


73 Session 1703

EnableAllAction DeleteAction CopyAction

MyDialogAction Extends LazyBuildAction (1)


public class MyDialogAction extends LazyBuildAction { private MyDialog _dialog; private JFrame _f; public MyDialogAction(JFrame f){ super(myDialog); _f= f; } protected void build(){ _dialog= new MyDialog(_f,data); } protected void activate(){ _dialog.setVisible(true); } }
74 Session 1703

MyDialogAction Extends LazyBuildAction (2)


public class MyDialogAction extends LazyBuildAction { private MyDialog _dialog; private JFrame _f; public MyDialogAction(JFrame f){ super(myDialog); _f= f; } protected void build(){ _dialog= new MyDialog(_f,data); } protected void activate(){ _dialog.setVisible(true); } }
75 Session 1703

MyDialogAction Extends LazyBuildAction (3)


public class MyDialogAction extends LazyBuildAction { private MyDialog _dialog; private JFrame _f; public MyDialogAction(JFrame f){ super(myDialog); _f= f; } protected void build(){ _dialog= new MyDialog(_f,data); } protected void activate(){ _dialog.setVisible(true); } }
76 Session 1703

Create the Dialog

MyDialogAction Extends LazyBuildAction (4)


public class MyDialogAction extends LazyBuildAction { private MyDialog _dialog; private JFrame _f; public MyDialogAction(JFrame f){ super(myDialog); _f= f; } protected void build(){ _dialog= new MyDialog(_f,data); } protected void activate(){ _dialog.setVisible(true); } }
77 Session 1703

Set the dialog visible

GUI Infrastructure Package


Application Code

GUI Infrastructure

JFC/Swing
78 Session 1703

GUI Infrastructure Package


Application Code
Dialogs Numeric Entry Utilities Table Utilities Actions

JFC/Swing
79 Session 1703

GUI Infrastructure Package


Application Code
Dialogs Numeric Entry Utilities Table Utilities Actions

GeneralAction

LazyBuildAction

JFC/Swing
80 Session 1703

Complete Part 1 Finishing the Application

Session 1703

Adding the Polishing Touches


Toolbars Splash screens with progress bars Tool Tips and Help Effective use of color Complete and informative error messages Drag and Drop

82

Session 1703

First Impressions Are Everything


First Five Minutes Rule Does it feel easy to use
Only a novice cares if it is easy to use The first few tasks must be easy to do

83

Session 1703

Small Features Are Important (1)


Small features greatly affect user acceptance Simply meeting requirements...
Feels very incomplete Only creates an average program!

84

Session 1703

Small Features Are Important (2)


Make time to add nice touches You will not be able to justify them
Add them anyway Everyone will love you, trust me

85

Session 1703

Start-up Time
Always use a splash screen Generally use a progress bar Do everything possible to speed it up
Be meticulous Constant vigilance

86

Session 1703

Complete Part 2 Installing on Multi-platforms

Session 1703

Installation Challenges
Easy Normal JRE (Java runtime environment)

88

Session 1703

Easy Installation
Very first impression of your application Almost Un-noticeable Quick Network installations are rarely easy!

89

Session 1703

Normal Installation
Just like any other application Feels normal for that platform No special request from the installer Nothing else to install

90

Session 1703

The Java Runtime Environment (JRE)


You must guarantee it is there You must have control over the version SolutionInstall your own

91

Session 1703

Summary
Homogeneous
Build a solid GUI infrastructure

Extensible
Build your application around Actions

Complete
Include the details to make it exceptional Include a clean and easy installation

92

Session 1703

Always Remember

A good program is like a sky-scraper... If you want to go high, first you better go deep

93

Session 1703

Session 1703

Session 1703

You might also like