JavaFX TreeView dynamisch aus Datenbank Tabelle erstellen

ralfb1105

Bekanntes Mitglied
Hallo zusammen,

ich habe mal wieder ein Problem für das ich so recht keine Lösung finde, bzw. mir fehlt der Funke um zu verstehen wie ich das Problem angehen kann.
Hier die Problemstellung:

Ich habe eine Datenbank Tabelle mit folgender Struktur und mal 3 Test Zeilen:
SIDVERSIONPATCHSYSPWDTNSPORTSERVERROOTPWDSERVEROSIPADDRESSSSHPORT
ORCL1111.2.0.4123456abcdef1521server1xyzRed Hat192.168.0.9921
ORCL2112.1.0.2567898abcedf1521server1xyzRed Hat192.168.0.9921
ORCL2212.1.0.2452367ghdhjd1521server2xyzSUSE10.10.10.1021

Die Tabelle wir natürlich erweitert bzw. es können auch Zeilen gelöscht werden.

Aus dieser Tabelle möchte ich noch folgenden TreeView erstellen:

Code:
ROOT
 \__ 11.2.0.4
            \__ ORCL11:Patch#123456:SERVEROS#Red Hat
 \__ 12.1.0.2
            \__ ORCL21:Patch#567898:SERVEROS#Red Hat
            \__ ORCL22:Patch#452367:SERVEROS#SUSE

Den Root Node möchte ich nicht sehen, wenn ich es richtig verstanden habe benötigt aber jeder TreeView einen Root Node. Diesen kann man aber wohl über:
Java:
treeViewSID.setShowRoot(false);
ausblenden.

Dann sollte jeder Node aus dem TreeView der die SID enthält, also nicht die Parents (11.2.04 / 12.1.0.2 / etc.) "clickbar sein, da ich je nach Auswahl dann ein weiteres Fenster öffen möchte in dem ich dann die weiteren Details zu der SID darstelle und weiter Aktionen (Connect to SID, open putty to server, etc.) anbiete.

Das mit dem clicken der Nodes habe ich schon mal an Hand einer manuell erstellen TreeView getestet. Hier der Code dazu:
In der initialize() Methode einen EventHandler registrieren:
Java:
EventHandler<MouseEvent> mouseEventHandle = (MouseEvent event) -> {
            handleTreeMouseClicked(event);
        };

treeViewSID.addEventHandler(MouseEvent.MOUSE_CLICKED, mouseEventHandle);

Dann die Methode die augeführt wird wenn der Event erfolgt:
Java:
private void handleTreeMouseClicked(MouseEvent event) {
        Node node = event.getPickResult().getIntersectedNode();
        // Accept clicks only on node cells, and not on empty spaces of the TreeView
        if (node instanceof Text || (node instanceof TreeCell && ((TreeCell) node).getText() != null)) {
            String name = (String) ((TreeItem) treeViewSID.getSelectionModel().getSelectedItem()).getValue();
            if (!name.equals("11.2") && !name.equals("12.1") && !name.equals("12.2") && !name.equals("18.3"))
                System.out.println("Node click: " + name);
        }
    }

Frage:

Wie kann ich denn aus der Tabelle einen TreeView erstellen der die Versionen als Parent hat und alle SIDs je nach Version dem Parent zuordnet?

Gruß

Ralf
 

ralfb1105

Bekanntes Mitglied
Hallo zusammen,

ich habe mal was versucht, das führt auch zu einem Ergebnis, ist aber bei weitem nicht dynamisch :eek:
Hier mal mein Versuch, mit der Hoffnung das Ihr noch bessere Ideen habt ;)

1. Ich babe in meinem Model pro Version, spricht Parent Node, eine List erstellt:
Java:
private List<TreeItem<String>> treeItemList11204;
private List<TreeItem<String>> treeItemList12102;
private List<TreeItem<String>> treeItemList12201;
private List<TreeItem<String>> treeItemList18300;
private List<TreeItem<String>> treeItemList18500;

Hierzu die entsprechenden Getter und Setter Methoden generiert, den Copde spare ich mir hier jetzt mal.

Im DAOService folgende Methode die mir eine List<TreeItem<String>> zurück gibt:
Java:
public List<TreeItem<String>> generateTreeItem(String version) {
        List<TreeItem<String>> treeItemList = new ArrayList<TreeItem<String>>();
        String querySidList;
        try {
            DataSourceSQLite sds = new DataSourceSQLite("oralabDdorf.db");
            conn = sds.getSQLiteDataSource().getConnection();
            querySidList = "select sid,patch,serveros from oralab where VERSION like '" + version + "%'";
            Statement stmt = conn.createStatement();
            ResultSet rset = stmt.executeQuery(querySidList);
            while (rset.next()) {
                String sidinfo = rset.getString(1) + ":Patch#" + rset.getString(2) + "@" + rset.getString(3);
                treeItemList.add(new TreeItem<String>(sidinfo));
            }
            
        } catch (Exception ex) {
            fireException(ex);
            return null;
        } finally {
            close();
        }
        
        return treeItemList;
    }

