문제

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?

도움이 되었습니까?

해결책

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

  • the code responsible for measuring the prototype size requirements is ColumnFactory.calcPrototypeWidth
  • it's doing so by configuring the renderer as returned by the table with the given prototype and measuring its prefSize
  • the rendering of the hierarchical column is delegated to a JTree, using black magic
  • the default factory is unaware of that black magic, thus querying the JTree's prefSize which is independent of the prototype
  • the first idea: make the factory aware of the special rendering of the hierarchical column and walk down to the real - underlying treeCellRenderer - doesn't work, again due to some other internal black magic
  • automatic column re-sizing due to setting the prototype is broken in JXTable (Issue #1510)

A workaround involves

  • a custom ColumnFactory which is aware of the special renderer (== JXTree) of the hierarchical column)
  • for the hierarchical column, configure and measure a TreeCellRenderer - not the one used by the tree itself, but a unrelated dummy
  • after setting the prototype, manually trigger a size evaluation of the column

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));
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top