我创建了一个JTreeTable
where the TreeCellRenderer
is a JTable
。这使我可以TableColumnModel
为每一行设置不同的 s。兄弟姐妹的JTree
共享一个TableColumnModel
。它工作得很好。我可以选择一行并显示一组不同的列,而无需实际更改其他行中的数据,即使在不同级别也是如此。
I have a problem though where when select a different row the JTable is changing my TableColumn
s width and setting it to the preferred size. 所以效果是拖动一列的宽度,然后选择不同的行将其设置回首选大小。
我已经尝试了很多方法来解决这个问题,包括添加 aTableColumnModelListener
并且当我更改宽度时,我设置了列的首选大小。这不起作用,因为 JTable 在我更改它后将首选大小设置为 15。
我已经将代码追溯到导致此问题的原因。这是JTable.doLayout()
造成我悲伤的方法。该方法正在调用私有方法setWidthsFromPreferredWidths(...)
。此方法是设置我的 TableColumn 宽度的方法。
我尝试覆盖该方法,因为它是公共的,但是当我已经覆盖该方法时我doLayout()
无法调用。super.doLayout()
如您所想,不调用它会导致一些非常奇怪的 UI 问题。我还尝试转换为isthis
的超类,但最终出现堆栈溢出错误。无论如何,这感觉不是正确的解决方案。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 想要将列调整为首选大小,因为它认为它没有足够的空间。我尝试在本地复制粘贴此方法,但由于涉及私有方法并且它越来越深,我停止了它。目的是尝试调试为什么选择调整宽度。如果我能解决根本原因,那可能是最好的解决方案。
JTree
本身在JScrollPane
. JTableHeader
设置ViewPortColumnHeaderView
为。下面是我选择不同行的 2 张图片。忽略标题对齐,我已经有一个解决方案,只是还没有完全实现它。
对这个问题的任何想法将不胜感激。如果您认为它会有所帮助,也很乐意发布您认为可能有用的任何代码。