我创建了一个JTreeTable
,其中TreeCellRenderer
是JTable
。这允许我为每一行提供不同的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个图像,我选择不同的行。忽略标题对齐,我已经有了一个解决方案,但还没有完全实现它。
对此问题的任何想法将不胜感激。如果您认为它有用,也很乐意发布您认为可能有用的任何代码。
答案 0 :(得分:0)
因此经过大量修改和调查后,由于没有表格的滚动窗格。我最初没有这样做,因为它在它周围放置了一个时髦的边框,并将边框设置为null无法正常工作。我要做的就是设置一个空边框。