Unsicherheiten in Bezug auf die Implementierung von Aktionen und die Verwendung eines einzelnen Modells mit mehreren Ansichten

Ich bin ein absoluter Neuling in Sachen GUI-Programmierung und vielleicht hat mein Problem eine recht einfache Lösung. Ich versuche, eine Java Swing-GUI zu implementieren, die als Editor für eine baumartige Datenstruktur dient. Die GUI ist in drei Teile gegliedert:

Ein Baum-Viewer im linken Viertel des Fensters zeigt die baumstrukturierten Daten an.

Der große rechte obere Bereich zeigt Editoren an, die Textfelder, Tabellen und dergleichen enthalten. Jede Art von Objekt in der Baumstruktur hat einen eigenen Editor, der angezeigt wird, wenn es im Tree Viewer ausgewählt wird.

Der untere rechte Bereich zeigt einen Konsolen-Viewer. Es wird verwendet, um Meldungen zu bestimmten Aktionen anzuzeigen.

Ich bemühe mich sehr, eine strikte Trennung des Modells von seiner Visualisierung in den Tree Viewern / Editoren in meinem Programm zu befolgen. Daher habe ich eine Instanz einer Unterklasse von DefaultTreeModel (MyTreeModel) erstellt, in der Verweise auf die Geschäftsdaten gespeichert sind, sowie eine Instanz einer Unterklasse von JTree, die die visuelle Darstellung der Baumstruktur bereitstellt.

Ich versuche, Funktionen zu implementieren, mit denen die Daten mithilfe von Aktionsklassen geändert werden. Jede Aktion (wie CreateNode, RenameNode, DeleteNode) wird in einer eigenen Aktionsklasse (Unterklasse von AbstractAction) implementiert. Die Aktionen werden im Kontextmenü des Tree Viewers und im Menü "Bearbeiten" der Anwendungen verwendet. Aber ich möchte auch einige davon in den Editor-Teilen der GUI wiederverwenden, z. die Aktion RenameNode. Und hier stecke ich momentan fest.

In der Strukturansicht wird für jeden Knoten in der Struktur ein Symbol zusammen mit dem Namen angezeigt. Und der jeweilige Editor enthält unter anderem auch ein JTextField, das den Namen des zugehörigen Knotens anzeigt.

Ich weiß, dass ich mit der setAction-Methode Aktionsobjekte an JMenu, JPopupMenu und sogar an JTextField-Objekte anhängen kann. Das habe ich getan und jetzt habe ich einen "Rename" -Menüeintrag im "Edit" -Menü des Programms, im Popup-Menü, das dem JTree zugeordnet ist, der den Tree Viewer darstellt, und dem JTextField, das den Knotennamen anzeigt, ist auch diese Aktion zugeordnet.

Um das Attribut "Name" eines Baumknotens zu ändern, habe ich die Klasse RenameNode als Unterklasse von AbstractAction erstellt. Wie bereits erwähnt, wird der Name an jedem Knoten im Tree Viewer angezeigt und die Aktion macht diesen Text einfach editierbar. Der Code dafür sieht wie folgt aus (in der Klasse RenameNode):

public void actionPerformed(ActionEvent ev) {
    // "mouseOverPath" is the Treepath were the mouse was placed on
    // when the popup menu was opened
    if (tree.existsMouseOverPath()) {
        tree.startEditingAtPath(tree.mouseOverPath);
    } else if (tree.getSelectionCount() != 0) {
        tree.startEditingAtPath(tree.getSelectionPath());
    }
}

Diese if-Anweisungen sind erforderlich, damit die Aktion ordnungsgemäß funktioniert:

- das Popup-Menü (first if-Anweisung; hier wird das Objekt, das sich beim Öffnen des Popup-Menüs unter der Maus befand, editierbar gemacht)

- das Menü der Anwendung (zweite if-Anweisung; hier wird der aktuell ausgewählte Baumknoten - falls vorhanden - bearbeitbar gemacht).

