51
TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc. Monday, 8 June 2009

TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

  • Upload
    others

  • View
    4

  • Download
    0

Embed Size (px)

Citation preview

Page 1: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

TS-4706 Bringing JTable to the ExtremeDavid QiaoJIDE Software, Inc.

Monday, 8 June 2009

Page 2: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

About JIDE> JIDE Software is a Swing component provider> Over 12 different products> Also provide L&F, UI and icon design service

l JIDE Docking Frameworkl JIDE Gridsl JIDE Pivot Gridl JIDE Data Gridsl JIDE Desktop Application Framework

2

Monday, 8 June 2009

Page 3: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Goal> Explore the internals of JTable > Find a way to enhance it to meet requirements

3

Monday, 8 June 2009

Page 4: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

JTable: 101

4

JTableTableModel

TableUI (BasicTableUI)

JTableHeaderTableColumn

TableColumnModel

TableCellRendererTableCellEditor

Monday, 8 June 2009

Page 5: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

JTable> Nothing but a bunch of cells arranged in grid-

like layout> Not enough in an real world application

5

Monday, 8 June 2009

Page 6: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Possible Enhancements: Table Header> AutoFilter (Excel style filter dropdowns)> Multiple Rows in the Header with Column

Span (nested table header)> Sortable/Groupable> Show/Hide Columns (right click context

menu)> Column Auto-Fit (double click on the column

divider)

6

Monday, 8 June 2009

Page 7: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Possible Enhancements: Table Body> Cell Spanning (merge cells)> Frozen Rows/Columns (make some rows or

columns not scrollable)> Resizable Rows/Columns (drag the grid lines

to resize)> Cell Styling (row/column stripes, back/

foreground color, font, flashing)> TreeTable> HierarchicalTable (put other components

inside table under each row)7

Monday, 8 June 2009

Page 8: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Possible Enhancements: Table Model> Sorting> Filtering> Grouping> Caching> Paginating> JavaBean Support> JDBC or Hibernate Support

8

Monday, 8 June 2009

Page 9: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Possible Enhancements: Renderer/Editor> More cell renderers and editors for various

data typesl Numbersl Colorl Date/Calendarl Fontl Insetsl Array

9

Monday, 8 June 2009

Page 10: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Possible Enhancements: Other> State persistence (column order, width, sort

order, selection)> Key navigation (i.e. only stop on editable cells)> Excel export> Non-contiguous cell selection> Formula (like Excel)> Copy and paste (copy is supported by JTable

but paste is missing)> Cell validation and row validation

10

Monday, 8 June 2009

Page 11: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Things to Consider> Compatible with JTable

l JTable is still moving along, there is no reason to start from scratch.

l Won’t break the code for every new JDK release.> Compatible with existing code which already

uses JTablel Make migration easierl Developer feels at home

> Cons: face some limitations

Monday, 8 June 2009

Page 12: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Things we can leverage> Subclassing

l JTablel BasicTableUIl TableModel

> Overridingl JTable: prepareRenderer, prepareEditor,

changeSelection, isCellSelected, rowAtPoint etc.l BasicTableUI: paint

> Leveraging existing JTable APIsl listeners, keyboard actions

Monday, 8 June 2009

Page 13: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Case Studies> Filtering and Sorting> Cell Spanning> Cell Styling

13

Monday, 8 June 2009

Page 14: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Case Study: Filtering and Sorting> The original TableModel should NOT be

touched> Performance and memory> Scalability

14

Monday, 8 June 2009

Page 15: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Demo of Sortable and Filterable Feature

15

Monday, 8 June 2009

Page 16: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

The solution is …> View/Model Conversion

l Using a row index mapping to map from the row index from the actual model to the row index in the view

> Nothing newl TableColumnModel is such a view/model

conversion except it is for the columns

16

Monday, 8 June 2009

Page 17: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

TableModelWrapper (or delegate)> It wraps any TableModel to provide a

mapping of row indices from the outer model to the inner model

> Only one methodl TableModel getActualModel()

> RowTableModelWrapper l Provides row index mappingl int getActualRowAt(int visualRowIndex)l int getVisualRowAt(int actualRowIndex)

Monday, 8 June 2009

Page 18: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

SortableTableModel3 06 10 21 35 42 58 69 77 84 9

SortableTableModel(set to a table)

Actual TableModel

.

.

.

Monday, 8 June 2009