Und dann im MainController innerhalb eines Service Task folgender Code:

Java:
Service reloadInventoryService = new Service() {

        @Override
        protected Task createTask() {
            return new Task() {
                @Override
                protected Void call() throws Exception {
                    // Start entering execution code here ...
                    LOGGER.info("Creating SID TreeView.");
                    updateMessage("Creating SID Tree View. Please wait ...");
                    Platform.runLater(() -> {
                        model.setTreeItemList11204(dao.generateTreeItem("11.2"));
                        model.setTreeItemList12102(dao.generateTreeItem("12.1"));
                        model.setTreeItemList12201(dao.generateTreeItem("12.2"));
                        model.setTreeItemList18300(dao.generateTreeItem("18.3"));
                        model.setTreeItemList18500(dao.generateTreeItem("18.5"));
                        createTree();
                    });
                    return null;
                }

                @Override
                protected void succeeded() {
                    super.succeeded();
                    updateProgress(1.0, 1.0);
                    updateMessage("Done!");
                }

                @Override
                protected void cancelled() {
                    super.cancelled();
                    setFadeTransitionLabelErrorStatus(true);
                    updateMessage("Cancelled!");
                }

                @Override
                protected void failed() {
                    super.failed();
                    setFadeTransitionLabelErrorStatus(true);
                    updateMessage("Failed!");
                }
            };
        }
    };

Die Methode createTree():
Java:
public void createTree() {
        TreeItem<String> rootItem = new TreeItem<String>("Root Node");
        // Root Item
        rootItem.setExpanded(true);
        TreeItem<String> item11204 = new TreeItem<String>("11.2.0.4");
        TreeItem<String> item12102 = new TreeItem<String>("12.1.0.2");
        TreeItem<String> item12201 = new TreeItem<String>("12.2.0.1");
        TreeItem<String> item18300 = new TreeItem<String>("18.3.0.0");
        TreeItem<String> item18500 = new TreeItem<String>("18.5.0.0");
        
        model.getTreeItemList12102().forEach(item -> item12102.getChildren().add(item));
        model.getTreeItemList11204().forEach(item -> item11204.getChildren().add(item));
        model.getTreeItemList12201().forEach(item -> item12201.getChildren().add(item));
        model.getTreeItemList18300().forEach(item -> item18300.getChildren().add(item));
        model.getTreeItemList18500().forEach(item -> item18500.getChildren().add(item));

        // Add to Root
        rootItem.getChildren().addAll(item11204,item12102,item12201,item18300,item18500);

        // Set the Root Item
        treeViewSID.setRoot(rootItem);
        // Hide the Root Item
        treeViewSID.setShowRoot(false);
    }

Im Prinzip funktioniert das, hat aber folgende entscheidende Nachteile:
1. Gibt es in der Tabelle neue Versionen, z.B. 19.1, muss diese durch den Code (Model, MainController) durch implementiert werden.
2. Ein erneuter reload bei geänderter Tabelle (Tabelle extern) funktioniert auch nicht.

Ich hoffe Ihr könnt mir auf die Sprünge helfen.

Gruß

Ralf
 

lam_tr

Top Contributor
Hi ralfb1105,

kannst du nicht einfach zuerst ein SQL Statment für die Versionen machen und die passenden TreeItems dazu und im zweiten Durlchlauf für die Kinder der Versionen? Die VersionsTreeItems eventuell in eine Map packen und beim Befüllen der Kinder die Eltern via Map holen.

Grüße
lam
 

ralfb1105

Bekanntes Mitglied
Hallo lam,

Danke für Deine Idee/Deinen Tipp! Ich werde es mal probieren, mir ist noch nicht ganz klar wie das mit der Map der Eltern und dann in Beziehung zu den Kindern setzen funktinieren soll. Aber ich werde erst einmal versuchen eine DAOService Methode erstellen die mir die verfügbaren Versionen zurück gibt.

Gruß

Ralf
 

Robat

