1 / 51

TS-4706 Bringing JTable to the Extreme

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

sahkyo
Download Presentation

TS-4706 Bringing JTable to the Extreme

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


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

  2. 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

  3. Goal • Explore the internals of JTable • Find a way to enhance it to meet requirements

  4. JTable: 101 JTable TableModel TableUI (BasicTableUI) TableCellRenderer TableCellEditor JTableHeader TableColumn TableColumnModel

  5. JTable • Nothing but a bunch of cells arranged in grid-like layout • Not enough in an real world application

  6. 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)

  7. 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)

  8. Possible Enhancements: Table Model • Sorting • Filtering • Grouping • Caching • Paginating • JavaBean Support • JDBC or Hibernate Support

  9. Possible Enhancements: Renderer/Editor • More cell renderers and editors for various data types • Numbers • Color • Date/Calendar • Font • Insets • Array

  10. 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

  11. 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

  12. 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

  13. Case Studies • Filtering and Sorting • Cell Spanning • Cell Styling

  14. Case Study: Filtering and Sorting • The original TableModel should NOT be touched • Performance and memory • Scalability

  15. Demo of Sortable and Filterable Feature

  16. 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

  17. 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 • TableModelgetActualModel() • RowTableModelWrapper • Provides row index mapping • intgetActualRowAt(intvisualRowIndex) • intgetVisualRowAt(intactualRowIndex)

  18. SortableTableModel Actual TableModel SortableTableModel (set to a table) . . .

  19. Implementation of getValueAt method public 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].

  20. FilterableTableModel Actual TableModel FilterableTableModel (set to a table)

  21. TableModelWrapper “Pipes” Sortable TableModel (1) Filterable TableModel (n) Actual TableModel (1) JTable

  22. 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 arrayis not created until getVisualRowAt is called

  23. SortableTable • SortableTableHeader to allow click-to-sort.

  24. 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

  25. If there were one thing to learn … • Remember the row index mapping idea and the table model wrapper design.

  26. Case Style: Cell Spanning • Merge several cells into one big cell

  27. Demo of CellSpanTable

  28. Brainstorming • Model: store the cell spans • View: change how the grid lines are painted

  29. 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

  30. SpanModel • Methods: • boolean isCellSpanOn() • CellSpan getCellSpanAt(int row, int column) • Any TableModel can implement this SpanModel interface • Implementations: • AbstractSpanTableModel • DefaultSpanTableModel: addCellSpan, removeCellSpan etc. methods

  31. Example class MyModel extends AbstractTableModelimplements 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; } }

  32. Subclassing BasicTableUI • BasicCellSpanTableUI extends BasicTableUI • The paintGrid and paintCells methods are private • End up overriding paint(g, c) method with many duplicated code

  33. Subclassing JTable • CellSpanTable • Override getCellRenderer, prepareRenderer, getCellEditor, prepareEditor, editCellAt • Override rowAtPoint, columnAtPoint and getCellRect • Override isCellSelected

  34. 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); }

  35. 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)

  36. If there were one thing to learn … • Store the information along the table model by implementing a new interface

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

  38. Demo of CellStyleTable

  39. Brainstorming • Is cell styling a model concept or a view concept?

  40. 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

  41. Brainstorming (Cont.) • Providing the Cellstyle • Using TableModel – for model related styles • Using JTable – for non-model related styles

  42. 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)

  43. StyleModel • Any TableModel can implement the StyleModel interface • Methods: • boolean isCellStyleOn() • CellStylegetCellStyleAt(int row, int column)

  44. Subclass JTable - CellStyleTable • Add setTableStyleProvider public interface TableStyleProvider { CellStylegetCellStyleAt(JTable table, int rowIndex, int columnIndex); } • Override prepareRenderer/prepareEditor methods

  45. 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?

  46. 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.

  47. 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

  48. 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.

  49. Showcases

  50. Q & A

More Related