Registrieren von Änderungen an CheckableNode in OutlineView

Alles zu NetBeans als RCP-Platform

Moderator: wegus

Antworten
padde
Beiträge: 96
Registriert: 16.03.2010, 09:21

Registrieren von Änderungen an CheckableNode in OutlineView

Beitrag von padde » 03.07.2013, 12:31

Hallo,

ich habe in einem Wizard einen OutlineView indem ich Nodes anzeige, welche eine Implementierung des CheckableNode-Interfaces im Lookup haben. Dadurch hat jeder Node eine Checkbox.

Nun würde ich gerne eine Validierung für dieses Wizard-Panel erreichen, so dass immer mindestens ein Node im OutlineView ausgewählt sein muss. Leider scheine ich aber keinen Listener zu finden, der mich über Änderungen an den Checkboxes informiert. Ich habe dazu bereits die Netbeans-Mailingliste befragt, wo mir geraten wurde, mich an einen Listener für das TableModel des Outlines im OutlineView zu hängen. Das führte aber leider auch zu keinem Erfolg.

Nutzt hier jemand einen OutlineView oder ähnliches mit CheckableNodes und kann mir dazu einen Tipp geben?

Gruß,
Patrick

ebaumann
Beiträge: 288
Registriert: 22.01.2009, 08:53
Wohnort: Würzburg
Kontaktdaten:

Re: Registrieren von Änderungen an CheckableNode in OutlineV

Beitrag von ebaumann » 04.07.2013, 07:29

Die Factory, die die Nodes erzeugt, kann einen PropertyChangeListener beim Erzeugen der Nodes anmelden oder du holst dir die Nodes über den ExplorerManager und registrierst dort den/die PropertyChangeListener. In setSelected() benachrichtigt dann das Node die Listener; setSelected() wird aufgerufen, falls das Node an/abgehakt wird:

Code: Alles auswählen

@Override
public void setSelected(Boolean selected) {
    Boolean old = this.selected;
    this.selected = selected;
    // ggf. weitere Aktionen
    firePropertyChange("selected", old, selected);
}

padde
Beiträge: 96
Registriert: 16.03.2010, 09:21

Re: Registrieren von Änderungen an CheckableNode in OutlineV

Beitrag von padde » 09.07.2013, 11:50

Danke, das klingt gut. Leider habe ich Probleme, den PropertyChangeSupport richtig zu implementieren.

Mein Node erweitert AbstractNode. Im Konstruktor übergebe ich dem super()-Aufruf Children.LEAF und einen Lookup der mein DataObject und eine Instanz von CheckNode enthält. CheckNode ist einfach eine Implementierung vom CheckableNode-Interface. Nun hat diese CheckNode natürlich keinen PropertyChangeSupport wie die AbstractNode, in dessen Lookup sie liegt. Dementsprechend kann ich natürlich auch nicht in setSelected() auf die Methode firePropertyChange() zugreifen, um das Event zu senden.

Habe ich da irgendwas übersehen? Ist meine Herangehensweise total falsch? Ich würde nun evtl. versuchen, dass mein eigentliches Node neben dem Erweitern von AbstractNode auch noch CheckableNode implementiert und CheckNode komplett wegfällt. Das würde aber heissen, dass ich dem super()-Aufruf erstmal keinen Lookup übergeben kann (this kann erst nach dem Aufruf von super() referenziert werden) und diesen nachträglich (durch das Überschreiben von getLookup?) setzen muss. Das sieht für mich auf den ersten Blick unsauberer aus als es sein müsste.

/e: Habe nun versucht meinen Lösungsansatz erstmal umzusetzen, das scheint aber nicht zu gehen. getLookup() ist final und lässt sich nicht überschreiben. Bis auf den Konstruktoraufruf habe ich keine Möglichkeit gefunden, den Lookup zu setzen und meine Nodes so durch eine Instanz von CheckableNode im Lookup mit einer Checkbox auszustatten.

Vielen Dank schonmal!

Patrick

ebaumann
Beiträge: 288
Registriert: 22.01.2009, 08:53
Wohnort: Würzburg
Kontaktdaten:

Re: Registrieren von Änderungen an CheckableNode in OutlineV

Beitrag von ebaumann » 09.07.2013, 13:56

