如何从JTable中的自动调整大小中排除列

时间:2011-03-29 08:23:40

标签: java swing jtable

我有一个JTable,在TableColumnModel中指定了5个列。我希望表格使用面板中所有可用的水平空间(可能会有所不同),但我想将调整大小限制为最后三行。

更详细:

使用首选宽度初始化前两列,但是用户应该能够通过鼠标拖动手动调整列的大小。

最后三列应该平均分配前两列未使用的所有剩余空间。编辑:他们还需要手动调整大小。

我尝试过以下方法: 将表设置为autoResizeMode JTable.AUTO_RESIZE_ALL_COLUMNS。这成功了 耗尽所有可用空间,但(显然)它也调整了前两列的大小。 我通过设置前两列的最小值和最大值来对此作出反应。这工作, 但它违反了我手动调整大小的限制。

JTable - API中是否有一种简单的方法可以实现这一目标?

提前致谢!

2 个答案:

答案 0 :(得分:1)

正如托马斯已经回答的那样,没有简单的api来实现你想要的东西:你必须自己实现这个行为。在一般情况下,这可能不是微不足道的,但在具体情况下可以管理。只是为了确保我正确理解您的要求:

A)用户可以调整2列,3个列不可由用户调整(它们应具有相同的宽度)

B)当用户调整2个可调整大小的列中的一个时,其他可调整大小的列应保持其当前宽度,任何空间分布应仅影响3个不可调整大小的列,均匀分布其上的多余/缺失宽度。 / p>

基本上,诀窍是“修复”其他可调整大小的列的大小,同时调整其中一个的大小。通过将其最小值/最大值设置为其首选值来实现“修复”。然后,在AUTO_RESIZE_ALL_COLUMNS模式下,其余列的空间均匀分布将自动发生。问题是检测调整大小的开始/停止:JTableHeader有一个属性resizingColumn,遗憾的是在核心中未绑定(也就是说:不会触发更改)。另一方面,SwingX(你已经猜到我迟早会提到SwingX :-)将该属性提升为一个成熟的bean属性 - 所以只需适当地监听并更新最小/最大大小约束。这是使用SwingX的代码片段

// custom ColumnFactory to configure the columns
ColumnFactory factory = new ColumnFactory(){

    /** 
     * @inherited <p>
     */
    @Override
    public void configureTableColumn(TableModel model,
            TableColumnExt columnExt) {
        super.configureTableColumn(model, columnExt);
        columnExt.setResizable(columnExt.getModelIndex() < 2);
        if (columnExt.getModelIndex() >= 2) {
            columnExt.setPreferredWidth(50);
        } else {
            columnExt.setPreferredWidth(150);
        }
    }

    /** 
     * @inherited <p>
     * Overridden to do nothing
     */
    @Override
    public void configureColumnWidths(JXTable table,
            TableColumnExt columnExt) {
    }

};

final JXTable table = new JXTable();
table.setColumnFactory(factory);
table.setModel(new DefaultTableModel(20, 5));
// propertyChangeListener
PropertyChangeListener l = new PropertyChangeListener() {

    TableColumn first = table.getColumn(0);
    TableColumn second = table.getColumn(1);

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        TableColumn resizingColumn = (TableColumn) evt.getNewValue();
        if (resizingColumn == null) {
            TableColumn oldResizing = (TableColumn) evt.getOldValue();
            TableColumn other = oldResizing == first ? second : first;
            other.setMaxWidth(Integer.MAX_VALUE);
            other.setMinWidth(15);
        } else {
            TableColumn other = resizingColumn == first ? second : first;
            other.setMaxWidth(other.getPreferredWidth());
            other.setMinWidth(other.getPreferredWidth());
        }

    }
};

table.getTableHeader().addPropertyChangeListener("resizingColumn", l);

这是SwingX的懒惰 - 很容易实现自己:

a)手动配置tableColumns

b)子类JTableHeader并实现setResizingColumn以在更改时触发

c)子类JTable并实现createTableHeader以返回子类标题

享受! 珍

答案 1 :(得分:0)

AFAIK无法从自动调整中排除列。设置最小/最大大小会影响大小计算,但是从JTable源看来,您似乎无法排除列。

使用JTable.AUTO_RESIZE_ALL_COLUMNS时,无法限制要调整大小的列范围。因此,调用表模型来设置每列的列宽,并应用约束。但是,我没有看到表模型可以区分自动和手动调整大小。