JTable正在调整列宽

时间:2017-06-03 18:37:12

标签: java swing jtable jtree jtreetable

我创建了一个JTreeTable,其中TreeCellRendererJTable。这允许我为每一行提供不同的TableColumnModel s。 JTree的兄弟姐妹共享TableColumnModel。它很棒。我可以选择一行并显示一组不同的列,而不会实际更改其他行中的数据,即使在不同的级别也是如此。

我遇到了一个问题,但是当选择一个不同的行时,JTable正在改变TableColumn的宽度并将其设置为首选大小。因此效果是拖动一列的宽度然后选择另一行将其设置回首选大小。

我已经尝试了很多方法来解决这个问题,包括添加TableColumnModelListener,当我更改宽度时,我设置了列的首选大小。这不起作用,因为JTable在我更改之后将首选大小设置为15。

我已经将代码追溯到造成这种情况的原因。 JTable.doLayout()方法导致了我的悲伤。该方法调用私有方法setWidthsFromPreferredWidths(...)。这个方法就是设置我的TableColumn宽度。

我尝试重写doLayout()方法,因为它是公开的,但是当我已经覆盖了该方法时,我无法调用super.doLayout()。不调用会导致一些非常奇怪的UI问题,正如您所想象的那样。我还尝试将this转换为JTable的超类JComponent,但最终出现堆栈溢出错误。无论如何,这不是正确的解决方案。

我认为发生的事情是因为我的JTable在一个面板内部作为树状单元格的渲染器而不是在滚动窗格内部,因此布局出现了问题。我不会这样做。但是我知道肯定。下面是我在上面引用的私有方法中的代码:

private void setWidthsFromPreferredWidths(final boolean inverse) {
    int totalWidth     = getWidth();
    int totalPreferred = getPreferredSize().width;
    int target = !inverse ? totalWidth : totalPreferred;

    final TableColumnModel cm = columnModel;
    Resizable3 r = new Resizable3() {
        public int  getElementCount()      { return cm.getColumnCount(); }
        public int  getLowerBoundAt(int i) { return cm.getColumn(i).getMinWidth(); }
        public int  getUpperBoundAt(int i) { return cm.getColumn(i).getMaxWidth(); }
        public int  getMidPointAt(int i)  {
            if (!inverse) {
                return cm.getColumn(i).getPreferredWidth();
            }
            else {
                return cm.getColumn(i).getWidth();
            }
        }
        public void setSizeAt(int s, int i) {
            if (!inverse) {
                cm.getColumn(i).setWidth(s);
            }
            else {
                cm.getColumn(i).setPreferredWidth(s);
            }
        }
    };

    adjustSizes(target, r, inverse);
}

查看代码,我认为发生的事情是getWidth()方法导致JTable想要将列的大小调整为preferredsize,因为它认为它没有足够的空间。我试着在本地复制粘贴这个方法,但由于涉及私有方法并且它越来越深入我停止了。目的是尝试调试为什么选择调整宽度。如果我能解决根本原因,那可能是最好的解决方案。

JTree本身位于JScrollPane内。 JTableHeader设置为ViewPortColumnHeaderView。下面是2个图像,我选择不同的行。忽略标题对齐,我已经有了一个解决方案,但还没有完全实现它。

JTreeTable-Level1 JTreeTable-Level2

对此问题的任何想法将不胜感激。如果您认为它有用,也很乐意发布您认为可能有用的任何代码。

1 个答案:

答案 0 :(得分:0)

因此经过大量修改和调查后,由于没有表格的滚动窗格。我最初没有这样做,因为它在它周围放置了一个时髦的边框,并将边框设置为null无法正常工作。我要做的就是设置一个空边框。