2

SwingX のTableColumnExtクラスを使用して、a の階層列の列幅のプロトタイプ値を設定しようとしていますJXTreeTable。モデルとテーブルを初期化したら、次のようにします。

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

テーブルがレンダリングされると、すべての列が同じサイズになります。これらは、JXTreeTableインスタンスで使用しているメソッドです。

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

ここで何が間違っていますか?

4

1 に答える 1

2

コメントで既に述べたように、これはバグです。問題は多岐にわたります。

  • プロトタイプのサイズ要件を測定するコードは、ColumnFactory.calcPrototypeWidth です。
  • これは、指定されたプロトタイプを使用してテーブルによって返されるようにレンダラーを構成し、その prefSize を測定することによって行われます。
  • 階層列のレンダリングは、ブラック マジックを使用して JTree に委任されます。
  • デフォルトのファクトリはその黒魔術を認識していないため、プロトタイプから独立した JTree の prefSize を照会します。
  • 最初のアイデア: ファクトリに階層列の特別なレンダリングを認識させ、実際のツリー (基になる treeCellRenderer) に降りていきますが、これも他の内部黒魔術が原因で機能しません。
  • プロトタイプの設定による列の自動サイズ変更が JXTable で壊れている (問題 #1510 )

回避策には以下が含まれます

  • 階層列の特別なレンダラー (== JXTree) を認識するカスタム ColumnFactory)
  • 階層列の場合、TreeCellRenderer を構成および測定します。これは、ツリー自体で使用されるものではなく、無関係のダミーです。
  • プロトタイプを設定した後、列のサイズ評価を手動でトリガーします

以下は、カスタムの ColumnFactory とその使用法です (正式にテストされていないため、多少の誤解があるかもしれません :-)。

// 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));
于 2012-07-16T15:06:37.620 に答える