Page 19: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Implementation of getValueAt methodpublic Object getValueAt(int row, int column) { if (_indexes != null && (row < 0 || row >= _indexes.length)) { return null; } else { return _model.getValueAt(getActualRowAt(row), column); } }

where getActualRowAt is _indexes[row].

19

Monday, 8 June 2009

Page 20: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

FilterableTableModel0 03 19 2

3456789

FilterableTableModel(set to a table)

Actual TableModel

Monday, 8 June 2009

Page 21: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

TableModelWrapper “Pipes”Sortable

TableModel (1)Actual

TableModel (1)

1 0 02 3 10 9 2

3456789

FilterableTableModel (n)

JTable

Monday, 8 June 2009

Page 22: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Performance and Memory> The lookup speed: a direct array access for

each table model wrapperl table.getValueAt(row, column) calls

tableModel.getValueAt(getActualRowAt(row), column)

> Memory consumption: one (or two) int array whose length is the same as the row count l Optional index caching feature to make reverse

lookup to make getVisualRowAt method fasterl Lazy initialization

l The index array is not created until there is sortingl The reverse index array is not created until

getVisualRowAt is called 22

Monday, 8 June 2009

Page 23: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

SortableTable> SortableTableHeader to allow click-to-sort.

23

Monday, 8 June 2009

Page 24: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Filterable related components> Different from SortableTable, no

FilterableTable> Any JTable can be filterable if you set a

FilterableTableModel on to it> Other components work with JTable and

FilterableTableModel to make it easy for user to add/remove filtersl AutoFilterTableHeaderl QuickTableFilterField (optionally use Lucene)l QuickFilterPanel TableCustomFilterEditor

24

Monday, 8 June 2009

Page 25: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

If there were one thing to learn …> Remember the row index mapping idea and

the table model wrapper design.

25

Monday, 8 June 2009

Page 26: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Case Style: Cell Spanning

26

> Merge several cells into one big cell

Monday, 8 June 2009

Page 27: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Demo of CellSpanTable

27

Monday, 8 June 2009

Page 28: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Brainstorming> Model: store the cell spans> View: change how the grid lines are painted

28

Monday, 8 June 2009

Page 29: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

CellSpan> _row: Span start row

index> _column: Span start

column index> _rowSpan: The number

of rows that it spans> _columnSpan: The

number of columns that it spans

CellSpan(1,2,3,4)

row, column, rowSpan, columnSpan

CellSpan(1,2,3,4)

row, column, rowSpan, columnSpan

CellSpan(1,2,3,4)

row, column, rowSpan, columnSpan

CellSpan(1,2,3,4)

row, column, rowSpan, columnSpan

CellSpan(1,2,3,4)

row, column, rowSpan, columnSpan

CellSpan(1,2,3,4)

row, column, rowSpan, columnSpan

CellSpan(1,2,3,4)

row, column, rowSpan, columnSpan

CellSpan(1,2,3,4)

row, column, rowSpan, columnSpan

CellSpan(1,2,3,4)

row, column, rowSpan, columnSpan

CellSpan(1,2,3,4)

row, column, rowSpan, columnSpan

CellSpan(1,2,3,4)

row, column, rowSpan, columnSpan

CellSpan(1,2,3,4)

row, column, rowSpan, columnSpan

Monday, 8 June 2009

Page 30: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

SpanModel> Methods:

l boolean isCellSpanOn()l CellSpan getCellSpanAt(int row, int column)

> Any TableModel can implement this SpanModel interface

> Implementations:l AbstractSpanTableModell DefaultSpanTableModel: addCellSpan,

removeCellSpan etc. methods

Monday, 8 June 2009

Page 31: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Exampleclass MyModel extends AbstractTableModel implements

