TS4706 Bringing JTable to the Extreme David Qiao
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 l l l JIDE Docking Framework JIDE Grids JIDE Pivot Grid JIDE Data Grids JIDE Desktop Application Framework 2
Goal > > Explore the internals of JTable Find a way to enhance it to meet requirements 3
JTable: 101 JTable. Model Table. UI (Basic. Table. UI) Table. Cell. Renderer Table. Cell. Editor JTable. Header Table. Column. Model 4
JTable > > Nothing but a bunch of cells arranged in grid-like layout Not enough in an real world application 5
Possible Enhancements: Table Header > > > Auto. Filter (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
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) Tree. Table Hierarchical. Table (put other components inside table under each row) 7
Possible Enhancements: Table Model > > > > Sorting Filtering Grouping Caching Paginating Java. Bean Support JDBC or Hibernate Support 8
Possible Enhancements: Renderer/Editor > More cell renderers and editors for various data types l l l Numbers Color Date/Calendar Font Insets Array 9
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
Things to Consider > Compatible with JTable l l > Compatible with existing code which already uses JTable l l > JTable is still moving along, there is no reason to start from scratch. Won’t break the code for every new JDK release. Make migration easier Developer feels at home Cons: face some limitations
Things we can leverage > Subclassing l l l > Overriding l l > JTable Basic. Table. UI Table. Model JTable: prepare. Renderer, prepare. Editor, change. Selection, is. Cell. Selected, row. At. Point etc. Basic. Table. UI: paint Leveraging existing JTable APIs l listeners, keyboard actions
Case Studies > > > Filtering and Sorting Cell Spanning Cell Styling 13
Case Study: Filtering and Sorting > > > The original Table. Model should NOT be touched Performance and memory Scalability 14
Demo of Sortable and Filterable Feature 15
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 new l Table. Column. Model is such a view/model conversion except it is for the columns 16
Table. Model. Wrapper (or delegate) > > It wraps any Table. Model to provide a mapping of row indices from the outer model to the inner model Only one method l > Table. Model get. Actual. Model() Row. Table. Model. Wrapper l l l Provides row index mapping int get. Actual. Row. At(int visual. Row. Index) int get. Visual. Row. At(int actual. Row. Index)
Sortable. Table. Model (set to a table) 3 0 6 1 0 2 1 3 5 4 2 5 8 6 9 7 4 . . . 7 8 9 Actual Table. Model
Implementation of get. Value. At method public Object get. Value. At(int row, int column) { if (_indexes != null && (row < 0 || row >= _indexes. length)) { return null; } else { return _model. get. Value. At(get. Actual. Row. At(row), column); } } where get. Actual. Row. At is _indexes[row]. 19
Filterable. Table. Model (set to a table) 0 0 3 1 9 2 3 4 5 6 7 8 9 Actual Table. Model
Table. Model. Wrapper “Pipes” Sortable Table. Model (1) JTable Filterable Table. Model (n) Actual Table. Model (1) 1 0 0 2 3 1 0 9 2 3 4 5 6 7 8 9
Performance and Memory > The lookup speed: a direct array access for each table model wrapper l > table. get. Value. At(row, column) calls table. Model. get. Value. At(get. Actual. Row. At(row), column) Memory consumption: one (or two) int array whose length is the same as the row count l l Optional index caching feature to make reverse lookup to make get. Visual. Row. At method faster Lazy initialization l l The index array is not created until there is sorting The reverse index array is not created until get. Visual. Row. At is called 22
Sortable. Table > Sortable. Table. Header to allow click-to-sort. 23
Filterable related components > > > Different from Sortable. Table, no Filterable. Table Any JTable can be filterable if you set a Filterable. Table. Model on to it Other components work with JTable and Filterable. Table. Model to make it easy for user to add/remove filters l l Auto. Filter. Table. Header Quick. Table. Filter. Field (optionally use Lucene) Quick. Filter. Pane Table. Custom. Filter. Editor 24
If there were one thing to learn … > Remember the row index mapping idea and the table model wrapper design. 25
Case Style: Cell Spanning > Merge several cells into one big cell 26
Demo of Cell. Span. Table 27
Brainstorming > > Model: store the cell spans View: change how the grid lines are painted 28
Cell. Span > > _row: Span start row index _column: Span start column index _row. Span: The number of rows that it spans _column. Span: The number of columns that it spans Cell. Span(1, 2, 3, 4) row, column, row. Span, column. Span
Span. Model > Methods: l l > > boolean is. Cell. Span. On() Cell. Span get. Cell. Span. At(int row, int column) Any Table. Model can implement this Span. Model interface Implementations: l l Abstract. Span. Table. Model Default. Span. Table. Model: add. Cell. Span, remove. Cell. Span etc. methods
Example class My. Model extends Abstract. Table. Model implements Span. Model { ……. // all other table model methods Cell. Span span; public Cell. Span get. Cell. Span. At(int row, int column) { // define the span based on the row and column index return span; } public boolean is. Cell. Span. On() { return true; } } 31
Subclassing Basic. Table. UI > Basic. Cell. Span. Table. UI extends Basic. Table. UI l l The paint. Grid and paint. Cells methods are private End up overriding paint(g, c) method with many duplicated code
Subclassing JTable > Cell. Span. Table l l l Override get. Cell. Renderer, prepare. Renderer, get. Cell. Editor, prepare. Editor, edit. Cell. At Override row. At. Point, column. At. Point and get. Cell. Rect Override is. Cell. Selected
get. Cell. Renderer @Override public Table. Cell. Renderer get. Cell. Renderer(int row, int column) { Cell. Span cell. Span = get. Cell. Span. At(row, column); if (cell. Span != null) { return super. get. Cell. Renderer(cell. Span. get. Row(), cell. Span. get. Column()); } return super. get. Cell. Renderer(row, column); } 34
Other Considerations > > > Caching Cell. Spans at Cell. Span. Table Caching the painting of Cell. Spans in Basic. Cell. Span. Table. UI to avoid the cells in the same Cell. Span painted again and again Converting the Cell. Span when columns are rearranged (not all possible) 35
If there were one thing to learn … > Store the information along the table model by implementing a new interface 36
Case Study: Cell Styling > > > > Background (solid color or gradient) Foreground Font (font name, style, size) Border Alignment Icon Row stripes/column stripes 37
Demo of Cell. Style. Table 38
Brainstorming > Is cell styling a model concept or a view concept? 39
Brainstorming > Is cell styling a model concept or a view concept? l l l 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
Brainstorming (Cont. ) > Providing the Cellstyle l l Using Table. Model – for model related styles Using JTable – for non-model related styles 41
Cell. Style > A class define styles mentioned on the previous slide that has many setters and getters, such as l l Color get. Foreground() void set. Foreground(Color color) Border get. Border() void set. Border(Border border)
Style. Model > > Any Table. Model can implement the Style. Model interface Methods: l l boolean is. Cell. Style. On() Cell. Style get. Cell. Style. At(int row, int column)
Subclass JTable - Cell. Style. Table > Add set. Table. Style. Provider public interface Table. Style. Provider { Cell. Style get. Cell. Style. At(JTable table, int row. Index, int column. Index); } > Override prepare. Renderer/prepare. Editor methods
Implements Foreground Style > prepare. Renderer(renderer, row, column); l l l > Call super to get the renderer. Component Gets the Cell. Style(s) from the Style. Model/Table. Style. Provider If Cell. Style has a foreground defined, call renderer. Component. set. Foreground Repeat the previous step to cover all styles Basic. Table. UI will then paint the renderer. Component on the table cell What will happen if we only do this? 45
Implements Foreground Style > prepare. Renderer(renderer, row, column); l l l > Call super to get the renderer. Component Gets the Cell. Style(s) from the Style. Model/Table. Style. Provider If Cell. Style has a foreground defined, call renderer. Component. set. Foreground Repeat the previous step to cover all styles Basic. Table. UI will then paint the renderer. Component 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
Implements Foreground Style: Cont. > release. Renderer. Component(renderer, row, column, renderer. Component) l l > We changed Table. UI to always call release. Renderer. Component after the renderer. Component is painted. And we reset the foreground to its previous value in this method We suggest Sun includes this method in JTable 47
If there were one thing to learn … > Define cell styling in a consistent way for all the tables in your application l l l Define all Cell. Style instances in one place You can even create Cell. Style on fly using stylesheet or a configuration file when application starts. get. Cell. Style. At return the predefined instance. 48
Showcases 49
Q&A 50
David Qiao JIDE Software, Inc. david@jidesoft. com 51
- Slides: 51