Top Contributor
Kleines Beispiel wie man es machen könnte:
Java:
public class Main extends Application {
    @Override
    public void start( Stage primaryStage ) throws Exception {

        List<Entry> data = List.of(
                new Entry("ORCL11", "11.2.0.4", "123456", "Red Hat"),
                new Entry("ORCL21", "12.1.0.2", "567898", "Red Hat"),
                new Entry("ORCL22", "12.1.0.2", "452367", "SUSE"));

        // data würde bei dir aus der DB kommen
        Map<String, List<Entry>> map = data.stream().collect(Collectors.groupingBy(Entry::getVersion));

        TreeItem<Entry> root = new TreeItem<>(new Entry("", "", "", ""));

        map.values().forEach(list -> {
            TreeItem<Entry> parent = new TreeItem<>(new Entry("", list.get(0).getVersion(), "", ""));
            list.stream().map(TreeItem::new).forEach(parent.getChildren()::add);
            root.getChildren().add(parent);
        });

        TreeView<Entry> tree = new TreeView<>(root);
        tree.setShowRoot(false);
        tree.getSelectionModel().selectedItemProperty().addListener(( obs, oldValue, newValue ) -> {
            if ( newValue != null && !newValue.getValue().getSid().isEmpty() ) {
                Entry item = newValue.getValue();
                System.out.println(String.format("%s:Path#%s:SERVEROS#%s", item.getSid(), item.getPatch(), item.getServeros()));
            }
        });
        tree.setCellFactory(param -> new TreeCell<>() {
            @Override
            protected void updateItem( Entry item, boolean empty ) {
                super.updateItem(item, empty);
                if ( !empty ) {
                    String text = item.getSid()
                            .isEmpty() ? item.getVersion() : String.format("%s:Path#%s:SERVEROS#%s", item.getSid(), item
                            .getPatch(), item.getServeros());
                    setText(text);
                } else {
                    setText(null);
                    setGraphic(null);
                }
            }

        });
        primaryStage.setScene(new Scene(tree));
        primaryStage.show();

    }
}
Java:
public class Entry {
    private StringProperty sid;
    private StringProperty version;
    private StringProperty patch;
    private StringProperty serveros;


    public Entry( String sid, String version, String patch, String serveros ) {
        this.sid = new SimpleStringProperty(sid);
        this.version = new SimpleStringProperty(version);
        this.patch = new SimpleStringProperty(patch);
        this.serveros = new SimpleStringProperty(serveros);
    }

    public String getVersion() {
        return version.get();
    }

    public String getSid() {
        return sid.get();
    }

    public String getPatch() {
        return patch.get();
    }

    public String getServeros() {
        return serveros.get();
    }
}
Ergebnis:
11694
 

Anhänge

  • 1555429178323.png
    1555429178323.png
    10,8 KB · Aufrufe: 43

ralfb1105

Bekanntes Mitglied
Hallo Robat,

vielen Dank schon mal :) ich schaue mir das Morgen mal an um zu sehen ob ich so weit verstehe um es bei mir zu implementieren. Sieht auf jeden Fall genauso aus wie ich es mir vorgestellt habe!!
Ich melde mich Morgen mit einem Status.

Gruß

Ralf
 

lam_tr

Top Contributor
Hi Robat,

ich bin nur ein bisschen vertraut mit Lamda Ausdrücken. Dieses Beispiel ist an der Stelle sehr einfach, da das parent nie ändert. Wie würde der Lamda Code aussehen wenn ich rekursiv ein Node-Model mit Parent und Children in TreeItem mappen soll?

Code:
 map.values().forEach(list -> {
            TreeItem<Entry> parent = new TreeItem<>(new Entry("", list.get(0).getVersion(), "", ""));
            list.stream().map(TreeItem::new).forEach(parent.getChildren()::add);
            root.getChildren().add(parent);
        });

Grüße
lam
 

lam_tr

Top Contributor
@Robat den Code kann man sicher noch schöner machen...

Code:
public class Node {

    private String name;

    private Node parent;

    private List<Node> children = new ArrayList<Node>();

    public Node(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Node getParent() {
        return parent;
    }

    public void setParent(Node parent) {
        this.parent = parent;
    }

    public List<Node> getChildren() {
        return children;
    }

    public void setChildren(List<Node> children) {
        this.children = children;
    }

}

Code:
public class Main {