Im Prinzip funktioniert dies einwandfrei, aber das Umbenennen des Knotens erfolgt nicht über den Code in der actionPerformed (ActionEvent ev) -Methode der RenameAction-Klasse. Die tatsächliche Änderung des Knotennamens wird in der MyTreeModel-Klasse der Struktur in der Methode valueForPathChanged () ausgeführt, die wie folgt überschrieben wird:

public class MyTreeModel extends DefaultTreeModel {


[...]

    @Override
    public void valueForPathChanged(TreePath path, Object newValue) {
    final MyTreeNode aNode = (MyTreeNode)path.getLastPathComponent();
    if (newValue instanceof String) {
        ((MyNode) aNode.getUserObject()).setName((String) newValue);
    } else {
        aNode.setUserObject(newValue);
    }
        nodeChanged(aNode);
    }

[...]

}

Ich habe absolut keine Ahnung, wie das Konzept der Handlungen hier richtig angewendet werden könnte. Noch schlimmer ist die Situation beim Umbenennen, wenn der Text im JTextField-Objekt geändert wird. Im Moment weiß ich nicht, wie ich das sauber umsetzen soll. Das JTextField sollte einem einzelnen Knoten aus der Baummodellstruktur als Modell zugeordnet werden, und die angehängte Aktion sollte dieses Modell ändern. Wenn dieses Modell geändert wird, muss der Tree Viewer benachrichtigt werden, um den Namen des jeweiligen Knotens im Tree Viewer zu aktualisieren.

Ich gehe davon aus, dass die MyNode-Klasse (die bereits eine Unterklasse von DefaultMutableTreeNode ist) das Interface Document implementieren müsste und die RenameAction-Klasse es ändern müsste und dann ein Ereignis ausgegeben werden müsste, um den Tree Viewer zu benachrichtigen, der das anzeigt geänderter Knoten.

Fazit: Ich muss zugeben, dass ich die ordnungsgemäße Implementierung einer Aktion, die an mehreren Stellen in einer GUI verwendet werden soll, noch nicht vollständig verstanden habe und auch nicht vollständig verstanden habe, wie ein Modell implementiert wird, das von mehreren GUI-Objekten verwendet werden kann (in meinem Fall ein JTree und ein JTextField). Möglicherweise ist das alles ganz einfach ...

Vielen Dank im Voraus für jede Hilfe!

Die Antworten waren sehr hilfreich, um zu erklären, wie Aktionen zusammen mit JTrees verwendet werden können. Aber es gibt noch einen Punkt, über den ich sprechen möchte. In meiner GUI habe ich eine Baumdarstellung meiner Geschäftsdaten kombiniert mit Editoren für die Daten (der Baum befindet sich im linken Viertel des Fensters und daneben ein knotentypspezifischer Editor). Alle Knoten haben Namen, die geändert werden können. Die Editoren enthalten ein Textfeld (implementiert mit einem JTextField), in dem der Knotenname angezeigt wird und das auch bearbeitet werden kann. Meine Unsicherheit ist hier wie folgt: Ein JTextField ermöglicht es, ihm ein Aktionsobjekt sowie ein Modell zuzuweisen. Tatsächlich wäre das Modell ein Knotenobjekt, das bereits im JTree angezeigt wird. Ich denke, es sollte eine Möglichkeit geben, dasselbe Modellobjekt, das im JTree verwendet wird, auch als Modell für das JTextField im Editor zu verwenden und dort auch die Action-Klasse wiederzuverwenden. In Bezug auf die Wiederverwendung des Modells denke ich, dass meine Modellklasse MyTreeNode auch die Document-Schnittstelle implementieren muss, richtig? Beim Aufrufen des knotenspezifischen Editors muss der aktuell in JTree ausgewählte Knoten mithilfe der setDocument () -Methode mit dem JTextField-Objekt verknüpft werden. Schließlich müsste meine RenameNodeAction die Änderung des Knotennamens von JTextField durchführen. Mein zentraler Punkt ist also, ein Modell in mehreren Ansichten anzuzeigen und nur eine RenameAction überall dort wiederzuverwenden, wo ein Knoten umbenannt werden soll. Ist das sinnvoll und ist meine Vorstellung, wie dies erreicht werden muss, realisierbar?

Antworten auf die Frage(3)

Ihre Antwort auf die Frage