2017-05-28 111 views
0

我正在構建一個JTreeTable。我發現了一些入門代碼,並且已經非常成功。最終,我的目標是能夠在不同層次上擁有不同的數據,如分層列表。JTreeTable的動態列

目前,我有它處理不同級別的數據。然而,當談到改變列作爲下一個目標時,我正遇到困難。從我目前站在我有3個里程碑:

  • 顯示不同的列集合供不同層次的
  • 能夠調整列寬爲不同層次
  • 保證檯面的JTree的部分一直保持到左

我越來越接近收盤這項任務,但再次停留在第一項3.

由於製作JTreeTable複雜,微量嗯例如利用圖像中的下列幾類:

enter image description here

我很高興代碼發佈到任何類的,但我也不想堵塞無用的代碼的問題。首先讓我展示我想要的功能。

第一個圖像是當選擇頂層時,第二個圖像是當第二個層次被選中。注意列的不同。這就是我想要在我的應用程序中發生的事情。

選擇頂級:

JTreeTable-TopLevelSelected

第二級選擇:

JTreeTable-SecondLevelSelected

所以我試圖解決這個問題的一種方式,當列表選擇在此部分代碼內更改:

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和表格上設置列模型。下面是當我選擇一排,然後什麼發生了:

JTreeTable-ColumnModelUpdated

列只是消失在我身上。列模型的建立在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; 
} 

任何方向將是非常有益的。再次高興地發佈您認爲可能有助於回答問題的任何代碼。只需發表評論,我將立即添加。

回答

0

我會添加里程碑,因爲我發現它們可以幫助其他人,但現在這個問題得到了解答。

里程碑1

實際上,我是能夠解決的第一個里程碑。關鍵是要觸發創建列模型的列,而不是創建新的列模型。下面是當行選擇改變的代碼:

//Change columns depending on row 
ListSelectionListener listener = (ListSelectionEvent e) -> { 
    createDefaultColumnsFromModel(); 
}; 
this.getSelectionModel().addListSelectionListener(listener); 

此代碼創建基於JTreeTableJTree部分選擇該行的列。 TreeTableModelAdapter通過將JTree中的選定行傳遞給JTreeTableModel來實現getColumnCount()getColumnName()方法,以便根據JTree中的特定節點動態檢索列及其名稱。這對我的關鍵是觸發那些被再次調用來更新JTreeTable

里程碑2

基礎上證明了數據級調整列寬要困難得多,比我原先的預期。爲了在柱模型改變時保留單元格狀態,我必須斷開單元格的繪畫。這是一個多毛的過程,因爲這是在BasicTableUI內部完成的,並且獲取單元矩形的方法是私有的。所以我不得不對它進行子類化,重載paint()方法並創建我自己的方法,這些方法在paint方法內被調用。有很多複製粘貼,以便我可以通常調用私人方法。我只是重新命名了它們,並引用了這些方法。 ui課程的設計方式並不是很靈活。下面是我選擇不同層次的2張圖片,不同層次的列寬明顯不同。

TopLevel

SecondLevel

里程碑3

我能夠保持在模型視圖的軌道,使這項工作。這對我來說似乎很骯髒,因爲模型應該與觀點分開。由於樹列的類是唯一的,所以如果該列是視圖中的第一個,我就返回了正確的類。

我用這種技術遇到的一個問題是,當返回的值不一致時,我得到意外的行爲。我試圖通過覆蓋JTree.covertValueToText()來解決這個問題。由於JTree只預計1個值,並且根據視圖中列的順序,此值可能會發生變化。因此,在重寫此方法時,我檢查存儲的JTree列值的索引。這又會導致意外的行爲。如果我找到修復,我會更新這篇文章。