# ActionEvents von Tochterklasse zu Elternklasse



## powerpaar (15. Nov 2011)

Hallo, 

Ich habe wieder mal ein kleines Problem, genauer gesagt ein größeres. Ich habe eine klare Unterteilung in Model-View-Controll (wem das nichts sagt: auch nicht so unheimlich wichtig, fest steht nur, ich muss im Prinzip genau das machen, was ich jetzt erkläre und darf nicht groß davon abweichen).

Normalerweise ist es ja kein großes Problem, bei einer graphischen Oberfläche ein paar ActionEvents abzufangen, indem man sie an Buttons oder an die Tastatur knüpft, so z.B. :


```
import java.awt.event.*;

public class sowieso implements KeyListener{
   public void keyTyped(KeyEvent e){
      if (e.getKeyCode() == KeyEvent.VK_L) {
          System.out.println("Wow, du hast voll cool die L-Taste gedrückt! Hol dir ein Stück Schoko!");
      }
}
```

Wenn man jetzt noch z.B. andere Objekte zu dieser Klasse hinzufügt, so kann man diese wieder über deren Methoden ansteuern - soweit klar. Es ist also kein Problem, in der "Hierarchie" der Klassen von Oben nach Unten Signale z.B. mit Gettern zu schicken und sie ggf. mit Settern zu verändern. 

Mein Problem ist jetzt aber das Umgekehrte: *Wie stelle ich es an, dass ein erzeugtes Objekt (bei mir das "Modell") ein Event auslöst, welches mein erzeugendes Objekt (bei mir der "Controller") anspricht?*

Das man einen Button z.B. mit 

```
b.addActionListener(new ActionListener{
            public void actionPerformed(ActionEvent e)
            {
                System.out.println("You clicked the button");
            } 
});
```

hinzufügen kann und später dann abfangen kann ist mir vollkommen klar, aber ich habe keinen Button und ich möchte auch von meiner erzeugten Instanz ganz verschiedene Dinge steuern können. Dazu brauche ich vermutlich ein Interface, habe aber keine Ahnung, wie das hier geht.

Bitte helft mir...


----------



## SlaterB (16. Nov 2011)

du könntest ActionListener selber auch verwenden oder was immer sonst als neues Interface,
die gedankliche Durchdringung kann dir niemand abnehmen, da musst du schon einmal durch und das verstehen,
evtl. konkretere Fragen stellen als bisher,

ein Objekt x kann andere Objekte aufnehmen und deren Methoden aufrufen bei Ereignissen, nichts dabei,
das Interface macht es etwas allgemeiner damit nicht exakt die anderen Klassen bekannt sein müssen, 
die schließlich evtl. gar erst dynamisch anonym deklariert werden


----------



## powerpaar (16. Nov 2011)

Hm... Was soll man dazu sagen? Ja, du hast Recht? 

Ich werde einfach mal konkreter: 

Ich habe einen ActionListener in der erzeugenden Klasse Controller erzeugt und dann dem Model hinzugefügt. 


```
ActionListener aLis= new ActionListener(){
         public void actionPerformed(ActionEvent e) {               
            eineMethodeVonController(); // hier steuere ich eine Methode im Controller an
         }
      };
      model1.addActionListener(aLis);
```

In Model gibt es die Methode addActionListener

```
private ActionListener controlerListener;
...
public void addActionListener(ActionListener a){
            controlerListener = a;
// editiert, da Fehler entdeckt
        }
```

Erst mal: Ist das so richtig? (Die Instanz von Model "model1" wurde natürlich vorher in Controller erzeugt).

Zweitens: Wie kann ich das ActionEvent (sofern es so wirklich übergeben wurde) konkret in model1 auslösen?

Edit:

Ich habe inzwischen die Methode actionPerformed() natürlich entdeckt, aber wie löst man sie aus?
Ich brauche ein ActionEvent, welches sich aber aus mir nicht bekannten Gründen nicht erzeugen lässt. 
Bisher bin ich soweit:

(Im Model)

```
ActionEvent evt=new ActionEvent();
controlerListener.actionPerformed(evt);
```

Aber natürlich nimmt er es nicht an, da ActionEvent noch Parameter benötigt. Ich komme der Lösung näher, aber ich scheine noch weit entfernt.


----------



## SlaterB (16. Nov 2011)

es gibt kein richtig und falsch, jedenfalls weniger bei unklaren Zielen/ individuellen Programmen,
lasse doch dein Programm laufen, wenn deine Ziele erreicht werden, war es wohl eine richtige Variante

> controlerListener = a;
> this.addActionListener(controlerListener);
kann man allerdings genau genommen doch als komisch betrachten, die zweite Zeile führt zur selben Methode,
Endlosschleife? die erste Zeile reicht doch für den beabsichtigten Effekt, a abzuspeichern..

der Aufruf ist dann denkbar einfach, wie bei jedem Objekt immer auf die gleiche Weise:
> controlerListener.actionPerformed(null);
wenn du kein Event mit Informationen brauchst kannst du vereinfacht null übergeben, der Aufruf an sich reicht,
oder eben ein schöneres Interface mit kürzeren Methodenennamen und ohne unnötigen Parameter erfinden: action(); oder event();


----------



## powerpaar (16. Nov 2011)

Danke! Das hat mir jetzt wirklich endgültig weitergeholfen!

Jetzt habe ich auch ein weit besseres Verständnis.... denke ich.... 
Werde mich noch etwas belesen :rtfm: bevor ich weitermache, damit ich wirklich durchsteige.


----------

