2017-05-28 3 views
0

Ich baue eine JTreeTable. Ich habe einen Startcode gefunden und bin ziemlich weit gekommen. Letztendlich ist es mein Ziel, verschiedene Daten auf verschiedenen Ebenen wie eine hierarchische Liste zu haben.Dynamische Spalten für JTreeTable

Derzeit habe ich es mit Daten auf verschiedenen Ebenen arbeiten. Ich renne jedoch gegen eine Wand, wenn es darum geht, die Säulen als nächstes Ziel zu wechseln. Von dort, wo ich zur Zeit stehe ich habe 3 weitere Meilensteine:

  • zeigen andere Gruppe von Spalten für die verschiedenen Ebenen
  • Fähigkeit Spaltenbreiten für die verschiedenen Ebenen
  • Sicherstellen, dass der JTree Teil der Tabelle einzustellen bleibt immer nach links

ich bin immer in der Nähe, diese Aufgabe zu schließen, sondern wieder bei der ersten dieser

3. stecken ein JTreeTable ist komplex Seit der Erstellung der minim um Beispiel nutzt mehrere Klasse im Bild unten aufgeführt:

enter image description here

Ich bin glücklich, den Code zu einem dieser Klassen zu schreiben, aber ich habe auch nicht, dass die Frage mit nutzlosem Code verstopfen. Lassen Sie mich zuerst die Funktionalität zeigen, die ich möchte.

Das erste Bild ist, wenn die oberste Ebene ausgewählt ist und das zweite Bild ist, wenn die zweite Ebene ausgewählt ist. Beachten Sie, dass die Spalten unterschiedlich sind. Das möchte ich in meiner Bewerbung machen.

Top Level ausgewählt:

JTreeTable-TopLevelSelected

Zweite Ebene ausgewählt:

JTreeTable-SecondLevelSelected

So eine Art und Weise habe ich versucht, dieses Problem zu lösen, wird, wenn die Listenauswahl ist innerhalb dieses Codeabschnitts geändert:

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); 

Dieser Code befindet sich in der Initialisierung von JTreeTable. Ich habe versucht, das Spaltenmodell sowohl auf dem TableHeader als auch auf der Tabelle zu setzen. Im Folgenden finden Sie, was dann passiert, wenn ich eine Zeile auswählen:

JTreeTable-ColumnModelUpdated

Die Säulen nur auf mich verschwinden. Die Schaffung des Säulenmodell geschieht in der TreeTableModelAdapter Klasse mit der folgenden Methode:

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; 
} 

Jede Richtung wäre sehr hilfreich. Ich freue mich schon darauf, einen Code zu veröffentlichen, der Ihrer Meinung nach hilfreich sein könnte, um die Frage zu beantworten. Schreiben Sie einfach einen Kommentar und ich werde es sofort hinzufügen.

Antwort

0

Ich werde die Meilensteine ​​hinzufügen, wie ich sie finde, falls dies anderen hilft, aber jetzt ist diese Frage beantwortet.

Milestone 1

war ich tatsächlich in der Lage den ersten Meilenstein zu lösen. Der Schlüssel besteht darin, die Erstellung der Spalten des Spaltenmodells auszulösen und kein neues Spaltenmodell zu erstellen. Unten ist der Code für, wenn die Zeilenauswahl geändert wird:

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

Dieser Code die Spalten erzeugt auf der Zeile in dem JTree Teil der JTreeTable ausgewählt basieren. Die Methode TreeTableModelAdapter implementiert die Methoden getColumnCount() und getColumnName(), indem auch die ausgewählte Zeile in JTree an die JTreeTableModel übergeben wird, sodass die Spalten und ihre Namen basierend auf einem bestimmten Knoten in JTree dynamisch abgerufen werden. Der Schlüssel hierfür war für mich Trigger die erneut aufgerufen werden sollen, um die JTreeTable zu aktualisieren.

Milestone 2

Anpassen der Spaltenbreite auf der Datenebene auf Basis erwies sich als viel schwieriger zu sein, als ich ursprünglich erwartet hatte. Um den Zellenzustand beizubehalten, als sich das Spaltenmodell änderte, musste ich die Abbildung der Zellen davon trennen. Dies ist ein haariger Prozess, da dies innerhalb BasicTableUI erfolgt und die Methode, die das Rechteck der Zelle erhält, privat ist. Also musste ich eine Unterklasse erstellen, die paint() Methode überladen und meine eigenen Methoden erstellen, die innerhalb der Paint-Methode aufgerufen werden. Es wurde viel kopiert, so dass ich normalerweise private Methoden aufrufen konnte. Ich habe sie nur umbenannt und stattdessen auf diese Methoden verwiesen. Die Art, wie die ui-Klasse entworfen wurde, hat es nicht sehr flexibel gemacht. Unten sind 2 Bilder, wo ich verschiedene Ebenen auswähle und die Spalten sind offensichtlich unterschiedlich breit auf verschiedenen Ebenen.

TopLevel

SecondLevel

Milestone 3

konnte ich diese Arbeit machen, indem sie in der Modellbahn der Ansicht zu halten. Das scheint mir sehr dreckig zu sein, da das Modell von der Sicht getrennt sein sollte. Da die Klasse der Baumspalte eindeutig ist, habe ich nur die richtige Klasse zurückgegeben, wenn diese Spalte die erste in der Ansicht war.

Das einzige Problem, das ich mit dieser Technik habe, ist, dass ich unerwartetes Verhalten bekomme, wo der zurückgegebene Wert nicht konsistent ist. Ich habe versucht, dies zu beheben, indem ich JTree.covertValueToText() überschreiben. Da ein JTree nur 1 Wert erwartet und abhängig von der Reihenfolge der Spalten in der Ansicht, könnte sich dieser Wert ändern. Beim Überschreiben dieser Methode überprüfe ich den gespeicherten Index auf den Wert der JTree-Spalte. Dies führt wiederum zu dem unerwarteten Verhalten. Ich werde den Beitrag aktualisieren, wenn ich den Fix finde.

Verwandte Themen