javaswingswingxjxtreetable

TableColumnExt not respecting prototype value


I'm trying to use SwingX's TableColumnExt class to set a prototype value for the column's width in the hierarchical column of a JXTreeTable. After I initialize the model and table I do this:

TableColumnExt column = dataTable.getColumnExt(0);            
column.setPrototypeValue(500);

When my table is rendered, all columns are equally sized. These are the methods I'm using on the JXTreeTable instance.

dataTable.setRowHeight(28);
dataTable.setFillsViewportHeight(true);
dataTable.setHorizontalScrollEnabled(true);

What am I doing wrong here?


Solution

  • As already mentioned in my comments, it's a bug. The issues are many-fold:

    A workaround involves

    Below is a custom ColumnFactory and its usage (not formally tested, so take it with a grain of salt :-).

    // a custom factory
    ColumnFactory factory = new ColumnFactory() {
    
        @Override
        protected int calcPrototypeWidth(JXTable table,
                TableColumnExt columnExt) {
            if (isHierarchicalPrototype(table, columnExt))  {
                return calcHierarchicalPrototypeWidth((JXTreeTable) table, columnExt);
            }
            return super.calcPrototypeWidth(table, columnExt);
        }
    
        protected boolean isHierarchicalPrototype(JXTable table,
                TableColumnExt columnExt) {
            return (table instanceof JXTreeTable) 
                    && ((JXTreeTable) table).getTreeTableModel().getHierarchicalColumn() == 
                             columnExt.getModelIndex()
                    && columnExt.getPrototypeValue() != null;
        }
    
        TreeCellRenderer dummy = new DefaultTreeCellRenderer();
        protected int calcHierarchicalPrototypeWidth(JXTreeTable table,
                TableColumnExt columnExt) {
            JXTree renderer = (JXTree) getCellRenderer(table, columnExt);
            // commented lines would be the obvious step down into the "real" sizing
            // requirements, but giving reasonable result due to internal black magic
            // TreeCellRenderer treeRenderer = renderer.getCellRenderer();
            // Component comp = treeRenderer.getTreeCellRendererComponent(renderer, 
                  columnExt.getPrototypeValue(), false, false, false, -1, false);
            // instead, measure a dummy
            Component comp = dummy.getTreeCellRendererComponent(renderer, 
                    columnExt.getPrototypeValue(), false, false, false, -1, false);
    
            return Math.max(renderer.getPreferredSize().width, comp.getPreferredSize().width);
        }
    
    };
    
    // usage: first create the treeTable, set the factory and set the model
    JXTreeTable table = new JXTreeTable();
    table.setColumnFactory(factory);
    table.setTreeTableModel(new FileSystemModel());
    // set the prototype
    table.getColumnExt(0).setPrototypeValue("long longer longest still not enough to really see" +
               " some effect of the prototype if available");
    // Issue #1510: prototype value handling broken in underlying JXTable
    // need to manually force the config
    table.getColumnFactory().configureColumnWidths(table, table.getColumnExt(0));