java - 如何在 JTable 中排除自动调整大小的列

标签 java swing jtable

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

更详细:

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

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

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

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

提前致谢!

最佳答案

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

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

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

基本上,诀窍是在调整其中一列大小的同时“修复”其他可调整大小的列的大小。 “修复”是通过将其最小值/最大值设置为其首选来实现的。然后,在 AUTO_RESIZE_ALL_COLUMNS 模式下,剩余列的空间均匀分布将自动发生。问题是检测调整大小开始/停止: JTableHeader 有一个属性 resizingColumn ,不幸的是,该属性在核心中未绑定(bind)(又名:不会在更改时触发)。另一方面,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 以返回子类化的 header

享受吧! 珍妮特

关于java - 如何在 JTable 中排除自动调整大小的列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5469739/

相关文章:

java - 是否可以在 Vaadin 14 和 RouterLink 中添加 uri 的 #fragment 部分?

java - 如何在 JTable 上显示行标题而不是列标题

java - 如何在 Java 中创建一个在您键入时将 URL 转换为超链接的 JTable

java JTable 单元格更改

java - 在frame中嵌套Panel实现动画

java - 如果我使用synchronized,我应该使用 volatile 吗?

java - Jackson 忽略@Ignore 注释

java - Picasso 加载 PHOTO_THUMBNAIL_URI 但不加载 PHOTO_URI

java - Nimbus JTree 在java 1.8 版本下呈现错误

java - ImageIO.read(URL) 需要很长时间