You are on page 1of 52

SwingX – Beyond

Components
Jeanette Winzenburg
Desktop Consultant
SwingEmpire
What to Expect

Tour through a couple of


Big Themes and some
Nasty Details

www.javapolis.com
My Background

 Long-time Swing-addict
 SwingEmpire
 Developer/Designer/Architect for SwingX
 Experimental (Bio-) Physicist

www.javapolis.com
Swing/X is Simple!

Everything should be as simple as


possible, but not more so.
-- Albert Einstein --

www.javapolis.com
Swing/X is Simple!

Everything should be as simple as


possible, but not more so.
-- Albert Einstein --

www.javapolis.com
Agenda

 Fun Spoilers
 Big Theme: Sorter/Filter
 Big Theme: Highlighter
 Conclusion

www.javapolis.com
Agenda

 Fun Spoilers
 Big Theme: Sorter/Filter
 Big Theme: Highlighter
 Conclusion

www.javapolis.com
Fun Spoiler: API Variation

getTableCellRendererComponent(table, value,
isSelected, hasFocus,
row, column)

getListCellRendererComponent(list, value,
index,
isSelected, hasFocus)

getTreeCellRendererComponent(tree, value,
isSelected, isExpanded, isLeaf,
row,
hasFocus)

www.javapolis.com
Fun Spoiler: Incomplete API

table.getColumn(columnIndex)

Exception in thread "main"


java.lang.IllegalArgumentException:
Identifier not found
at … DefaultTableColumnModel.getColumnIndex
(DefaultTableColumnModel.java:264)
at … JTable.getColumn(JTable.java:1788)
at … (custom code)

www.javapolis.com
Fun Spoiler: Complete API without Implementation

monthView.setTimeZone(xmasZone)

www.javapolis.com
Fun Spoiler: Instability
Bare Renderer
// do nothing

www.javapolis.com
Fun Spoiler: Instability

Add Icon Decoration

list.addHighlighter(getHighlighter("star.gif"));

www.javapolis.com
Fun Spoiler: Instability

Add Padding Decoration


list.addHighlighter(getBorderHighlighter());
list.addHighlighter(getHighlighter("star.gif"));

www.javapolis.com
Fun Spoiler: Instability

Some time later…


list.addHighlighter(getBorderHighlighter());
list.addHighlighter(getHighlighter("star.gif"));

www.javapolis.com
Agenda

 Fun Spoilers
 Big Theme: Sorter/Filter
 Big Theme: Highlighter
 Conclusion

www.javapolis.com
Sorter/Filter: None

Model Component

State

Client

www.javapolis.com
Sorter/Filter: None

value = model.getValueAt(row, … )
value = table.getModel().getValueAt(row, … )

// state-dependent
selectedRow = table.getSelectedIndex(..)
value = model.getValueAt(selectedRow, … )
value = table.getModel().getValueAt(selectedRow, … )

www.javapolis.com
Sorter/Filter: Model Decoration

Input Transformation Output Component

State

Client

www.javapolis.com
Sorter/Filter: Model Decoration

// model != table.getModel()
valueM = model.getValueAt(row, … )
valueV = table.getModel().getValueAt(row, … )

// state-dependent
selectedRowV = table.getSelectedIndex(…)
selectedRowM = transformation.convert(…)
value = model.getValueAt(selectedRowM, … )

www.javapolis.com
Sorter/Filter: View Responsibility

Input Transformation Output Component

State
Output

Client

www.javapolis.com
Sorter/Filter: View Responsibility

// model == table.getModel()
value = model.getValueAt(rowM, … )
value = table.getModel().getValueAt(rowM, … )

// state-dependent
selectedRowV = table.getSelectedIndex(…)
selectedRowM = table.convert(selectedRowV)
value = model.getValueAt(selectedRowM, … )

www.javapolis.com
Sorter/Filter: View Responsibility – UI perspective

UIClient

Input Transformation Output Component

State
Output

www.javapolis.com
Sorter/Filter: View Responsibility – UI perspective

UIClient

Input Transformation Output Component

State
Output

www.javapolis.com
Sorter/Filter: View Responsibility – UI Perspective

// delegate methods – view coordinates


value = table.getValueAt(rowV, … )

// state-dependent
selectedRowV = table.getSelectedIndex(…)
value = table.getValueAt(selectedRowV, …)

// skip value
selectedRowV = table.getSelectedIndex(…)
renderingComponent =
table.prepareRenderer(selectedRowV, …)

