Developing Beyond the Component Libraries
Ryan Cuprakwww.cuprak.net
JavaOne 2010
1
Speaker
JavaOne 2010
www.enginuityplm.com
www.ctjava.org
2
What makes an application unique?
What it does.
How useful it is.
How a user interacts with it.
JavaOne 20103
Agenda❖ Why write a custom component?❖ Implementing a custom component❖ Introduction to Java’s L&F❖ Extending Swing components❖ Creating novel components❖ Understanding editor integration❖ Mashing Swing and JavaFX
JavaOne 20104
Developing Beyond the Component Libraries
❖ Users should not know they are using a Java application.❖ Users approach the computer as a tool for accomplishing a
task. ❖ Users should not be impeded by a user interface.❖ Users should never hear:
“You are limited to a JTextField because Java/Oracle doesn’t provide an ‘X’ GUI widget”
Java’s GUI component architecture is build for extension!
Couple of things before we get started:
JavaOne 20105
❖ Button❖ Check Box❖ Color Chooser❖ Combo Box❖ Desktop Pane❖ Dialog❖ Editor Pane❖ File Chooser❖ Formatted Field❖ Frame❖ Internal Frame❖ Label
❖ Layered Pane❖ List❖ Menus❖ Option Pane❖ Panel❖ Password Field❖ Progress Bar❖ Radio Button❖ Scroll Bar❖ Scroll Pane❖ Separator❖ Slider
❖ Spinner❖ Split Pane❖ Tabbed Pane❖ Table❖ Text Area❖ Text Field❖ Text Pane❖ Toggle Button❖ Tool Bar❖ Tree
Hasn’t expanded since Swing was introduced.
Why write a custom component?
JavaOne 20106
Why write a custom component?
❖ Swing component library is a starting point.❖ Applications need more than basic components:
❖ Currency Fields - support multiple currencies❖ Percent Fields - covert to PPM/PPB❖ Date Viewers - render dates❖ Numeric controls - scientific notation, locale aware❖ Text editor - highlight spelling errors
❖ Reduce redundant coding❖ Distinctive appearance
JavaOne 20107
❖ Decorating components:
❖ Fields containing validation errors
❖ Fields that are required
❖ Auto-focusing on fields with validation errors
❖ Binding and sorting data
❖ Restricting or facilitating data input
❖ Adding new platform controls (Office Ribbon)
❖ Leveraging platform controls (WebKit)
Why write a custom component?
JavaOne 20108
❖ Does it exist already?❖ Does the functionality really need a new component?❖ Will the component be used in an editor such as NetBeans,
IDEA, Eclipse, JFormDesigner?❖ Is the component locale sensitive?❖ Is the component Look & Feel sensitive?❖ Does it need to support accessibility?
Why write a custom component?Before rushing off to implement components:
JavaOne 2010
9
❖ Swingx (swingx.dev.java.net)❖ Flamingo (flamingo.dev.java.net)❖ JIDE Software (www.jidesoft.com/)❖ ILOG (www.ilog.com)❖ Beans Binding (beansbinding.dev.java.net)❖ JGraph (www.jgraph.com)❖ ArcGIS (www.esri.com)❖ JFreeChart (www.jfree.org/jfreechart)❖ JavaFX - controls/effects (http://javafx.com)❖ TWaver - http://www.servasoftware.com
Many More!Don’t reinvent the wheel!
Why write a custom component?
Alternatives to writing a component:
JavaOne 201010
Which path to take?
❖ Java Swing
❖ Java AWT
❖ JavaFX
❖ SWT
❖ LWUIT
❖ Apache Pivot
Why write a custom component?
JavaOne 201011
Agenda
❖ Why write a custom component?❖ Implementing a custom component❖ Introduction to Java’s L&F❖ Extending components❖ Creating novel components❖ Understanding editor integration❖ Mashing Swing and JavaFX
JavaOne 201012
❖ Create new button with a custom appearance:❖ Custom background and border❖ Dashed border around text focused❖ Underline text on roll-over❖ Use the cambria font❖ Text grows with the component
❖ Implementation:1. Subclass javax.swing.JComponent2. Override JComponent.paintComponent(),
getPreferredSize(), getMinimumSize()3. Add a FocusListener4. Add a MouseMotionListener
Implementing a custom component
JavaOne 201013
Implementing a custom component
Code Demo
JavaOne 201014
Approach shortcomings:
❖ Reinvents logic already in JButton.
❖ Ignores Look And Feel framework entirely.
❖ Can’t be used as a default button for a dialog.
❖ Doesn’t support HTML labels, icons, etc.
❖ Cannot be extended easily.
Implementing a custom component
JavaOne 201015
Agenda
❖ Why write a custom component?❖ Implementing a custom component❖ Introduction to Java’s L&F❖ Extending components❖ Creating novel components❖ Understanding editor integration❖ Mashing Swing and JavaFX
JavaOne 201016
Introduction to Java’s L&FWhat is a LookAndFeel?
❖ LookAndFeel is a set of ComponentUI classes that provide a common theme or appearance for controls.❖ Either cross platform or platform specific.
❖ Transparent to the application programmer using controls (mostly). ❖ LookAndFeels controls:
❖ Key bindings❖ Icons❖ Focus border❖ Text (Locale sensitive)❖ Consistent appearance
❖ Note: UI is skinned in JavaFX with CSS.
JavaOne 201017
Introduction to Java’s L&FWhat is a LookAndFeel?
JavaOne 201018
Introduction to Java’s L&FLookAndFeel Hierarchy
JavaOne 201019
Introduction to Java’s L&F
JavaOne 201020
Default Look & Feel
❖ MacOS X:
❖ com.apple.laf.AquaLookAndFeel
❖ Windows:
❖ javax.swing.plaf.metal.MetalLookAndFeel
Introduction to Java’s L&FWhat is a LookAndFeel?
JavaOne 201021
Introduction to Java’s L&F
What are the pieces of a component in Swing?
❖Keystroke handling❖Tooltips❖Accessibility❖Client Properties
❖Painting❖Layout❖Dimensions
JComponent ComponentUI
LookAndFeel Specific
JavaOne 201022
Introduction to Java’s L&FJComponent
JavaOne 201023
Introduction to Java’s L&FComponentUI
JavaOne 201024
Introduction to Java’s L&FComponentUI
JavaOne 201025
Introduction to Java’s L&FComponentUI Instantiation
JavaOne 201026
Introduction to Java’s L&FComponentUI Instantiation
JavaOne 201027
Introduction to Java’s L&F
So how do we go from a ButtonUI to a MetalButtonUI or an AquaButtonUI?
JButton returns “ButtonUI”, UIDefaults it maps to a MetalButtonUI.
ComponentUI Instantiation
JavaOne 201028
To sum up the creation process:1. LookAndFeel initializes and populates UIDefaults with a mapping of
UI Class Identifiers to the LookAndFeels implementations.2. JComponent subclass requests its UI delegate from the UIManager (singleton).
3. UI Manager queries the JComponent subclass for its UI Class ID.❖ ButtonUI for JButton❖ TextFieldUI for JTextField
4. UIManager looks up the UIComponent using the UI Class ID:❖ ButtonUI maps to MetalButtonUI
5. UIManager invokes static method createUI(JComponent) on the ComponentUI❖ UI delegate can be a singleton or unique for each component.
Introduction to Java’s L&FComponentUI Instantiation
JavaOne 201029
Introduction to Java’s L&FSetting Bounds
Assumes a LayoutManager.JavaOne 2010
30
Introduction to Java’s L&FPainting
JavaOne 201031
❖ Fonts❖ Insets❖ Shadows❖ Icons❖ Borders❖ Foreground color❖ Background color
❖ Input Maps❖ Margins❖ Mnemonic❖ Opaque flag❖ Caret blink rate❖ Disabled colors❖ etc.
Introduction to Java’s L&F
UIDefaults stores settings used to by the components:
Defaults
JavaOne 201032
Introduction to Java’s L&FDefaults
InstallUI method on ComponentUI loads default values.
JavaOne 201033
❖ Many changes to Swing components cannot be made by simply overriding a component’s paint() method.
❖ Major changes to a component must be made in the ComponentUI:❖ Joining of cells in JTable❖ Custom popup for adding/removing table columns❖ Changing the disabled color of the text on a
JRadioButton❖ Radically changing or altering the appearance of a
component.
Introduction to Java’s L&FComponentUI
JavaOne 201034
Introduction to Java’s L&F3 Steps to Component Creation
Subclass JComponent
Subclass ComponentUI
Register with UIManagerThis sounds simple right?
JavaOne 201035
Agenda
❖ Why write a custom component?❖ Implementing a custom component❖ Introduction to Java’s L&F❖ Extending components❖ Creating novel components❖ Understanding editor integration❖ Mashing Swing and JavaFX
JavaOne 201036
Customize three existing components:
❖ JButton - create an ObsidianButton
❖ JTextField - Currency Editor
❖ JRootPane - customize window border/buttons.
Extending ComponentsObjectives
JavaOne 201037
❖ Objective implement the Obsidian Button correctly.
❖ ObsidianButton recipe:
❖ Extend ButtonUI - ObsidianButtonUI
❖ Extend JButton - ObsidianButton
❖ Register with UIManager
Extending ComponentsObsidian Button
JavaOne 201038
Tidbits:
❖ ButtonModel contains the current state of the button.
❖ BasicButtonUI has hooks to ease extensions.
Extending ComponentsObsidian Button
JavaOne 201039
Extending Components
Code Demo
JavaOne 201040
❖ Why create a currency control?❖ Restrict user input to just numeric data.❖ Control the presentation of the currency.❖ Control the interpretation of the number.❖ Control the input of the number.
❖ Why not use JFormattedTextField?❖ How is invalid user input interpreted?❖ Controlling locale/currency settings independently.
Extending ComponentsCurrency Control
JavaOne 2010
JFormattedTextField Demo
41
Extending ComponentsCurrency Control
JavaOne 2010
How is a text field rendered?
42
Recipe for implementing the currency control:
1. Create a FieldView subclass to do the custom rendering.
2. Create a new BasicTextFieldUI subclass.
1. Override the create method and return the new FieldView
3. Create a new JTextField subclass
1. Return the new BasicTextFieldUI subclass
Extending ComponentsCurrency Control
43
Extending Components
Code Demo
JavaOne 2010
Currency Control
44
Extending Components
Food for thought:
You can radically change the rendering of a document.
Consider for example restricting input to ABCDEFG and creating a view that renders it like:
45
What’s the matter with the standard JRootPane?
Extending ComponentsJRootPane
JavaOne 2010
Because sometimes you want to customize it!
46
Recipe for customizing the title pane:
1.Create a JComponent subclass to render the title pane.
2.Extend RootPaneUI
3.Extend your Look And Feel:
1. In initClassDefaults perform the following configuration:JDialog.setDefaultLookAndFeelDecorated(true);JFrame.setDefaultLookAndFeelDecorated(true);
2.Return true for getSupportsWindowDecorations()
Extending ComponentsJRootPane
47
Extending Components
Code Demo
JavaOne 2010
JRootPane
48
❖ Why write a custom component?❖ Implementing a custom component❖ Introduction to Java’s L&F❖ Extending components❖ Creating novel components❖ Understanding editor integration❖ Mashing Swing and JavaFX
Agenda
JavaOne 201049
❖ Components to be demoed:❖ iPhone Switch Component
❖ What we will see:❖ Supporting multiple Look & Feels❖ Handling focus and keyboard events
Creating Novel Components
JavaOne 201050
Creating Novel ComponentsLet’s look at replicating the iPhone switch. ❖ Simple “Toggle” button that slides
back and forth for On and Off.❖ Tapping on the opposite state causes
the button to toggle with a visible animation.
❖ Dragging the switch with the mouse moves the button.
❖ Releasing the button causes the button to snap the nearest side.
JavaOne 201051
Creating Novel Components
❖ Gradient Paints
❖ Rounded Borders
❖ Not 50/50
❖ Highlights
❖ Border effects
52
Creating Novel Components1. JComponent Approach
1. Subclass JComponent.2. Override
paintComponent()2. LookAndFeel Approach
1. Subclass JToggleButton2. Create a ComponentUI
subclass.
JavaOne 201053
❖ Implement listeners for:FocusLister, MouseListener, MotionListener, KeyboardListener
❖ Track and render states:Focus, Enabled/Disabled
❖ Support Accessibility❖ Match L&F Appearance/Theme❖ Paint the control (and have it look professional)
Creating Novel ComponentsJComponent Approach Challenges
This is not trivial!
JavaOne 201054
❖ Matching current L&F is not trivial:❖ Borders❖ Shadowing❖ Font❖ Background/Foreground Colors❖ Painting (gradients)❖ Keybindings
❖ Matching multiple L&F is even more challenging.❖ Users change themes (Windows Appearance settings).
Creating Novel ComponentsJComponent Approach Challenges
JavaOne 201055
Code Demo
Creating Novel Components
JavaOne 201056
Agenda
❖ Why write a custom component?❖ Implementing a custom component❖ Introduction to Java’s L&F❖ Changing Swing’s appearance❖ Creating novel components❖ Understanding editor integration❖ Mashing Swing and JavaFX
JavaOne 201057
Understanding Editor Integration
Why editor integrations?❖ Manually writing swing code is time consuming.❖ Many good editors for constructing Swing interfaces.❖ Have you ever tried maintaining code like this?
JavaOne 201058
❖ Supporting editors such as NetBeans:
❖ Create BeanInfo objects for each component.
❖ Each component property should support PropertyChangeEvents (Beans Bindings).
❖ Include an icon representing the component.
❖ Support serialization.
Understanding Editor Integration
JavaOne 201059
Understanding Editor IntegrationAdding SwingX widgets to NetBeans.
JavaOne 201060
❖ Why write a custom component?❖ Implementing a custom component❖ Introduction to Java’s L&F❖ Extending components❖ Creating novel components❖ Understanding editor integration❖ Mashing Swing and JavaFX
Agenda
JavaOne 201061
❖ Why JavaFX vs. Swing?❖ Scene graph❖ Integration with Photoshop/Illustrator❖ Skin controls with CSS❖ Rich media support❖ JavaFX 1.3 added lots of controls.
❖ Why Swing vs JavaFX?❖ Rich component libraries❖ Support native Look And Feels
❖ Why mix JavaFX and Swing?❖ Get the best of both worlds!
Mashing Swing and JavaFX
These are just a few reasons!
?JavaOne 2010
62
Mashing Swing and JavaFX
Code Demo
Using JavaFX with Swing
JavaOne 201063
❖ How to start writing components:❖ Browse the source to Java Swing library (src.jar).❖ Excellent open source projects (read/debug):
❖ SwingX (https://swingx.dev.java.net/)❖ JIID Software Open Layer (http://www.jidesoft.com/)
❖ Tools:❖ Java Decompiler (http://java.decompiler.free.fr/)
❖ Links:❖ http://www.l2fprod.com (Look & Fool)❖ http://today.java.net/article/2007/02/19/how-write-
custom-swing-component
Starting Points
JavaOne 201064
Reference MaterialFurther Reading:
❖ Core Swing Advanced Programming by Kim Topley (0130832928)
❖ Filthy Rich Clients by Chet Hasse/Romain Guy (0-13-241393-0)
❖ JavaFX in Action by Simon Morris (1-933988-99-1)
JavaOne 201065
Recap component development:
❖ ComponentUI - renders a component.
❖ JComponent - delegates rendering to its ComponentUI.
❖ ComponentUIs are looked up via the UIManager.
❖ Components can be customized via UIDefaults
Summary
JavaOne 201066
❖ Don’t reinvent the wheel!
❖ Test on multiple platforms.
❖ Write a test harness to verify:
❖ Changing Locale
❖ Changing Look and Feel
❖ Enabling/disabling programmatically
Summary
JavaOne 201067
Q&ACode samples/slides: www.cuprak.netQuestions: [email protected]
JavaOne 201068