# Trennung des Event-Handling von der GUI



## darkie23 (4. Jan 2006)

Hallo,

ich komme gleich mal zur Sache. Ich habe mich entschlossen die Logik für das Event-Handling komplett von der GUI zu trennen. Dafür habe ich zunächst 3 Klassen erstellt. Die Klasse für die eigentliche Swing GUI, eine Klasse für das Event-Handling und eine Klasse, welche die anderen beiden instanziiert.

Nun möchte ich, dass ich beim Drücken des Buttons den Text des Labels der GUI verändern kann (über die public Funktion setText). Wie komme ich da bei actionPerformed in der Event-Klasse ran? Mit getSource() komme ich ja nur an nur an den Button selbst, der das Event ausgelöst hat oder!?

Die GUI und Event Klasse werden also folgendermaßen instanziiert:

```
public class Start {

	public static void main(String[] args) {
		
		Event cmd = new Event();
		GUI gui = new GUI(cmd);
		
	}
	
}
```

In meiner GUI ist nur ein Button mit addActionListener und ein Label enthalten:

```
import java.awt.BorderLayout;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JLabel;

public class GUI extends JFrame {

	private JPanel jContentPane = null;
	private JButton jButton = null;
	private JLabel jLabel = null;
	private Event cmd = null;
	
	public GUI(Event cmd) {
		super();
		System.out.println(cmd);
		initialize();
	}

	private void initialize() {
		this.setSize(300, 200);
		this.setContentPane(getJContentPane());
		this.setTitle("JFrame");
	}

	private JPanel getJContentPane() {
		if (jContentPane == null) {
			jLabel = new JLabel();
			jLabel.setText("JLabel");
			jContentPane = new JPanel();
			jContentPane.setLayout(new BorderLayout());
			jContentPane.add(getJButton(), java.awt.BorderLayout.SOUTH);
			jContentPane.add(jLabel, java.awt.BorderLayout.NORTH);
		}
		return jContentPane;
	}

	private JButton getJButton() {
		if (jButton == null) {
			jButton = new JButton();
			jButton.setText("OK");
			jButton.addActionListener(cmd);
		}
		return jButton;
	}

         public void setText(String text) {

                  jLabel.setText(text);

         }

}
```

Die Event-Handling Klasse sieht ungefähr so aus, um den Button zu bedienen:


```
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Event 
implements ActionListener {

	public void actionPerformed (ActionEvent e) {
		// Hier möchte ich auf den Text des Labels zugreifen können und zwar indem ich indirekt die 
                  // public Funktion setText aufrufen möchte. 
	}

}
```

Vielen Dank im Voraus
Gruß
Darkie


----------



## Roar (4. Jan 2006)

die Event klasse müsste entweder
1) das JLabel/die GUI instanz kennen (böse)
oder 2) eine schnittstelle bereitstellen, die es der gui erlaubt sich bei dem eventhandler anzumelden und dann vom eventhandler benachrichtigt wird durch sowas wie labelTextChanged() und der text im label neu gesetzt wird. (besser)
oder 3) du kloppst den blöden listener einfach in die gui klasse. ist zwar unsauber, aber für so eine aufgabe wohl das einzig sinnvolle ^^

ansonten schau mal in der faq unter design patterns/observer


----------



## Erddrache (4. Jan 2006)

Ich machs, ums ma in nem Beispiel zu bringen, immer so, wenn ich die listener Auslagern will:

```
{
						exitMenuItem = new JMenuItem();
						jMenu3.add(exitMenuItem);
						exitMenuItem.setText("Exit");
						exitMenuItem.setActionCommand("Exit");
						exitMenuItem.addActionListener(new eActionMain());
					}
```
 dann ne neue Klasse mit Namen eActionMain, die nen Listener implementiert:


```
public class eActionMain implements ActionListener {

	public void actionPerformed( ActionEvent e) {
		String test = e.getActionCommand();
		
		}
		if (test.equals("Exit")) {
		System.exit(0);
		}
```

Klappt eigentlich ganz gut...


----------



## darkie23 (5. Jan 2006)

@Roar: Ich schau's mir gleich mal an...

@Erddrache: Die Auslagerung des Listeners stellt nicht das eigentliche Problem dar. Das Problem ist, wie der der Listener vollen Zugriff auf die GUI bekommt. Mit getsource() bekommt man leider nur Zugriff auf die direkte Quelle des Events (z.B. den Button), aber nicht vollen Zugriff auf dessen Eltern bzw. die komplette GUI.


----------



## darkie23 (5. Jan 2006)

Ich hab grade mal bei Sun nachgeschaut (http://java.sun.com/j2se/1.3/docs/guide/awt/designspec/events.html). Die haben da einen interessanten Beispielcode.

Kurz zusammengefasst: Die Logik erstellt die GUI und übergibt sich selbst noch als Parameter. Die GUI erstellt dann den Listener und übergibt ebenfalls die Ihr bekannte Logik. Der Listener selbst greift dann bei einem Event direkt auf die öffentliche Funktionen der Logik zu.

Klingt ja gut... mich würde aber mal interessieren ob das Übergeben der Logik von oben bis unten keine Nachteile birgt und wirklich der beste Weg ist...hmmm!?


----------

