SWT: Widget auf welchem das Kontextmenü aufgerufen wurde

java123

Mitglied
Hallo,

ich entwickle eben mein erstes Eclipse Plugin und arbeite auch das erste Mal mit SWT.
Ausgangslage:
Ich habe einen org.eclipse.swt.widgets.Tree der maximal drei Ebenen des Filesystems darstellt und Mehrfachselektion erlaubt. Die hinzugefügten TreeItems repräsentieren also ein Verzeichnis oder eine Datei, wobei ich die repräsentierte Fileinstanz mittels #setData() in den TreeItems speichere.
Nun muss es möglich sein die selektierten Items zu öffnen: Wird das Kontextmenü auf einem Verzeichnis aufgerufen, so soll das Verzeichnis im Dateiexplorer geöffnet werden; sind eine oder mehrere Datei-TreeItems selektiert und das Kontextmenü wird irgendwo – nur nicht auf einem Verzeichnis-TreeItem – aufgerufen, so sollen diese mit dem Standardeditor geöffnet werden. Zweiteres habe ich implementiert und diese Funktion wird momentan immer aufgerufen.

Die repräsentierte Ablage kann entweder so aussehen:
Code:
— Verzeichnis
    — Verzeichnis
        — Datei
oder so:
Code:
— Verzeichnis
    — Datei
Das sollte allerdings nichts zur Sache tun; nur zum Verständnis.

Problem:
Wie kann ich unterscheiden, auf welchem TreeItem das Kontextmenü «aufgerufen» (kA ob das das korrekte Wort ist, aber ich hoffe ihr wisst was ich meine) wurde um zu unterscheiden, ob das Verzeichnis geöffnet werden soll oder die Dateien?
Da schon mal mehrere tausend TreeItems hinzugefügt werden können und die Funktion nicht oft aufgerufen wird, möchte ich nicht jedem Item ein Menü hinzufügen, sondern wie oben beschrieben dynamisch schauen wo der Benutzer rechtsgeklickt hat oder der Fokus war als er die Kontexttaste gedrückt hat.
Doppelklick auf die Items ist übrigens keine Ausgangslösung, dies ist bereits einer anderes Funktion zugewiesen. Es muss wirklich über das Kontextmenü möglich sein.

Was ich bisher versucht habe:

Natürlich Google gefragt und viele Snippets und Threads gefunden. Diese fügen allerdings zu jedem Item ein Menü hinzu, unterscheiden nicht zwischen den Nodes oder berücksichtigen einfach die selektierten Items. Das will ich allerdings nicht (bzw. die Benutzer nicht, da nicht Verzeichnisse und Dateien miteinander geöffnet werden sollen).
Ausserdem habe ich versucht das aktuell selektierte Widget zu holen sobald die Funktion aufgerufen wird, habe allerdings nur shell.getDisplay().getFocusControc() gefunden, die den Tastaturfokus zurückliefert. Dort erhalte ich allerdings immer den Tree selbst und kein Item, auch wenn ich z. B. mit den Pfeilen etwas fokusiert habe. Das gleiche Widget erhalte ich auch, wenn ich dem Tree einen MenuDetectListener hinzufüge. Irgendwie muss es doch möglich sein, das aktuell fokusierte Widget zu erhalten, welches das TreeItem (also das wirklich fokusierte liefert und nicht den Tree…).
Die Mauszeigerposition auf dem Bildschirm kann ich auch nicht einfach abfragen, da eben auch per Kontextmenü-Taste und Shift + F10 das Menü aufgerufen werden kann und der Mauszeiger an einer völlig anderen Position sein kann.

Mein bisheriger Code schaut so aus:
Java:
Menu treeContextMenu = new Menu(tree);
tree.setMenu(treeContextMenu);
MenuItem open = new MenuItem(treeContextMenu, SWT.NONE);
open.setText("open");

open.addSelectionListener(new SelectionAdapter() {
    @Override
    public void widgetSelected(SelectionEvent aSelectionEvent) {
        // hier muss ich rausfinden worauf das kontextmenu aufgerufen
        // wurde und dann entsprechend das verzeichnis oder die dateien
        // öffnen
    }
});

Als selektiertes Widget wird beim Event natürlich das MenuItem «open» geliefert und nicht das TreeItem. Aus dem Event kann ich also auch nichts herauslesen.

Was viellicht noch wichtig zu verstehen ist: Es geht hier um reines SWT und nicht dynamische Kontextmenüs die irgendwo im plugin.xml definiert werden.
Stelle später vielleicht auf einen JFace TreeViewer um, würde das für meine Situation einen Unterschied machen?


Jetzt ist der Text etwas lang geworden, aber ich wollte allfällig auftretende Unklarheiten vermeiden und Lösungsansätze die ich bereits versucht habe :p. Danke schonmal.
 

Neue Beiträge

Zurück