    public void init() {
        Node parent = new Node("Root");
        Node a1Node = new Node("A1");
        Node a11Node = new Node("A1-1");
        Node a111Node = new Node("A1-1-1");
        a1Node.getChildren().add(a11Node);
        a11Node.getChildren().add(a111Node);
        a1Node.getChildren().add(new Node("A1-2"));
        a1Node.getChildren().add(new Node("A1-3"));
        parent.getChildren().add(a1Node);
    }
}

Und dieses Modell soll in TreeView dargestellt werden.
 

Robat

Top Contributor
@lam_tr Jetzt weiß ich was du meinst. So richtig braucht man allerdings keine Lambda-Ausdruck. Zumindest nicht an der Stelle wie im ersten Beispiel:
Java:
public class Main extends Application {
    @Override
    public void start( Stage primaryStage ) throws Exception {

        Node parent = new Node("Root");

        Node a1Node = new Node("A1");
        Node a11Node = new Node("A1-1");
        a11Node.addChildren(new Node("A1-1-1"));
        a1Node.addChildren(a11Node);
        a1Node.addChildren(new Node("A1-2"));
        a1Node.addChildren(new Node("A1-3"));

        parent.addChildren(a1Node);

        Node a2Node = new Node("A2");
        a2Node.addChildren(new Node("A2-1"));
        parent.addChildren(a2Node);

        TreeItem<Node> parentItem = new TreeItem<>();
        addToTreeView(parentItem, parent);

        TreeView<Node> tree = new TreeView<>(parentItem);

        primaryStage.setScene(new Scene(tree));
        primaryStage.show();

    }

    private void addToTreeView( TreeItem<Node> parentItem, Node parent ) {
        parentItem.setValue(parent);
        parent.getChildren().forEach(node -> {
            TreeItem<Node> subParent = new TreeItem<>();
            addToTreeView(subParent, node);
            parentItem.getChildren().add(subParent);
        });

    }


    class Node {
        private String name;
        private List<Node> children;

        public Node( String name ) {
            this.name = name;
            this.children = new ArrayList<>();
        }

        @Override
        public String toString() {
            return name;
        }

        public void addChildren( Node node ) {
            children.add(node);
        }

        public List<Node> getChildren() {
            return children;
        }
    }
}
 

ralfb1105

Bekanntes Mitglied
Hallo Robat,

auch von meiner Seite vielen Dank für das Beispiel, es funktioniert bei mir so wie von Dir dargestellt. Ich habe die Infos aus der DB in mein DAOService als Methode implementiert:

Java:
public List<Entry> generateTreeData() {
        List<Entry> dataEntries = new ArrayList<Entry>();

        String querySidList;
        try {
            DataSourceSQLite sds = new DataSourceSQLite("oralabDdorf.db");
            conn = sds.getSQLiteDataSource().getConnection();
            querySidList = "select sid,version,patch,serveros from oralab";
            Statement stmt = conn.createStatement();
            ResultSet rset = stmt.executeQuery(querySidList);
            while (rset.next()) {
                dataEntries.add(new Entry(rset.getString(1), rset.getString(2), rset.getString(3), rset.getString(4)));
            }

        } catch (Exception ex) {
            fireException(ex);
            return null;
        } finally {
            close();
        }
        return dataEntries;
    }
Im MainController in der initialize() Methode dann der Code zum erstellen der Map:
Java:
List<Entry> data = new ArrayList<Entry>(dao.generateTreeData());
        Map<String, List<Entry>> map = data.stream().collect(Collectors.groupingBy(Entry::getVersion));

Hier hätte ich jetzt noch eine Frage ;)

Frage:
Die Map ist ja von Haus aus unsortiert und ich habe keinen Weg gefunden die Map nach den Keys (Versionen) absteigend zu sortieren?

Gruß

Ralf
 

Robat

Top Contributor
Hi Ralf,
schön, dass es geklappt hat.
Die Map ist ja von Haus aus unsortiert und ich habe keinen Weg gefunden die Map nach den Keys (Versionen) absteigend zu sortieren?
Das gilt für HashMaps. Wenn du eine TreeMap nimmst, kannst du einen Comparator mitgeben, nach welchem die Keys dann sortiert werden.
Java:
List<Entry> data = List.of(
        new Entry("ORCL11", "11.2.0.4", "123456", "Red Hat"),
        new Entry("ORCL21", "12.1.0.2", "567898", "Red Hat"),
        new Entry("ORCL22", "12.1.0.2", "452367", "SUSE"),
        new Entry("ORCL22", "12.1.0.3", "452367", "SUSE"));

Comparator<String> entryVersionComparator = ( entry, other ) -> {

    String[] entryNumbers = entry.split("\\.");
    String[] otherNumbers = other.split("\\.");

    for ( int i = 0; i < Math.max(entryNumbers.length, otherNumbers.length); i++ ) {
        int entryNumber = i < entryNumbers.length ? Integer.parseInt(entryNumbers[ i ]) : 0;
        int otherNumber = i < otherNumbers.length ? Integer.parseInt(otherNumbers[ i ]) : 0;

        if ( entryNumber < otherNumber ) {
            return 1;
        }
        if ( entryNumber > otherNumber ) {
            return -1;
        }
    }

    return 0;
};
Map<String, List<Entry>> map = data.stream().collect(Collectors.groupingBy(Entry::getVersion, () -> new TreeMap<>(entryVersionComparator), Collectors.toList()));
map.forEach(( key, value ) -> System.out.println(key));
Code:
12.1.0.3
12.1.0.2
11.2.0.4

