2. Goal
Learn about two new
frameworks that will make your
Swing development radically
easier
3. But Who Needs Another Framework?
Swing Development
is Like
A Day at the Beach
4.
5. Disclaimer
These projects are in development now
●
in the open!
●
This is a review of current prototypes
●
The details will almost certainly change
●
The fundamentals could change too
●
6. Agenda
How Did We Get Here? The Back Story
JSR 296: Swing Application Framework
JSR 295: Beans Binding
7. Agenda
How Did We Get Here? The Back Story
JSR 296: Swing Application Framework
JSR 295: Beans Binding
8. How Did We Get Here?
Swing version 0.1 debuts in 1997
●
It’s widely adopted
●
Developers let us know that building Swing
●
applications can be difficult. They tell us that a
standard application framework would make the
job easier.
9. How Did We Get Here?
Swing version 0.1 debuts in 1997
●
It’s widely adopted
●
Developers let us know that building Swing
●
applications can be difficult. They tell us that a
standard application framework would make the
job easier.
(8 years pass...)
●
10. How Did We Get Here? (Cont.)
Late Spring 2006
●
Swing Team files two JSRs aimed at simplifying
●
building applications:
JSR 295 Beans Binding
●
JSR 296 Swing Application Framework
●
Both JSRs
●
Focus on issues common to typical Swing applications
●
Are intended for Java Platform, Standard Edition (Java
●
SE platform) SE 7
Have prototypes available, java.net projects
●
11. Agenda
How Did We Get Here? The Back Story
JSR 296: Swing Application Framework
JSR 295: Beans Binding
Helpful links, Q&A
12. Swing Application Framework goals
As small and simple as possible (not more so)
●
Explain it all in one hour 22.5 minutes
●
Work very well for small/medium apps
●
Not the kitchen sink:
●
No module system, integral docking framework, generic
●
data model, scripting language, GUI markup schema,
web services integration simplification model for service
oriented architecture interoperability, ...
13. What the Framework Does
Lifecycle
●
Resources
●
Actions
●
Tasks
●
Session state
●
15. Using the Framework
Create a subclass of Application
●
Create and show your GUI in the startup method
●
Use ApplicationContext services to
●
define/manage actions and tasks
●
load/inject resources
●
save/restore session state
●
Call Application.launch from your main method
●
16. Using the Framework: Hello World
public class MyApp extends SingleFrameApplication {
@Override protected void startup() {
JLabel label = new JLabel(quot;Hello Worldquot;);
show(label);
}
public static void main(String[] args) {
Application.launch(MyApp.class, args);
}
}
// SingleFrameApplication is a subclass of Application
17. Application Class
Subclass defines your application’s lifecycle
●
Most apps will start with a class that extends
●
Application
e.g., SingleFrameApplication
●
Subclasses override lifecycle methods
●
Application instance is constructed on the EDT
●
Lifecycle methods run on the EDT (except launch)
●
Most lifecycle methods do little by default
●
…other than being called at the appropriate time
●
18. Application Lifecycle Methods
Calls initialize(), startup() and ready() on the EDT.
launch()
A static method, usually called from main().
Performs initializations that must happen before the GUI
initialize()
is created, like setting the look and feel.
Create the initial GUI and show it.
startup()
All applications will override this method.
Any work that must wait until the GUI is visible and
ready()
ready for input.
Call shutdown, if the exitListeners don't veto.
exit()
Main frame’s WindowListener calls exit().
shutdown() Take the GUI down, final cleanup.
19. What the Framework Does
Lifecycle
●
Resources
●
Actions
●
Tasks
●
Session state
●
20. Application Resources
Defined with ResourceBundles
●
Organized in resources subpackages
●
Used to initialize properties specific to:
●
locale
●
platform
●
a few related values…
●
21. ResourceMaps
Encapsulate list of ResourceBundles whose
●
names are based on a class:
Generic ResourceBundle; just the class name
●
Per OS platform, class_os, e.g., MyForm_OSX
●
Package-wide resources
●
Application-wide resources
●
Support string to type resource conversion
●
Extensible
●
22. Getting a ResourceMap
Resources for mypackage/MyForm.java
●
mypackage/resources/MyForm.properties
●
mypackage/resources/MyApp.properties
●
ResourceMap for MyForm:
●
ApplicationContext c = ApplicationContext.getInstance();
ResourceMap r = c.getResourceMap(MyForm.class);
23. Using ResourceMaps: Example
# resources/MyForm.properties
aString = Just a string
aMessage = Hello {0}
anInteger = 123
aBoolean = True
anIcon = myIcon.png
aFont = Arial-PLAIN-12
colorRGBA = 5, 6, 7, 8
color0xRGB = #556677
ApplicationContext c = ApplicationContext.getInstance();
ResourceMap r = c.getResourceMap(MyForm.class);
r.getString(quot;aMessagequot;, quot;Worldquot;) => quot;Hello Worldquot;
r.getColor(quot;colorRBGAquot;) => new Color(5, 6, 7, 8)
r.getFont(quot;aFontquot;) => new Font(quot;Arialquot;, Font.PLAIN, 12)
26. Resource Injection Advantages
Localizable by default
●
No need to explicitly lookup/set resources
●
Easy to reconfigure visual app properties
●
review visual app properties
●
But:
●
not intended to be a “styles” mechanism
●
not intended for general purpose GUI markup
●
@Resource injection requires privileges
●
27. What the Framework Does
Lifecycle
●
Resources
●
Actions
●
Tasks
●
Session state
●
28. Actions: A (very) brief review
Encapsulation of an ActionListener and:
●
some purely visual properties
●
● enabled and selected boolean properties
// define sayHello Action – pops up message Dialog
Action sayHello = new AbstractAction(quot;Helloquot;) {
public void actionPerformed(ActionEvent e) {
String s = textField.getText();
JOptionPane.showMessageDialog(s);
}
};
// use sayHello – set the action property
textField.setAction(sayHello);
button.setAction(sayHello);
29. The sayHello Action in Action
Disable the sayHello Action:
●
sayHello.setEnabled(false);
30. Actions: What We Like
Encapsulation of default GUI + behavior
●
The enabled and selected properties
●
Reusability
●
31. What We’re Not So Happy About
Overhead: creating Action objects is a pain
●
Visual properties should be localized!
●
Asynchronous Actions are difficult
●
Proxy linkages can be messy
●
It's tempting to make a little spaghetti:
●
Backend logic that depends on Actions: find all the
●
actions you need to enable/disable
32. The new @Action annotation
// define sayHello Action – pops up message Dialog
@Action public void sayHello() {
String s = textField.getText();
JOptionPane.showMessageDialog(s);
}
// use sayHello – set the action property
Action sayHello = getAction(quot;sayHelloquot;);
textField.setAction(sayHello);
button.setAction(sayHello);
ActionEvent argument is optional
●
Used to define a “sayHello” ActionMap entry
●
Encapsulation of default GUI + behavior
●
33. Where did the Action come from?
// utility method: look up an action for this class
Action getAction(String name) {
ApplicationContext c = ApplicationContext.getInstance();
ActionMap actionMap = c.getActionMap(getClass(), this);
return actionMap.get(name);
}
ApplicationContext.getActionMap()
●
creates an Action for each @Action method
●
default key is the action's method name
●
creates and caches an ActionMap
●
34. Action Resources
Loaded from the target class's ResourceMap
●
# resources/MyForm.properties
sayHello.Action.text = Say &Hello
sayHello.Action.icon = hello.png
sayHello.Action.accelerator = control H
sayHello.Action.shortDescription = Say hello modally
35. public class MyApp extends SingleFrameApplication {
@Action public void sayHello() {
JLabel label = new JLabel();
label.setName(quot;labelquot;);
show(JOptionPane.createDialog(label));
}
@Override protected void startup() {
show(new JButton(getAction(quot;sayHelloquot;)));
}
public static void main(String[] args) {
Application.launch(MyApp.class, args);
}
}
# resources/MyApp.properties
sayHello.Action.text = Say&Hello
sayHello.Action.shortDescription = say hello
label.text = Hello World
mainFrame.title = Hello
36. @Action enabled/selected linkage
@Action parameter names bound property
●
The rest of the app depends on the property, not the
●
Action object
@Action(enabledProperty = “name”)
●
@Action(selectedProperty = “name”)
●
37. // Defines 3 Actions: revert, save, delete
public class MyForm extends JPanel {
@Action(enabledProperty = quot;changesPendingquot;)
public void revert() { ... }
@Action(enabledProperty = quot;changesPendingquot;)
public void save() { ... }
@Action(enabledProperty = quot;!selectionEmptyquot;)
public void delete() { ... }
// These properties are bound, when they change
// PropertyChangeEvents are fired
public boolean getChangesPending() { ... }
public boolean isSelectionEmpty() { ... }
// ...
}
38. What the Framework Does
Lifecycle
●
Resources
●
Actions
●
Tasks
●
Session state
●
39. Don’t Block the EDT
Use a background thread for
●
Computationally intensive tasks
●
Tasks that might block, like network or file IO
●
Background thread monitoring/management
●
Starting, interrupting, finishing
●
Progress, messages
●
Descriptive information
●
SwingWorker: most of what we need
●
Task subclass adds...
●
40. Tasks: Support for Monitoring
Task title, description properties
●
For users (humans)
●
Initialized from ResourceMap
●
Task message property, method
●
myTask.setMessage(“loading ” + nThings)
●
myTask.message(“loadingMessage”, nThings)
●
(resource) loadingMessage = loading {0} things
●
Task start/done time properties
●
Task userCanCancel property
●
42. Tasks and TaskServices
TaskService T0 T1 T2 ...
T3 T4
“ConcurrentTasks”
T0 ...
T1 T2
TaskService
“SingleTaskQueue”
...
43. What the Framework Does
Lifecycle
●
Resources
●
Actions
●
Tasks
●
Session state
●
44. Session State
Make sure the application remembers where
●
you left things
Most applications should do this
●
But they don’t
●
Too complex to bother with
●
What state to save?
●
Where to store it (and what if you’re unsigned)?
●
How to safely restore the GUI?
●
45. Using SessionStorage
SingleFrameApplication saves/restores
●
automatically, at startup/shutdown time
You can customize what’s stored/restored
●
Create SessionStorage.Property implementations
●
SessionStorage.putProperty(forClass, ssp)
●
Usually, you will not need to
●
Save/restore arbitrary objects too:
●
ApplicationContext c = ApplicationContext.getInstance();
c.getSessionStorage().save(quot;data.xmlquot;, myHashMap);
47. Application Framework Summary
Swing Application Framework supports
●
Actions, resources, tasks, sessions
●
Application and ApplicationContext singletons
●
You subclass Application, SingleFrameApplication
●
Call Application.launch() in main
●
JSR-296 expert group is responsible
●
for defining the framework’s final form
●
finishing in time for Java platform 7
●
Get the code and learn more on the project site:
●
http://appframework.dev.java.net
48. Agenda
How Did We Get Here? The Back Story
JSR 296: Swing Application Framework
JSR 295: Beans Binding
50. Beans Binding
Keeps two properties
of two objects in sync
51. Beans Binding
Source properties are specified using Expression
●
Language (EL) syntax:
ex: “${customer}” or “${employee.salary}”
●
This EL dependency is changing – see later slides
●
Does not require special object types, endpoints
●
typed to Object:
bind(Object source,
String sourcePath,
Object target,
String targetPropertyName);
52. Beans Binding Builds Upon…
Beans
●
Standard way to track changes to a property
●
PropertyChangeListener
●
Adds ability to accommodate objects that don’t
●
strictly follow beans spec
Collection classes
●
Standard way to encapsulate common data types
●
Observable variants of List and Map will be created
●
53. Beans Binding
Will accommodate objects that don’t strictly follow
●
beans pattern
Map treated as a bean with dynamic properties
●
Ability to specify different update strategies
●
Read once, read only from source, keep source
●
and target in sync
Ability to do validation as property changes
●
Ability to transform value
●
String to Color, Date to String
●
56. javax.beans.binding.Binding
Describes and maintains binding between
●
two objects
Source, target, source path, target property
●
Converter
●
Ability to convert values from source or target
●
Validator
●
Validates changes from the target
●
Update strategy
●
How the two properties are kept in sync
●
57. Binding: Example
// Create an unbound binding
Binding binding = new Binding(
source, “sourcePath”,
target, “targetPropertyName”);
// Bind it
binding.bind();
// Optionally force the target property
// to update from the source
binding.setTargetValueFromSourceValue();
// Remove the binding
binding.unbind();
58. BindingContext
Manages a set of Bindings
●
Methods and listener to track state
●
of all Bindings
Invalid, newer…
●
Single point to bind and unbind the set
●
of Bindings
60. BindingContext: Example
// Create an unbound binding context
BindingContext context =
new BindingContext();
// Add some bindings
context.addBinding(source, “sourcePath”,
target, “targetPropertyName”);
context.addBinding(source, “sourcePath”,
target, “targetPropertyName”);
// Bind all bindings in the context
context.bind();
61. BindingConverter
Converts value from source to target, and back
●
Default implementations will be supplied
●
for common conversions
Integer → String
●
String → Dates
●
…
●
62. BindingConverter: Example
BindingConverter colorConverter =
new BindingConverter() {
public void Object
sourceToTarget(Object o){
return ((Boolean)o.booleanValue())
? Color.GREEN : Color.RED;
}
};
Binding binding = new Binding(
customer, “${active}”,
textField, “background”);
binding.setConverter(colorConverter);
63. JTable
Driven by a TableModel
●
int getRowCount();
●
Object getValueAt(int row, int column);
●
Using Binding:
●
Specify List<T>, each T corresponds to a row
●
Changes to List are tracked if List is an ObservableList
●
Specify how the value for each column is obtained
●
64. JTable: Binding
In an ideal world
// Binds the list (ObservableList<?>) to table's
// “elements” property
bind(list, table, quot;elementsquot;);
// Specifies the first column should use the 'firstName'
// property.
bind(quot;${firstName}quot;, 0);
// Specifies the second column should use the 'lastName'
// property.
bind(quot;${lastName}quot;, 1);
65. JTable: Binding to Elements
Working code
// Binds the list (ObservableList<?>) to table's
// “elements” property
Binding binding = new Binding(
list, null, // source
table, “elements”); // target
66. JTable: Binding to Elements
Working code
// Binds the list (ObservableList<?>) to table's
// “elements” property
Binding binding = new Binding(
list, null, // source
table, “elements”); // target
// Bind the “firstName” property of each element to the
// 1st column
binding.addBinding(
“${firstName}”, // source property EL
“value”, // target property
TableColumnParameter, 0); // 1st column
67. JTable: Binding to Elements
Working code
the 2nd column
// “lastName” property to
binding.addBinding(
“${lastName}”, // source property
“value”, // target property
1); // 2nd column
TableColumnParameter,
// etc...
68. What Is JTable “elements”?
JTable does not have an “elements” property
●
JTable has a TableModel
●
“elements” is a binding property
●
70. Recent/Ongoing API Changes
Motivation for changes
●
Remove required dependency on Expression
●
Language (EL)
Make binding-property creation more explicit and clear
●
The Big Idea
●
Use Property objects to specify the source/target
●
information
Property can use EL ... or not
●
71. Comparison
Previous approach
●
Binding binding = new Binding(
Object source, String expression,
Object target, String path);
New approach
●
Binding binding = new Binding(
Property source, Property target);
72. Property Implementations
Two Property subclasses provided
●
ELProperty
●
uses EL
●
BeanProperty
●
uses reflection
●
Developers can provide their own
●
Example: XPath
●
73. Example: Binding with Property
Previous:
●
new Binding(person, quot;${firstName}quot;,
uiComponent, quot;textquot;);
New:
●
new Binding(
new ELProperty(quot;${firstName}quot;, person),
new BeanProperty(quot;textquot;, uiComponent));
Or, if EL is not needed:
●
new Binding(
new BeanProperty(quot;firstNamequot;, person),
new BeanProperty(quot;textquot;, uiComponent));
74. For More Information
Source code, docs, and binaries on java.net
●
http://appframework.dev.java.net
●
http://beansbinding.dev.java.net
●
Planned integration (pending completion,
●
approval, etc.) into:
NetBeans6 (early releases available now)
●
JDK7
●
Tools support is important
●
Working with NetBeans team for support for both
●
frameworks in NetBeans GUI Builder