SpanModel {

……. // all other table model methods

CellSpan span; public CellSpan getCellSpanAt(int row, int column) { // define the span based on the row and column index return span; } public boolean isCellSpanOn() { return true; } }

31

Monday, 8 June 2009

Page 32: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Subclassing BasicTableUI> BasicCellSpanTableUI extends BasicTableUI

l The paintGrid and paintCells methods are private

l End up overriding paint(g, c) method with many duplicated code

Monday, 8 June 2009

Page 33: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Subclassing JTable> CellSpanTable

l Override getCellRenderer, prepareRenderer, getCellEditor, prepareEditor, editCellAt

l Override rowAtPoint, columnAtPoint and getCellRect

l Override isCellSelected

Monday, 8 June 2009

Page 34: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

getCellRenderer @Override public TableCellRenderer getCellRenderer(int row, int column) { CellSpan cellSpan = getCellSpanAt(row, column); if (cellSpan != null) { return super.getCellRenderer(cellSpan.getRow(),

cellSpan.getColumn()); } return super.getCellRenderer(row, column); }

34

Monday, 8 June 2009

Page 35: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Other Considerations> Caching CellSpans at CellSpanTable> Caching the painting of CellSpans in

BasicCellSpanTableUI to avoid the cells in the same CellSpan painted again and again

> Converting the CellSpan when columns are rearranged (not all possible)

35

Monday, 8 June 2009

Page 36: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

If there were one thing to learn …> Store the information along the table model

by implementing a new interface

36

Monday, 8 June 2009

Page 37: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Case Study: Cell Styling> Background (solid color or gradient)> Foreground> Font (font name, style, size)> Border> Alignment> Icon> Row stripes/column stripes

37

Monday, 8 June 2009

Page 38: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Demo of CellStyleTable

38

Monday, 8 June 2009

Page 39: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Brainstorming> Is cell styling a model concept or a view

concept?

39

Monday, 8 June 2009

Page 40: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Brainstorming> Is cell styling a model concept or a view

concept?l It dependsl Row striping is certain a view concept because

it has nothing to do with the table datal However “displaying red text for negative

values” is related to the table data so it is kind of a model concept

40

Monday, 8 June 2009

Page 41: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Brainstorming (Cont.)> Providing the Cellstyle

l Using TableModel – for model related stylesl Using JTable – for non-model related styles

41

Monday, 8 June 2009

Page 42: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

CellStyle> A class define styles mentioned on the

previous slide that has many setters and getters, such as l Color getForeground()l void setForeground(Color color)l Border getBorder()l void setBorder(Border border)

Monday, 8 June 2009

Page 43: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

StyleModel> Any TableModel can implement the

StyleModel interface> Methods:

l boolean isCellStyleOn()l CellStyle getCellStyleAt(int row, int column)

Monday, 8 June 2009

Page 44: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Subclass JTable - CellStyleTable> Add setTableStyleProvider

public interface TableStyleProvider { CellStyle getCellStyleAt(JTable table, int rowIndex, int columnIndex);}

> Override prepareRenderer/prepareEditor methods

Monday, 8 June 2009

Page 45: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Implements Foreground Style> prepareRenderer(renderer, row, column);

l Call super to get the rendererComponentl Gets the CellStyle(s) from the StyleModel/

TableStyleProviderl If CellStyle has a foreground defined, call

rendererComponent.setForegroundl Repeat the previous step to cover all stylesl BasicTableUI will then paint the rendererComponent

on the table cell> What will happen if we only do this?

45

Monday, 8 June 2009

Page 46: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Implements Foreground Style> prepareRenderer(renderer, row, column);

l Call super to get the rendererComponentl Gets the CellStyle(s) from the StyleModel/

TableStyleProviderl If CellStyle has a foreground defined, call

rendererComponent.setForegroundl Repeat the previous step to cover all stylesl BasicTableUI will then paint the rendererComponent

on the table cell> What will happen if we only do this?

l Because the same renderer is used in a table for different cells, all those cells will have the same foreground.

46

Monday, 8 June 2009

Page 47: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Implements Foreground Style: Cont.> releaseRendererComponent(renderer, row,

column, rendererComponent)l We changed TableUI to always call

releaseRendererComponent after the rendererComponent is painted.

l And we reset the foreground to its previous value in this method

> We suggest Sun includes this method in JTable

47

Monday, 8 June 2009

Page 48: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

If there were one thing to learn …> Define cell styling in a consistent way for all

the tables in your applicationl Define all CellStyle instances in one placel You can even create CellStyle on fly using

stylesheet or a configuration file when application starts.

l getCellStyleAt return the predefined instance.

48

Monday, 8 June 2009

Page 49: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Showcases

49

Monday, 8 June 2009

Page 50: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

Q & A

50

Monday, 8 June 2009

Page 51: TS-4706 Bringing JTable to the Extreme - Oracle · l JTable is still moving along, there is no reason to start from scratch. l Won’t break the code for every new JDK release. >

51

David QiaoJIDE Software, [email protected]

Monday, 8 June 2009