Gruß Robert
 

ralfb1105

Bekanntes Mitglied
Hallo Robert,

und nochmals VIELEN DANK.
Ich muss zugeben das ich das vermutlich ohne Hilfe nicht hinbekommen hätte. Ja, von Comperator habe ich schon gelesen, ob ich die Sortierung hinebkommen hätte .. na ja - großes ?

Die Zeile

Map<String, List<Entry>> map = data.stream().collect(Collectors.groupingBy(Entry::getVersion, () -> new TreeMap<>(entryVersionComparator), Collectors.toList()));

aber definitiv nicht - da fehlt mir noch ein großes Stück - daher vielen Dank für die Unterstützung.
Es hat wunderbar funktioniert:

11697

Gruß

Ralf
 

Robat

Top Contributor
Ja, von Comperator habe ich schon gelesen, ob ich die Sortierung hinebkommen hätte .. na ja - großes ?
Wichtig ist nicht, ob du das ganze ad hoc alleine hinbekommen hättest. Viel wichtiger ist, dass du nachvollziehen kannst was der Code macht und es verinnerlichst.
da fehlt mir noch ein großes Stück - daher vielen Dank für die Unterstützung.
Es hat wunderbar funktioniert:
Hier das gleiche Spielchen. Wissen ist nicht alles auswendig zu können, sondern zu wissen, wo man nachschlagen kann ;)
 

ralfb1105

Bekanntes Mitglied
Hallo Robat,

ich muss doch noch eine Frage zu dem TreeView stellen. Ich habe folgendes Verhalten, kein echtes Problem, eher "unschön" ;) und vielleicht hast Du eine Idee wie ich das lösen kann.

Ich habe den TreeView ja nach Deinem Beispiel implementiert und es funktioniert auch sehr gut. Das einzige Problem was ich sehe, wenn ich auf ein Item clicke wird die Aktion ausgeführt, getriggert durch den Listener. In meinem Fall öffne ich ein neues Fenster um weitere Aktionen zu der gewählten SID auszuführen. Schließe ich nach der Ausführung das Fenster und clicke erneut auf die SID in dem Tree *OHNE* den Baum vorher zu schließen und neu auf zu klappen, wird keine Aktion durchgeführt, ich vermute es liegt daran das sich der Wert nicht geändert hat und somit der Listener keine Veränderung von oldValue zu newValue feststellt.

Hier noch einmal der Code um den es geht:
Java:
// Add a listener to the items and store the clicked node value "sid" to the
        // Model StringProperty
        treeViewSID.getSelectionModel().selectedItemProperty().addListener((obs, oldValue, newValue) -> {
            if (newValue != null && !newValue.getValue().getSid().isEmpty()) {
                Entry item = newValue.getValue();
//                    System.out.println(
//                            String.format("%s:Path#%s:SERVEROS#%s", item.getSid(), item.getPatch(), item.getServeros()));
                model.setTreeItemSidClicked(item.getSid());
                proceedOperationActionBoxController();
            }
        });

Hast Du eine Idee wie ich eine Veränderung herbeiführe ohne den Baum schließen zu müssen?

Gruß

Ralf
 

lam_tr

Top Contributor
Hallo Robat,

ich muss doch noch eine Frage zu dem TreeView stellen. Ich habe folgendes Verhalten, kein echtes Problem, eher "unschön" ;) und vielleicht hast Du eine Idee wie ich das lösen kann.

Ich habe den TreeView ja nach Deinem Beispiel implementiert und es funktioniert auch sehr gut. Das einzige Problem was ich sehe, wenn ich auf ein Item clicke wird die Aktion ausgeführt, getriggert durch den Listener. In meinem Fall öffne ich ein neues Fenster um weitere Aktionen zu der gewählten SID auszuführen. Schließe ich nach der Ausführung das Fenster und clicke erneut auf die SID in dem Tree *OHNE* den Baum vorher zu schließen und neu auf zu klappen, wird keine Aktion durchgeführt, ich vermute es liegt daran das sich der Wert nicht geändert hat und somit der Listener keine Veränderung von oldValue zu newValue feststellt.

