Java JTreeTable的动态列

Java JTreeTable的动态列,java,treetable,Java,Treetable,我正在建造一个JTreeTable。我找到了一些启动代码,已经走了相当远。最终,我的目标是能够在不同的级别上拥有不同的数据,就像一个分层列表一样 目前,我有它在不同级别的数据工作。然而,当我下一个目标是改变立柱时,我遇到了困难。从我目前的立场来看,我还有3个里程碑: 显示不同级别的不同列集 能够调整不同级别的列宽 确保桌子的JTree部分始终保持在左侧 我即将完成这项任务,但又一次陷入了这3项任务中的第一项 由于创建JTreeTable非常复杂,因此最简单的示例利用了下图中列出的几个类:

我正在建造一个JTreeTable。我找到了一些启动代码,已经走了相当远。最终,我的目标是能够在不同的级别上拥有不同的数据,就像一个分层列表一样

目前,我有它在不同级别的数据工作。然而,当我下一个目标是改变立柱时,我遇到了困难。从我目前的立场来看,我还有3个里程碑:

  • 显示不同级别的不同列集
  • 能够调整不同级别的列宽
  • 确保桌子的JTree部分始终保持在左侧
我即将完成这项任务,但又一次陷入了这3项任务中的第一项

由于创建JTreeTable非常复杂,因此最简单的示例利用了下图中列出的几个类:

我很乐意将代码发布到这些类中的任何一个,但我也不想用无用的代码来阻塞这个问题。首先让我展示我想要的功能

第一个图像是选择顶层时的图像,第二个图像是选择第二层时的图像。请注意这些列是如何不同的。这就是我希望在我的应用程序中实现的

所选顶级:

选择第二级:

因此,我试图解决这个问题的一种方法是,在这段代码中更改列表选择:

ListSelectionListener listener = (ListSelectionEvent e) -> {
        TreeTableModelAdapter adapter = (TreeTableModelAdapter) JTreeTable.this.getModel();
        //Need to see why this breaks.
        JTreeTable.this.getTableHeader().setColumnModel(adapter.getColumnModel());
    };
    this.getSelectionModel().addListSelectionListener(listener);
此代码位于JTreeTable的初始化中。我已经尝试在TableHeader和table上设置列模型。下面是我选择一行时发生的情况:

柱子就在我身上消失了。列模型的创建是在
TreeTableModelAdapter
类中使用以下方法进行的:

public TableColumnModel getColumnModel(){
     DefaultTableColumnModel model  = new DefaultTableColumnModel();
     for(int i=0;i<getColumnCount();i++){
         TableColumn column = new TableColumn();
         column.setIdentifier(getColumnName(i));
         model.addColumn(column);
     }
     return model;
 }
public TableColumnModel getColumnModel(){
DefaultTableColumnModel=新的DefaultTableColumnModel();

对于(int i=0;i我将添加我发现的里程碑,以防这有助于其他人,但现在这个问题已经得到了回答

里程碑1

我实际上能够解决第一个里程碑。关键是触发列模型列的创建,而不是创建新的列模型。下面是更改行选择时的代码:

//Change columns depending on row
ListSelectionListener listener = (ListSelectionEvent e) -> {
    createDefaultColumnsFromModel();
};
this.getSelectionModel().addListSelectionListener(listener);
此代码基于
JTreeTable
部分的
JTree
中选择的行创建列。
TreeTableModelAdapter
实现
getColumnCount()
getColumnName()
方法,将
JTree
中选定的行传递给
JTreeTableModel
,以便根据
JTree
中的特定节点动态检索列及其名称。对我来说,关键是再次调用这些列以更新
JTreeTable

里程碑2

事实证明,根据数据级别调整列宽比我最初预期的要困难得多。为了在列模型更改时保持单元格状态,我必须断开单元格的绘制。这是一个复杂的过程,因为这是在
BasicTableUI
和获取rec的方法中完成的细胞的缠结是私有的,所以我不得不对它进行子类化,使
paint()过载
method并创建我自己的方法,这些方法在paint方法中被调用。有很多复制粘贴,因此我可以调用正常的私有方法。我只是重命名了它们并引用了这些方法。ui类的设计方式并没有使其非常灵活。下面是两张图片,我在其中选择了不同的级别和c在不同的水平上,柱的宽度明显不同

里程碑3

我能够通过跟踪模型中的视图来实现这一点。这对我来说似乎非常脏,因为模型应该与视图分离。由于树列的类是唯一的,如果该列是视图中的第一列,我只返回了正确的类

这种技术的一个问题是,在返回的值不一致的情况下,会出现意外行为。我试图通过重写
JTree.covertValueToText()来解决此问题
。由于JTree只需要1个值,并且根据视图中列的顺序,此值可能会更改。因此,在重写此方法时,我会检查存储的索引中JTree列的值。这同样会导致意外行为。如果找到修复方法,我将更新帖子