# SWT Tab Listener



## Gast2 (1. Okt 2008)

Hallo,
was kann ich für einen Listener verwenden bzw. was gibt es für einen Listener wenn ich ein TabItem anklicke???


```
final TabItem photoTabItem = new TabItem(parent, SWT.NONE);
    photoTabItem.setControl(Composite c);
```


----------



## Gast2 (1. Okt 2008)

hab die möglichkeit gefunden


```
TabFolder.addSelectionListener(new SelectionAdapter()
    {
      public void widgetSelected(SelectionEvent e)
      {
        System.out.println("Change selection");

      }

    });
```

hab erst immer beim tabitem gesucht


----------



## Olel (19. Nov 2008)

Ich möchte diese Frage noch mal wieder nach oben holen, denn ich bin auch auf der Suche nach einer geschickten Möglichkeit, um die Selektion eines TabItem anfragen zu können.

Was ich möchte:
Wenn ein TabItem selektiert wird, sollen die Inhalt die innerhalb dieses TabItems dargestellt werden, aktualisiert werden. Dies geschieht in Abhängigkeit einer Selektion in einem TableViewer an anderer Stelle.


Was ich mir wünsche:
Damit jedes Element nur über das bescheid weiß, was es wissen muss (nämlich über die Elemente im TabItem), fänd ich es halt schön, wenn jedes TabItem einen SelectionListener bekommt und darin dann die Aktualisierung vornimmt.

Die Wahrheit:
Leider kann ich einen SelectionListener nur auf den TabFolder setzen. Dann müsste der aber über die jeweiligen Inhalte der TabItems bescheid wissen und zudem auf deren Index basierend die jeweils richtigen Dinge tun: also bspw. wenn das TabItem mit dem Index 2 selektiert wurde, muss halt dessen Ansicht aktualisiert werden - unschön finde ich.

Gibt es eine sinnvolle andere Lösung, die ich bislang noch nicht bedacht habe?

Ole

PS: Eine theoretische Möglichkeit wäre es vielleicht auch TabItem zu überschreiben, aber im API-Doc steht halt klipp und klar drin "is NOT intended to be subclassed".


----------



## Gast2 (19. Nov 2008)

du musst nicht unbedingt über den index gehen um das selektierte item rauszufinden du kannst auch über das object gehen


```
TabFolder.addSelectionListener(new SelectionAdapter()
    {
      public void widgetSelected(SelectionEvent e)
      {
        if (TabFolder.getItem(TabFolder.getSelectionIndex()).equals(TabItem1))
        {
           TabItem1.akualisiere();
        }
          if (TabFolder.getItem(TabFolder.getSelectionIndex()).equals(TabItem2))
        {
           TabItem2.akualisiere();
        }
       ......
      }
    });

  }
```


----------



## Olel (20. Nov 2008)

SirWayne hat gesagt.:
			
		

> du musst nicht unbedingt über den index gehen um das selektierte item rauszufinden du kannst auch über das object gehen



Ja stimmt, dass ist mir in der Zwischenzeit auch schon aufgefallen. Das ändert aber nichts an dem eigentlichen Problem. In deinem Beispielcode rufst Du ja TabItem.aktualisieren() auf. Das soll zwar sicher nur Pseudocode sein, aber genau hier liegt das Problem. Ich kann ja keine eigenen Methoden an dem TabItem aufrufen, solange ich das TabItem nicht überschreibe. Das ist aber wie gesagt laut API gerade nicht erwünscht.

Ich habe es jetzt wie folgt gelöst:


```
myTabFolder.addSelectionListener(new SelectionAdapter() {
    @Override
    public void widgetSelected(SelectionEvent event) {
        Event e = new Event();
        e.data = MeinDatenObjekt;
        ((CTabItem) event.item).notifyListeners(SWT.Selection, e);
    }
});


// Dies hier dann für jedes TabItem
myTabItem1.addListener(SWT.Selection, new Listener() {
    @Override
    public void handleEvent(Event event) {
        if (event.data != null)
        {
            // do Something with the event data
        }
    }
});
```


Tut auf jeden Fall was ich möchte. Ob es die eleganteste Lösung ist, weiß ich aber nicht. Wenn jemand noch eine bessere Idee hat immer her damit!


----------



## Gast2 (20. Nov 2008)

du kannst dem TabItem ein Controll(Composite) setzen und das kannst du selber schreiben und auf das kannst du auch überprüfen


```
TabItem.setControl(TabItemControl);
    TabFolder.addSelectionListener(new SelectionAdapter()
    {
      public void widgetSelected(SelectionEvent e)
      {
        if (TabFolder.getItem(TabFolder.getSelectionIndex()).equals(TabItem))
        {
          TabItemControl.akualisiere...
        }
       }
     }
```


----------



## Olel (20. Nov 2008)

Hmm, aber auch ein Control sollte nicht subclassed werden; hilft hier also auch nicht weiter.


----------



## Gast2 (20. Nov 2008)

was????? ein Controll ist z.B. ein Composite da kannst du doch deine ganze GUI drauf packen... und diese dann nach belieben aktualisieren...


----------



## Olel (20. Nov 2008)

Ja, ein Composite ist ein Control und natürlich kann ich da weitere GUI-Elemente (andere Controls) drauf packen, aber darum geht es doch nicht.

Es geht darum, dass ich doch eine selbstgeschriebene Methode aktualisieren() bräuchte, um darin gewisse Dinge tun zu können. Und diese Methode hätte ich nur, wenn ich eine eigene Klasse (z.B. MyControl) schreibe, die von Control erbt. Und das ist laut API eben nicht erlaubt / gewollt.


----------



## Gast2 (20. Nov 2008)

nein du schreibst ein eigenes MyComposite dass von Composite erbt und die enthält deine aktualisiere methode...
und dann tabItem.setControl(MyComposite)...


----------



## Olel (20. Nov 2008)

Ok, zugegebenermaßen dürfte ich von Composite erben, wenn ich ein "custom Control" (Zitat aus der API-Doc) schreiben würde. Das tue ich aber nicht und bloß um eine eigene aktualisieren() Methode zu schreiben ist das Überschreiben von Composite nicht der richtige Ansatz, denke ich.
Gibt auch irgendwo einen Artikel von Fowler oder so, der davor warnt alles mögliche zu überschreiben und fordert, dass mehr Aggregation genutzt wird.

Nochmal auf die Idee mit den SelectionListenern: was ist davon zu halten? Gibt es da evtl. noch bessere Lösungen? Andere Meinungen sind herzlich willkommen.


----------



## Gast2 (20. Nov 2008)

> Gibt auch irgendwo einen Artikel von Fowler oder so, der davor warnt alles mögliche zu überschreiben und fordert, dass mehr Aggregation genutzt wird.



Überschreibst du alles mögliche???
ich weiß ja nicht was deine aktualisiere methode macht... aber wenn sie besondere sachen machen ist sie ein custom control  ???:L


----------



## Olel (20. Nov 2008)

Naja, was heißt schon "besondere Sachen". Sie würde halt den Inhalt des Controls ändern, z.B. ein neues Bild laden. Das ist aber aus meiner Sicht kein custom control. Darunter versehe ich ein neues allgemein gültiges Control im Sinne eines Framework, das als Basis für andere dient. Also z.B. ist ein CLabel halt ein "custom Label".

Wie auch immer: fällt noch jemand anderem eine Lösung ein, die ohne Vererbung auskommt?


----------