Hier noch einmal der Code um den es geht:
Java:
// Add a listener to the items and store the clicked node value "sid" to the
        // Model StringProperty
        treeViewSID.getSelectionModel().selectedItemProperty().addListener((obs, oldValue, newValue) -> {
            if (newValue != null && !newValue.getValue().getSid().isEmpty()) {
                Entry item = newValue.getValue();
//                    System.out.println(
//                            String.format("%s:Path#%s:SERVEROS#%s", item.getSid(), item.getPatch(), item.getServeros()));
                model.setTreeItemSidClicked(item.getSid());
                proceedOperationActionBoxController();
            }
        });

Hast Du eine Idee wie ich eine Veränderung herbeiführe ohne den Baum schließen zu müssen?

Gruß

Ralf

Muss der TreeView eventuell nach dem Schließen des anderen Fensters refreshed werden?
 

ralfb1105

Bekanntes Mitglied
Genau nach so etwas suche ich gerade ... der Baum an sich funktioniert ja einwandfrei, lediglich der Click auf das selbe Item triggered den Listener nicht. Wenn ich den Tree nach dem schließen des Fenster manuell zu klappe, dann wieder auf und auf das gleiche Item wie zuvor clicke geht es wieder ...
 

Robat

Top Contributor
Das ist tatsächlich etwas unschön .. daran hab ich gar nicht gedacht.
Lösungsvorschlag: Anstatt auf die Änderung im selectionModel zu hören, kannst du bei jedem Item einen MOUSE_CLICKED Eventfilter setzen. Der Code müsste dazu wie folgt angepasst werden:
Java:
tree.setCellFactory(param -> {
    TreeCell<Entry> cell = new TreeCell<>() {
        @Override
        protected void updateItem( Entry item, boolean empty ) {
            super.updateItem(item, empty);
            if ( !empty ) {
                String text = item.getSid().isEmpty() ? item.getVersion() : String.format("%s:Path#%s:SERVEROS#%s", item.getSid(), item
                        .getPatch(), item.getServeros());
                setText(text);
            } else {
                setText(null);
                setGraphic(null);
            }
        }

    };
    cell.addEventFilter(MouseEvent.MOUSE_CLICKED, event -> {
        if (!cell.getItem().getSid().isEmpty() ) {
            Entry item = cell.getItem();
            System.out.println(String.format("%s:Path#%s:SERVEROS#%s", item.getSid(), item.getPatch(), item.getServeros()));
        }
    });
    return cell;
});
 

ralfb1105

Bekanntes Mitglied
Hallo Robat,

und noch einmal VIELEN DANK! So funktioniert es auch beim 2. Click ohne den Tree erneut zu schließen/öffnen :)
Ich schaue mir den Code Morgen noch einmal in Ruhe an und werde versuchen es im Detail zu verstehen - prinzipiell ist es mir klar, ggf. frage ich dann noch im Detail. Was ich mir auf jeden Fall noch im Detail, incl. Übungen, anschauen muss sind Lambda Expression .. da fehlt mir noch das Grundwissen o_O

Gruß

