ts-4706 bringing jtable to the extreme david qiao jide software, inc

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

Upload: tamsyn-shaw

Post on 17-Dec-2015

233 views

Category:

Documents


4 download

TRANSCRIPT

Page 1: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

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

Page 2: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

About JIDE

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

JIDE Docking Framework JIDE Grids JIDE Pivot Grid JIDE Data Grids JIDE Desktop Application Framework

2

Page 3: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

Goal

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

3

Page 4: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

JTable: 101

4

JTableTableModel

TableUI (BasicTableUI)

JTableHeaderTableColumn

TableColumnModel

TableCellRendererTableCellEditor

Page 5: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

JTable

> Nothing but a bunch of cells arranged in grid-like layout

> Not enough in an real world application

5

Page 6: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

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

Page 7: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

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

Page 8: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

Possible Enhancements: Table Model

> Sorting> Filtering> Grouping> Caching> Paginating> JavaBean Support> JDBC or Hibernate Support

8

Page 9: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

Possible Enhancements: Renderer/Editor

> More cell renderers and editors for various data types Numbers Color Date/Calendar Font Insets Array

9

Page 10: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

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

Page 11: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

Things to Consider

> Compatible with JTable JTable is still moving along, there is no reason to start

from scratch. Won’t break the code for every new JDK release.

> Compatible with existing code which already uses JTable Make migration easier Developer feels at home

> Cons: face some limitations

Page 12: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

Things we can leverage

> Subclassing JTable BasicTableUI TableModel

> Overriding JTable: prepareRenderer, prepareEditor,

changeSelection, isCellSelected, rowAtPoint etc. BasicTableUI: paint

> Leveraging existing JTable APIs listeners, keyboard actions

Page 13: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

Case Studies

> Filtering and Sorting> Cell Spanning> Cell Styling

13

Page 14: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

Case Study: Filtering and Sorting

> The original TableModel should NOT be touched> Performance and memory> Scalability

14

Page 15: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

Demo of Sortable and Filterable Feature

15

Page 16: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

The solution is …

> View/Model Conversion Using a row index mapping to map from the row index

from the actual model to the row index in the view> Nothing new

TableColumnModel is such a view/model conversion except it is for the columns

16

Page 17: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

TableModelWrapper (or delegate)

> It wraps any TableModel to provide a mapping of row indices from the outer model to the inner model

> Only one method TableModel getActualModel()

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

Page 18: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

SortableTableModel

3 0

6 1

0 2

1 3

5 4

2 5

8 6

9 7

7 8

4 9

SortableTableModel(set to a table)

Actual TableModel

.

.

.

Page 19: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

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

Page 20: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

FilterableTableModel

0 0

3 1

9 2

3

4

5

6

7

8

9

FilterableTableModel(set to a table)

Actual TableModel

Page 21: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

TableModelWrapper “Pipes”Sortable

TableModel (1)Actual

TableModel (1)

1 0 0

2 3 1

0 9 2

3

4

5

6

7

8

9

FilterableTableModel (n)

JTable

Page 22: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

Performance and Memory

> The lookup speed: a direct array access for each table model wrapper 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 Optional index caching feature to make reverse lookup

to make getVisualRowAt method faster Lazy initialization

The index array is not created until there is sorting The reverse index array is not created until getVisualRowAt is

called22

Page 23: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

SortableTable

> SortableTableHeader to allow click-to-sort.

23

Page 24: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

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 filters AutoFilterTableHeader QuickTableFilterField (optionally use Lucene) QuickFilterPane TableCustomFilterEditor

24

Page 25: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

If there were one thing to learn …

> Remember the row index mapping idea and the table model wrapper design.

25

Page 26: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

Case Style: Cell Spanning

26

> Merge several cells into one big cell

Page 27: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

Demo of CellSpanTable

27

Page 28: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

Brainstorming

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

28

Page 29: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

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

Page 30: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

SpanModel

> Methods: boolean isCellSpanOn() CellSpan getCellSpanAt(int row, int column)

> Any TableModel can implement this SpanModel interface

> Implementations: AbstractSpanTableModel DefaultSpanTableModel: addCellSpan, removeCellSpan

etc. methods

Page 31: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

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

Page 32: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

Subclassing BasicTableUI

> BasicCellSpanTableUI extends BasicTableUI The paintGrid and paintCells methods are private End up overriding paint(g, c) method with many

duplicated code

Page 33: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

Subclassing JTable

> CellSpanTable Override getCellRenderer, prepareRenderer,

getCellEditor, prepareEditor, editCellAt Override rowAtPoint, columnAtPoint and getCellRect Override isCellSelected

Page 34: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

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

Page 35: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

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

Page 36: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

If there were one thing to learn …

> Store the information along the table model by implementing a new interface

36

Page 37: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

Case Study: Cell Styling

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

37

Page 38: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

Demo of CellStyleTable

38

Page 39: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

Brainstorming

> Is cell styling a model concept or a view concept?

39

Page 40: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

Brainstorming

> Is cell styling a model concept or a view concept? It depends Row striping is certain a view concept because it has

nothing to do with the table data However “displaying red text for negative values” is

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

40

Page 41: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

Brainstorming (Cont.)

> Providing the Cellstyle Using TableModel – for model related styles Using JTable – for non-model related styles

41

Page 42: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

CellStyle

> A class define styles mentioned on the previous slide that has many setters and getters, such as Color getForeground() void setForeground(Color color) Border getBorder() void setBorder(Border border)

Page 43: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

StyleModel

> Any TableModel can implement the StyleModel interface

> Methods: boolean isCellStyleOn() CellStyle getCellStyleAt(int row, int column)

Page 44: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

Subclass JTable - CellStyleTable

> Add setTableStyleProviderpublic interface TableStyleProvider { CellStyle getCellStyleAt(JTable table, int rowIndex, int columnIndex);}

> Override prepareRenderer/prepareEditor methods

Page 45: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

Implements Foreground Style

> prepareRenderer(renderer, row, column); Call super to get the rendererComponent Gets the CellStyle(s) from the StyleModel/TableStyleProvider If CellStyle has a foreground defined, call

rendererComponent.setForeground Repeat the previous step to cover all styles BasicTableUI will then paint the rendererComponent on the

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

45

Page 46: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

Implements Foreground Style

> prepareRenderer(renderer, row, column); Call super to get the rendererComponent Gets the CellStyle(s) from the StyleModel/TableStyleProvider If CellStyle has a foreground defined, call

rendererComponent.setForeground Repeat the previous step to cover all styles BasicTableUI will then paint the rendererComponent on the

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

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

46

Page 47: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

Implements Foreground Style: Cont.

> releaseRendererComponent(renderer, row, column, rendererComponent) We changed TableUI to always call

releaseRendererComponent after the rendererComponent is painted.

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

> We suggest Sun includes this method in JTable

47

Page 48: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

If there were one thing to learn …

> Define cell styling in a consistent way for all the tables in your application Define all CellStyle instances in one place You can even create CellStyle on fly using stylesheet or a

configuration file when application starts. getCellStyleAt return the predefined instance.

48

Page 49: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

Showcases

49

Page 50: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

Q & A

50

Page 51: TS-4706 Bringing JTable to the Extreme David Qiao JIDE Software, Inc

51

David QiaoJIDE Software, [email protected]