www.javapolis.com
Sorter/Filter: Summary

 2 coordiate systems
 View
 Model
 SwingX/Swing6
 Transformation is view responsibility
 Component must have API to convert
 Best with delegate API in view coordinates

www.javapolis.com
Sorter/Filter: Concrete Components

 J/X/Table
 Traditionally has delegate methods
 X-only: sort API
 Sort is transparent to UI
 J/X/List
 Traditionally has no delegate methods
 Sort would break UI
 X-only: cheats … (hidden model decoration)

www.javapolis.com
Sorter/Highlighter: JTable Glitch

 Missing sort API


// in BasicTableHeaderUI mouseHandler
modelColumn =
table.convertColumnIndexToModel(viewColumn);
sorter.toggleSortOrder(modelColumn);

 In a better world
table.toggleSortOrder(viewColumn);

www.javapolis.com
Agenda

 Fun Spoilers
 Big Theme: Sorter/Filter
 Big Theme: Highlighter
 Conclusion

www.javapolis.com
Highlighter: Example
None

www.javapolis.com
Highlighter: Example
Add Striping

www.javapolis.com
Highlighter: Example
Add Colored Pattern Highlight

www.javapolis.com
Highlighter: Example
Add Bold-Italic Pattern Highlight

www.javapolis.com
Highlighter: Example
Add Shading Column (on lookup column)

www.javapolis.com
Highlighter: Example
Add Value-based Gradient

www.javapolis.com
Highlighter: Example
Sorted

www.javapolis.com
Highlighter: Scope
Renderer Configures
 Content: value as  Visual Properties
 Text  Color
 Icon  Font
 Graph  Border
 …  Painter (X-only)
 Enabled
 Component Orientation
 Alignment
 …

www.javapolis.com
Highlighter: Scope

 Content: value as  Highlight Visuals


 Text  Color
 Icon  Font
 Graph  Border
 …  Painter (X-only)
 Default Visuals  Enabled
 Color
 Component Orientation
 Font
 Alignment
 Border
 …
 …

www.javapolis.com
Highlighter: Mechanics

 Clients installs on the collection


components
collectionComp.addHighlighter(myHighlighter)

 Collection component
 Requests the rendering component
 Applies the installed highlighters

Component component = renderer.getXXComponent(..)


highlighters.apply(component,..);

www.javapolis.com
Highlighter: Mechanics – What Do they Buy?

 Consistent API
 Single plug-in point
 Visual decoration independent of
 Type of renderer
 Type of collection component
 Type of rendering component
 Content representation

www.javapolis.com
Highlighter: Concrete Components

 JXTable
 super has API to request rendering component
 extended to apply highlighters
 JXList/JXTree
 no super API to request rendering component
 decorates super renderer with wrapper

www.javapolis.com
Highlighter: Example
Sorted

www.javapolis.com
Highlighter: Example Code Snippet

table.setHighlighters(
striping,
magentaForegroundWithPatternCondition,
boldFontWithPatternCondition,
shadingColumn,
valueBasedGradient)

www.javapolis.com
Highlighter: Example
Simulate Table by Lists

www.javapolis.com
Highlighter: Example Code Snippet

listFirstName.setHighlighters(striping)

listLastName.setHighlighters(striping,
magentaForegroundWithPatternCondition,
boldFontWithPatternCondition,
shadingColumn)

listNumber.setHighlighters(striping,
valueBasedGradient)
listNumber.setCellRenderer(new DefaultListRenderer(

FormatStringValue.NUMBER_TO_STRING,
JLabel.RIGHT));

www.javapolis.com
Agenda

 Fun Spoilers
 Big Theme: Sorter/Filter
 Big Theme: Highlighter
 Conclusion

www.javapolis.com
Swing/X is Simple!

 Enhance ease-of-use
 Stability
 Consistency
 Strict separation

www.javapolis.com
Community: Places

 Project homes
 https://swingx.dev.java.net
 Free-style contribution zone
 https://jdnc-incubator.dev.java.net
 Very active SwingLabs forum
 http://forums.java.net/jive/forum?jsp?forumID=73

www.javapolis.com
Community: Persons
Special Thanks to
 Jan Haderka
 rah003@java.dev.net
 Neat Results Ltd.
 Karl Schaefer
 kschaefe@java.dev.net
 Westinghouse Electric Company LLC

www.javapolis.com
Community: Action

SwingX needs You!

www.javapolis.com
Q&A
View JavaPolis talks @ www.parleys.com
Thank you for your
attention