Ralf
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
agent47 JavaFX TreeView Struktur dynamisch einlesen AWT, Swing, JavaFX & SWT 1
M JavaFX TreeView - TreeItem - SelectedItem AWT, Swing, JavaFX & SWT 7
W JavaFX JavaFX - TreeView will nicht AWT, Swing, JavaFX & SWT 8
ProggersWorld JavaFX Icons im TreeView werden nicht angezeigt AWT, Swing, JavaFX & SWT 1
L JavaFX TreeView aufstellen läuft irgendwie auf Endlosschleife AWT, Swing, JavaFX & SWT 3
L JavaFX TreeView Edit Mode über F2 AWT, Swing, JavaFX & SWT 13
B JavaFx TreeView mit file system AWT, Swing, JavaFX & SWT 1
D JavaFX TreeView stylen AWT, Swing, JavaFX & SWT 6
L JavaFX TreeView mit File Objects AWT, Swing, JavaFX & SWT 0
P TreeView automatisch an große von Inhalt anpassen AWT, Swing, JavaFX & SWT 3
P X extends TreeView - eigene Methoden AWT, Swing, JavaFX & SWT 5
I JavaFX Im TreeView, TreeItems sortieren AWT, Swing, JavaFX & SWT 3
B TreeView cellFactory AWT, Swing, JavaFX & SWT 4
D javafx.scene.control.TreeView als dropdown Menü AWT, Swing, JavaFX & SWT 6
K JavaFX Mehrere Cell Editors in einem TreeView Item AWT, Swing, JavaFX & SWT 2
I JavaFX TreeView Pfeil nicht mehr Klickbar machen AWT, Swing, JavaFX & SWT 1
B JavaFX Wie Treeview aus xml erzeugen AWT, Swing, JavaFX & SWT 11
B Convert Treeview to XML AWT, Swing, JavaFX & SWT 9
N JavaFX TreeView mit verschiedenen Datentypen AWT, Swing, JavaFX & SWT 8
C SWT Treeview mit Bilder im Label verändert Expanded Icon AWT, Swing, JavaFX & SWT 1
Tom299 JavaFX TreeView Expanded-Icon ändern AWT, Swing, JavaFX & SWT 0
ToBJo JavaFX TreeView zerstört sich selbst AWT, Swing, JavaFX & SWT 1
G JavaFX TreeView stylen AWT, Swing, JavaFX & SWT 2
G JavaFX TreeView AWT, Swing, JavaFX & SWT 3
G Problem mit TreeView AWT, Swing, JavaFX & SWT 2
L TreeViewerColumn - gesamte TreeView-breite nutzen? AWT, Swing, JavaFX & SWT 5
T SWT Treeview größe ändern AWT, Swing, JavaFX & SWT 2
C SWT Error/Warnings in TreeView AWT, Swing, JavaFX & SWT 2
P Eindeutiger Knoten im Treeview AWT, Swing, JavaFX & SWT 3
K SystemIcons v. Dateien & Verz. im TreeView anzeigen AWT, Swing, JavaFX & SWT 2
W JavaFX Farben dynamisch anpassen AWT, Swing, JavaFX & SWT 4
B Größe der Parent-Component dynamisch an children anpassen AWT, Swing, JavaFX & SWT 30
K Buttons dynamisch erstellen (NetBeans) AWT, Swing, JavaFX & SWT 10
ralfb1105 JavaFX Dynamisch TableView Spalten erstellen AWT, Swing, JavaFX & SWT 4
A Swing JPanels dynamisch untereinander einfügen AWT, Swing, JavaFX & SWT 3
Wurstsemmel SWT MenuItem dynamisch hinzufügen AWT, Swing, JavaFX & SWT 2
L JavaFX List oder TableView Größe dynamisch anpassen? AWT, Swing, JavaFX & SWT 4
MaxG. Swing Dynamisch grafische Objekte erzeugen AWT, Swing, JavaFX & SWT 12
Thallius JTable dynamisch Spaltenanzahl verändern AWT, Swing, JavaFX & SWT 2
Thallius JTable dynamisch laden? AWT, Swing, JavaFX & SWT 2
S CombinedDomainXYPlot und dynamisch hinzugefügte subplots: Darstellungsprobleme AWT, Swing, JavaFX & SWT 3
K Liniendicke für Line Chart dynamisch ändern AWT, Swing, JavaFX & SWT 0
N Swing Wie Programm strukturieren? (Dynamisch Komponenten hinzufügen) AWT, Swing, JavaFX & SWT 1
llabusch JavaFX Dynamisch alles vergrößern (wie im Browser) AWT, Swing, JavaFX & SWT 3
D JavaFX Dynamisch erzeugte Buttons sollen Code ausführen. AWT, Swing, JavaFX & SWT 2
D JavaFX Dynamisch erzeugte Checkboxen aus VBox auslesen AWT, Swing, JavaFX & SWT 3
J Swing/AWT | Dynamisch erzeugte Objekte ansprechen AWT, Swing, JavaFX & SWT 1
I JTable dynamisch aus ArrayList befüllen AWT, Swing, JavaFX & SWT 3
T JavaFX Flexible Layouts dynamisch erstellen / Design-Inspirationen AWT, Swing, JavaFX & SWT 8
T Dynamisch mehrere Checkboxen anlegen AWT, Swing, JavaFX & SWT 2
J JavaFX TextArea dynamisch Icon im Background anzeigen AWT, Swing, JavaFX & SWT 2
T JPanel dynamisch erstellen AWT, Swing, JavaFX & SWT 4
G FormLayout dynamisch wachsend AWT, Swing, JavaFX & SWT 0
T JTable dynamisch mit ArrayList AWT, Swing, JavaFX & SWT 2
A Swing Logikaufgabe: Zeilenanzahl einer JTable mit 3d String dynamisch anpassen AWT, Swing, JavaFX & SWT 2
T Swing JScrollPane in JPanel - Breite dynamisch, Höhe fix - wie? AWT, Swing, JavaFX & SWT 2
P TableViewerColumn dynamisch erzeugen AWT, Swing, JavaFX & SWT 3
Kandum obj_JMenu.addMenuListener - variable Anzahl an JMenus / menulistenern & frame.setTitle() dynamisch AWT, Swing, JavaFX & SWT 7
A HELP: JFieldText dynamisch setzen -> langsam AWT, Swing, JavaFX & SWT 19
C Swing CardLayout dynamisch erweitern AWT, Swing, JavaFX & SWT 11
B Link eines Icons dynamisch gestalten AWT, Swing, JavaFX & SWT 2
P ScrollPane nach zeichnen dynamisch resize AWT, Swing, JavaFX & SWT 7
B JToolBar dynamisch auf mehrere Zeilen erweitern AWT, Swing, JavaFX & SWT 2
I Jlist dynamisch aus Datenbank füllen AWT, Swing, JavaFX & SWT 14
P Gifs dynamisch auf GUI anzeigen AWT, Swing, JavaFX & SWT 4
E Breite eines JButton dynamisch ändern AWT, Swing, JavaFX & SWT 3
P Swing Dynamisch zeichnen mit Shapes wie Rectangle2D.Float ? AWT, Swing, JavaFX & SWT 6
C SWT - widget dynamisch erzeugen und anzeigen AWT, Swing, JavaFX & SWT 10
C Tooltip dynamisch setzen AWT, Swing, JavaFX & SWT 7
T Elemente zu JList dynamisch hinzufügen AWT, Swing, JavaFX & SWT 4
X jTextFields dynamisch initialisieren AWT, Swing, JavaFX & SWT 2
A Swing Dynamisch Objekte erzeugen AWT, Swing, JavaFX & SWT 3
L Label dynamisch awt AWT, Swing, JavaFX & SWT 2
H Swing Symbol in Taskleiste dynamisch aus- bzw. einblenden AWT, Swing, JavaFX & SWT 14
B JTabbedPane mit Enumeration dynamisch füllen AWT, Swing, JavaFX & SWT 5
L Dynamisch Objekte in Canvas zeichnen AWT, Swing, JavaFX & SWT 5
D Panels Dynamisch zur Laufzeit austauschen AWT, Swing, JavaFX & SWT 2
J Java 2D - dynamisch zeichnen AWT, Swing, JavaFX & SWT 4
A AWT HSB-Farben dynamisch berechnen AWT, Swing, JavaFX & SWT 5
P Dynamisch Sortieren AWT, Swing, JavaFX & SWT 2
B Swing Dynamisch Elemente in JScrollPane hinzufügen AWT, Swing, JavaFX & SWT 6
Airwolf89 Swing Dynamisch auf Objekte in einer GUI zugreifen AWT, Swing, JavaFX & SWT 10
Airwolf89 Swing Tabs dynamisch ausblenden AWT, Swing, JavaFX & SWT 3
H Swing Register (jTabbedPane) dynamisch hinzufügen? AWT, Swing, JavaFX & SWT 7
Airwolf89 Swing Anzahl der Tabellenspalten dynamisch setzen AWT, Swing, JavaFX & SWT 2
S SWT WizardPage - Button anzeigen und Text-Widgets dynamisch aktualisieren AWT, Swing, JavaFX & SWT 12
R JLabel und JSlider dynamisch erzeugen? AWT, Swing, JavaFX & SWT 3
W Swing dynamisch Buttons in JEditorPane erstellen AWT, Swing, JavaFX & SWT 2
Pithecanthropus Swing JPanels dynamisch austauschen AWT, Swing, JavaFX & SWT 8
S Applet mit Graphics dynamisch vergrößern AWT, Swing, JavaFX & SWT 3
Spot84 jtable mit checkboxnode dynamisch per arraylist füllen AWT, Swing, JavaFX & SWT 8
bugmenot Dynamisch erzeugte jLabels werden nicht angezeigt. AWT, Swing, JavaFX & SWT 5
ABstraCT JCombobox dynamisch füllen (erstes Element Problem) AWT, Swing, JavaFX & SWT 4
J JLabels usw. dynamisch anlegen AWT, Swing, JavaFX & SWT 8
A JList dynamisch vergrößern AWT, Swing, JavaFX & SWT 4
G Felder dynamisch erzeugen! AWT, Swing, JavaFX & SWT 3
I Textfields dynamisch erzeugen AWT, Swing, JavaFX & SWT 4
G Dynamisch Komponenten in einem JPanel bzw JFram austauschen AWT, Swing, JavaFX & SWT 7
B JTree dynamisch aufbauen AWT, Swing, JavaFX & SWT 3
L JPanel dynamisch zuweisen AWT, Swing, JavaFX & SWT 5

Ähnliche Java Themen

Neue Themen


Oben