padde hat geschrieben:Nun hat diese CheckNode natürlich keinen PropertyChangeSupport wie die AbstractNode, in dessen Lookup sie liegt. Dementsprechend kann ich natürlich auch nicht in setSelected() auf die Methode firePropertyChange() zugreifen, um das Event zu senden.
Weshalb auch immer ein Node im Lookup eines anderen Node sein muss: Dieses kann wie jede Java-Klasse Listener an- und abmelden lassen und benachrichtigen. Ob du jetzt ein PropertyChangeSupport-Objekt darin als Field deklarierst und die An-/Abmelde-/Benachrichtigungs-Aufgaben an dieses delegierst oder auf andere Weise das Beobachter-Pattern implementierst, ist dir freigestellt.
padde hat geschrieben:Ich würde nun evtl. versuchen, dass mein eigentliches Node neben dem Erweitern von AbstractNode auch noch CheckableNode implementiert und CheckNode komplett wegfällt. Das würde aber heissen, dass ich dem super()-Aufruf erstmal keinen Lookup übergeben kann (this kann erst nach dem Aufruf von super() referenziert werden) und diesen nachträglich (durch das Überschreiben von getLookup?) setzen muss. Das sieht für mich auf den ersten Blick unsauberer aus als es sein müsste.
Das Ableiten von AbstractNode oder BeanNode erleichert die Arbeit. Im Konstruktor des abgeleiteten Node kann ein Lookup-Objekt an die Basisklasse überreicht werden, in dessen Content du alles einfügen kannst. Für das Feststellen eines Ceck-Events ist das Lookup nicht notwendig, das erfahren die PropertyChangeListener oder sonstigen Beobachter.

Code: Alles auswählen

public final class NodeImpl extends AbstractNode implements CheckableNode {

        private final InstanceContent ic;

        public NodeImpl() {
            this(new InstanceContent());
        }

        private NodeImpl(InstanceContent ic) {
            super(Children.LEAF, new AbstractLookup(ic));
            this.ic = ic;
            ic.add(wasAuchImmer1);
            ic.add(wasAuchImmer2); 
        }

       ...
}

padde
Beiträge: 96
Registriert: 16.03.2010, 09:21

Re: Registrieren von Änderungen an CheckableNode in OutlineV

Beitrag von padde » 09.07.2013, 18:54

ebaumann hat geschrieben: Weshalb auch immer ein Node im Lookup eines anderen Node sein muss: Dieses kann wie jede Java-Klasse Listener an- und abmelden lassen und benachrichtigen. Ob du jetzt ein PropertyChangeSupport-Objekt darin als Field deklarierst und die An-/Abmelde-/Benachrichtigungs-Aufgaben an dieses delegierst oder auf andere Weise das Beobachter-Pattern implementierst, ist dir freigestellt.
Es liegt kein Node im Lookup eines anderes Nodes. Der Name ist leider etwas irreführend. Im Lookup meines abgeleiteten AbstractNodes liegt eine Implementierung des CheckableNode-Interfaces, die Klasse heisst bei mir CheckNode. Laut Netbeans-Javadoc muss eine Implementierung dieses Interfaces im Lookup eines Nodes liegen, damit die Checkbox vor dem Node im OutlineView erscheint. Das funktioniert auch so.
ebaumann hat geschrieben:Das Ableiten von AbstractNode oder BeanNode erleichert die Arbeit. Im Konstruktor des abgeleiteten Node kann ein Lookup-Objekt an die Basisklasse überreicht werden, in dessen Content du alles einfügen kannst. Für das Feststellen eines Ceck-Events ist das Lookup nicht notwendig, das erfahren die PropertyChangeListener oder sonstigen Beobachter.

Code: Alles auswählen

public final class NodeImpl extends AbstractNode implements CheckableNode {

        private final InstanceContent ic;

        public NodeImpl() {
            this(new InstanceContent());
        }

        private NodeImpl(InstanceContent ic) {
            super(Children.LEAF, new AbstractLookup(ic));
            this.ic = ic;
            ic.add(wasAuchImmer1);
            ic.add(wasAuchImmer2); 
        }

       ...
}
Danke, dass mit dem InstanceContent werde ich morgen mal probieren und das CheckableNode direkt im meiner Ableitung von AbstractNode implementieren.

someDude
Beiträge: 8
Registriert: 12.09.2013, 19:27

Re: Registrieren von Änderungen an CheckableNode in OutlineV

Beitrag von someDude » 15.09.2013, 21:07

hast du's mittlerweile hinbekommen und wie (konkret)?

hier solltest du eine Lösung finden:
https://kenai.com/projects/nbvideostore

Kontext: siehe auch
https://blogs.oracle.com/geertjan/entry ... utlineview
https://blogs.oracle.com/geertjan/entry ... r_view_via

EDIT:
und hier noch schöner gelöst
http://forums.netbeans.org/post-151234.html

Antworten