# ActionListener *verzweifel*



## Tahomar (22. Dez 2006)

Hallo,

ich verzweifle gerade an einem, wie ich dachte simplen Problem. Ich wollte zwei Buttons mit Funktionalität ausstatten, beim Hilfe-Button soll sich bspw. eine Textarea öffnen. Aber ich krieg das einfach mit dem ActionListener nicht auf die Kette. Hab schon Literatur, google, usw. bemüht aber ich habe da scheinbar ne Blockade. Kann mir bitte jemand helfen?

Vielen Dank schon mal!

Hier mein Code, der eigentlich lauffähig ist wenn man die Listener Geschichte und die Methode ganz unten wieder auskommentiert:


```
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.net.*;
import java.io.*;


public class SocketClient
{
static String d,f,g;

	public static void main(String[] args) throws Exception
	{
	
	JFrame anwendungsFenster = new JFrame("Rechenanfrage an Server");
	JTextField ersterOperand = new JTextField("0", 10);
	JTextField operationsSchalter = new JTextField("+", 1);
	JTextField zweiterOperand = new JTextField("0", 10);
	JTextField ergebnis = new JTextField("0", 20);
	JButton hilfe = new JButton("Hilfe");
	JButton eingabe = new JButton("Eingabe beginnen");
	ergebnis.setEditable(false);
	JLabel label = new JLabel("Statusfenster", 	SwingConstants.LEADING);

	JPanel textfeldPanel = new JPanel();
		
		textfeldPanel.setLayout(new GridLayout(3, 1));
		textfeldPanel.add(ersterOperand);
		textfeldPanel.add(zweiterOperand);
		textfeldPanel.add(ergebnis);
	
	anwendungsFenster.getContentPane().setLayout(new GridLayout(1, 2));
anwendungsFenster.getContentPane().add(label);		

anwendungsFenster.getContentPane().add(operationsSchalter);
		anwendungsFenster.getContentPane().add(textfeldPanel);
anwendungsFenster.getContentPane().add(hilfe);
anwendungsFenster.getContentPane().add(eingabe);

// HIER WIRDS PROBLEMATISCH

hilfe.addActionListener(listener);
eingabe.addActionListener(listener);

// ***

	anwendungsFenster.getContentPane().setLayout( new FlowLayout());
		anwendungsFenster.pack();
		anwendungsFenster.show();

		
	try
	{
	String s = JOptionPane.showInputDialog
	( "Bitte ersten Operanden eingeben" );
	double i = Double.parseDouble( s );
	d=(new Double(i)).toString();

	s = JOptionPane.showInputDialog
	( "Bitte den Operator, also + , - , * oder : eingeben" );
	if ( s != null && s.length() > 0 )
  	{
	char c = s.charAt( 0 );
	f=(new Character(c)).toString();
	}
	s = JOptionPane.showInputDialog
	( "Bitte zweiten Operanden eingeben" );
	double o = Double.parseDouble( s );
	g=(new Double(o)).toString();
	}
	catch(Exception ex)
	{
	System.out.println("Eingabefehler");
	System.exit(1);
	}

	ersterOperand.setText(d);
	zweiterOperand.setText(g);
	operationsSchalter.setText(f);
	anwendungsFenster.show();

	// Socket-Verbindung auf den Port 1234 des Servers anfragen
	Socket server= new Socket("localhost", 1234);
	// Datenströme öffnen
	DataInputStream in = new DataInputStream(server.getInputStream());
	DataOutputStream out = new DataOutputStream (server.getOutputStream());
	// Beide Argumente als Intergerzahlen an den Server senden
	double zahl1 = Double.parseDouble(d);	
	double zahl2 = Double.parseDouble(g);
	char op = f.charAt( 0 );
	
	out.writeDouble(zahl1);
	out.writeDouble(zahl2);
	out.write(op);

	// Ergebnis von Server einlesen und ausgeben
	double resultat= in.readDouble();
	String h=(new Double(resultat)).toString();
	ergebnis.setText(h);
	anwendungsFenster.show();
	// Socketverbindungzu Server schliessen
	server.close();
}
// UND HIER KLAPPTS AUCH NICHT

public void actionPerformed (ActionEvent e) {
		if (e.getSource() == hilfe) {
			JTextArea Hilfetext= new JTextArea("bla");
			getContentPane().add(Hilfetext);
		}
		if (e.getSource() == eingabe) {
			
		}
		}
}
```


----------



## Wildcard (22. Dez 2006)

Du hast listener nirgends deklariert, das würde gar nicht kompilieren.
Davon abgesehen... eine GUI in einer einzigen statischen Methode!?  :noe: 
Ich glaube du solltest vorher noch etwas im Java Buch deiner Wahl schmökern und was über OOP lernen.


----------



## WieselAc (22. Dez 2006)

Du schreibst echt ne GUI in der Main ?!?!? 


*vom stuhl fall*


werd jetzt mal durch den quelltext gucken...

edit: mist zu spät, aber schön das es nicht nur mir so geht


----------



## Tahomar (22. Dez 2006)

Danke für die schnelle Antwort.

Ja, ich weiß, ich wollts wohl auch noch etwas "aufsplitten"  ...

Genau beim listener liegt mein Problem, wie deklariere ich den... ActionListener listener?


----------



## Wildcard (22. Dez 2006)

Du brauchst eine Klasse die das Interface implementiert, instanzierst diese Klasse und registrierst sie dann als ActionListener.
Aber mal ganz ehrlich:
Ohne die Grundlagen bist du in der Oberflächenprogrammierung verloren.


----------



## chamaeleon879 (30. Dez 2006)

Vielleicht hilft dir das ja schon weiter:

Listener registrieren:


```
jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });
```

beim klick auf den Button wird dann folgende Methode aufgerufen:


```
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {  
bla bla bla
}
```
[/code]


----------



## Tahomar (30. Dez 2006)

Vielen Dank für die Antwort.

Ich habe jetzt das Programm objektorientiert ausgestaltet und Chamaeleons Tipp für den Hilfe und den Eingabe Beginnen Button integriert:


```
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.net.*;
import java.io.*;


public class SocketClient
{
static String d,f,g;
static double resultat;
JFrame anwendungsFenster;
JTextField Operand1;
JTextField Operator;
JTextField Operand2;
JTextField ergebnis;
JButton hilfe;
JButton eingabe;
JLabel label;
JPanel textfeldPanel;
DataInputStream in;
DataOutputStream out;

public SocketClient()
{
AnfrageAnnehmen();
Kommunikation();
ErgAnz();

}

public void AnfrageAnnehmen()
{
anwendungsFenster = new JFrame("Rechenanfrage an Server");
Operand1 = new JTextField("0", 10);
Operator = new JTextField("+", 1);
Operand2 = new JTextField("0", 10);
ergebnis = new JTextField("0", 20);
hilfe = new JButton("Hilfe");
eingabe = new JButton("Eingabe beginnen");
Operand1.setEditable(false);
Operand2.setEditable(false);
Operator.setEditable(false);
ergebnis.setEditable(false);
label = new JLabel("Statusfenster",SwingConstants.LEADING);
textfeldPanel = new JPanel();
		
		textfeldPanel.setLayout(new GridLayout(3, 1));
		textfeldPanel.add(Operand1);
		textfeldPanel.add(Operand2);
		textfeldPanel.add(ergebnis);

anwendungsFenster.getContentPane().setLayout(new GridLayout(4, 2));
anwendungsFenster.getContentPane().add(hilfe);
anwendungsFenster.getContentPane().add(eingabe);
anwendungsFenster.getContentPane().add(label);		
anwendungsFenster.getContentPane().add(Operator);
anwendungsFenster.getContentPane().add(textfeldPanel);

anwendungsFenster.getContentPane().setLayout( new FlowLayout());
anwendungsFenster.pack();
anwendungsFenster.show();

hilfe.addActionListener(new java.awt.event.ActionListener() {
    public void actionPerformed(java.awt.event.ActionEvent evt) {
        hilfeActionPerformed(evt);
    }
}); 
       
eingabe.addActionListener(new java.awt.event.ActionListener() {
    public void actionPerformed(java.awt.event.ActionEvent evt) {
        eingabeActionPerformed(evt);
    }
});
//AN DIESER STELLE SOLL ER AUF DAS DRÜCKEN EINES BUTTON WARTEN 
}
    
public void EingabeDialog(){
try
	{
	String s = JOptionPane.showInputDialog
	( "Bitte ersten Operanden eingeben" );
	double i = Double.parseDouble( s );
	d=(new Double(i)).toString();

	s = JOptionPane.showInputDialog
	( "Bitte den Operator, also + , - , * oder : eingeben" );
	if ( s != null && s.length() > 0 )
  	{
	char c = s.charAt( 0 );
	f=(new Character(c)).toString();
	}
	s = JOptionPane.showInputDialog
	( "Bitte zweiten Operanden eingeben" );
	double o = Double.parseDouble( s );
	g=(new Double(o)).toString();
	}
	catch(Exception ex)
	{
	System.out.println("Eingabefehler");
	System.exit(1);
	}

	Operand1.setText(d);
	Operand2.setText(g);
	Operator.setText(f);
	anwendungsFenster.show();
}


public void Kommunikation()
{
// Socket-Verbindung auf den Port 1234 des Servers anfragen
	try
	{
	Socket server= new Socket("localhost", 1234);
	// Datenströme öffnen
	DataInputStream in = new DataInputStream(server.getInputStream());
	DataOutputStream out = new DataOutputStream (server.getOutputStream());
	
	// Beide Argumente als Intergerzahlen an den Server senden
	double zahl1 = Double.parseDouble(d);	
	double zahl2 = Double.parseDouble(g);
	char op = f.charAt( 0 );
	
	out.writeDouble(zahl1);
	out.writeDouble(zahl2);
	out.write(op);

	// Ergebnis von Server einlesen und ausgeben
	resultat= in.readDouble();
	// Socketverbindung zu Server schliessen
	server.close();
	}
	catch(Exception ex)
	{
	System.out.println("Kommunikationsfehler");
	System.exit(1);
	}
	
}


public void ErgAnz()
{
String h=(new Double(resultat)).toString();
	ergebnis.setText(h);
	anwendungsFenster.show();
	
}

private void hilfeActionPerformed(java.awt.event.ActionEvent evt) { 
	JTextArea Hilfetext=new JTextArea();
	Hilfetext.show();
	} 

private void eingabeActionPerformed(java.awt.event.ActionEvent evt) { 
	EingabeDialog();	
	}


public static void main(String[] args) throws Exception
	{
	SocketClient C=new SocketClient();
	}
}
```


Nun will ich Euch ja nicht über Gebühr in Anspruch nehmen, aber ich möchte jetzt, dass das Programm wartet, bis man den "Eingabe beginnen" button drückt oder den "Hilfe"-Button und nicht gleich durchläuft. Ich kann da einfach nichts finden...

Vielen Dank schon mal und einen guten Rutsch wünsche ich.


----------



## chamaeleon879 (30. Dez 2006)

weiß jetzt nicht ob ich das richtig verstanden habe. Aber denke mal, du willst, das ein Dialog erscheint, welcher auf eine Benutzereingabe wartet. 
Klickt er ok, dann mach weiter, klickt er abbrechen, dann tu halt nix.

Also ich habe das mal so realisiert:



```
JOptionPane PaneOK  = new JOptionPane();
            JOptionPane confirmPane= new JOptionPane();
            int reversint = confirmPane.showConfirmDialog(this,"Soll weitergearbeitet werden?","Frage an Benutzer",JOptionPane.YES_NO_OPTION);            
             if (reversint ==JOptionPane.YES_OPTION){


tu irgendwas}
```

hoffe es hilft.


----------



## Gast (30. Dez 2006)

Danke für die schnelle Antwort.

Ich meinte es eher so:

Beim Start des Programms wird ein Fenster angezeigt mit zwei Buttons "Hilfe" und "Eingabe beginnen". An der Stelle soll er dann warten, dass der Benutzer entweder Hilfe drückt, dann öffnet sich die Textarea oder "Eingabe beginnen" drückt, dann wird die Methode aufgerufen in der über einen Eingabedialog die Rechenaufgabe eingegeben werden soll. Das einzige was jetzt noch fehlt, ist, dass er an der Stelle wo die Listener hinzugefügt werden, warten soll, dass der Nutzer was drückt. Jetzt läuft es darüber hinweg. Die Stelle habe ich im Code oben kommentiert.

Ich hoffe ich habe mich nicht zu umständlich ausgedrückt.


----------



## VipViper2000 (31. Dez 2006)

Also ich würde vorschlagen du liest dir wirklich mal was über OOP durch - du versuchst das alles irgendwie prozedural zu programmieren.

1. Verwende NIE deprecated Methoden ( z.B. show())

2. Deine main sollte nur den Controller aufrufen der dann wiederrum eine Instanz der GUI erstellt und Listener regisriert (Hier is es eine Geschmacksfrage in welcher Reihenfolge man es macht)

3.Dieses "warten" was du erzwingen willst passiert doch automatisch, sobald du die Oberfläche mit setVisible(true) sichtbar gemacht hast. Wenn du dann auf den Hilfe Knopf drückst, wird der Listener darüber informiert, woraufhin du dann ein neues JFrame (oder besser von JDialog abgeleitet) erzeugen kannst.

Aber wie gesagt: Diese Denkweise - "Der durchläuft mein Programm von oben nach unten und soll an der Stelle anhalten" ist vollkommen falsch.

Gruß,
VipViper2000


----------



## chamaeleon879 (1. Jan 2007)

also ich kann da VipViper2000 nur zustimmen. Verstehe das mit dem "warten" auch nicht.

was für einen editor benutzt du eigentlich ??Also ich persönlich finde Netbeans super, auch wen sehr viel auf Eclipse schwören, finde ich in Eclips keine Vorteil. Aber das ist Geschmackssache und soll keine Grundsatzdiskussion auslösen. Meine nur, da der Editor den Code für die Gui selber schreibt udn du dich auf die wichtigen Dinge konzentrieren kannst.


----------



## Guest (2. Jan 2007)

Ein frohes neues Jahr wünsche ich!

Ich habe bisher immer den Windows-Zubehör-Editior und die Kommandozeile benutzt. Aber ich bin jetzt kürzlich auf Eclipse umgestiegen. 

Ich habe jetzt alle deprecated Methoden mit aktuellen ersetzt und habe mich bemüht noch mehr Objektorientiertheit reinzubringen, ich weiß, dass ich da noch mehr lernen muss und arbeite jeden Tag mit Hochdruck daran.  :###

Leider bleibt mein Problem bestehen. Ich poste es jetzt noch mal:


```
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.net.*;
import java.io.*;


public class SocketClient
{
static String d,f,g;
static double resultat;
JFrame anwendungsFenster;
JTextField Operand1;
JTextField Operator;
JTextField Operand2;
JTextField ergebnis;
JButton hilfe;
JButton eingabe;
JLabel label;
JPanel textfeldPanel;
DataInputStream in;
DataOutputStream out;

public SocketClient()
{
ErstellungOberfl();
ListenerReg();
OberflAnz();
Kommunikation();
ErgAnz();

}

public void ErstellungOberfl()
{
anwendungsFenster = new JFrame("Rechenanfrage an Server");
Operand1 = new JTextField("0", 10);
Operator = new JTextField("+", 1);
Operand2 = new JTextField("0", 10);
ergebnis = new JTextField("0", 20);
hilfe = new JButton("Hilfe");
eingabe = new JButton("Eingabe beginnen");
Operand1.setEditable(false);
Operand2.setEditable(false);
Operator.setEditable(false);
ergebnis.setEditable(false);
label = new JLabel("Statusfenster",SwingConstants.LEADING);
textfeldPanel = new JPanel();
		
		textfeldPanel.setLayout(new GridLayout(3, 1));
		textfeldPanel.add(Operand1);
		textfeldPanel.add(Operand2);
		textfeldPanel.add(ergebnis);

anwendungsFenster.getContentPane().setLayout(new GridLayout(4, 2));
anwendungsFenster.getContentPane().add(hilfe);
anwendungsFenster.getContentPane().add(eingabe);
anwendungsFenster.getContentPane().add(label);		
anwendungsFenster.getContentPane().add(Operator);
anwendungsFenster.getContentPane().add(textfeldPanel);

anwendungsFenster.getContentPane().setLayout( new FlowLayout());
anwendungsFenster.pack();
}
public void ListenerReg(){
hilfe.addActionListener(new java.awt.event.ActionListener() {
    public void actionPerformed(java.awt.event.ActionEvent evt) {
        hilfeActionPerformed(evt);
    }
});        
eingabe.addActionListener(new java.awt.event.ActionListener() {
    public void actionPerformed(java.awt.event.ActionEvent evt) {
        eingabeActionPerformed(evt);
        
    }
}); 
}

public void OberflAnz(){
anwendungsFenster.setVisible(true);
}
    
public void EingabeDialog(){
try
	{
	String s = JOptionPane.showInputDialog
	( "Bitte ersten Operanden eingeben" );
	double i = Double.parseDouble( s );
	d=(new Double(i)).toString();

	s = JOptionPane.showInputDialog
	( "Bitte den Operator, also + , - , * oder : eingeben" );
	if ( s != null && s.length() > 0 )
  	{
	char c = s.charAt( 0 );
	f=(new Character(c)).toString();
	}
	s = JOptionPane.showInputDialog
	( "Bitte zweiten Operanden eingeben" );
	double o = Double.parseDouble( s );
	g=(new Double(o)).toString();
	}
	catch(Exception ex)
	{
	System.out.println("Eingabefehler");
	System.exit(1);
	}

	Operand1.setText(d);
	Operand2.setText(g);
	Operator.setText(f);
	anwendungsFenster.setVisible(true);
}


public void Kommunikation()
{
// Socket-Verbindung auf den Port 1234 des Servers anfragen
	try
	{
	Socket server= new Socket("localhost", 1234);
	// Datenströme öffnen
	DataInputStream in = new DataInputStream(server.getInputStream());
	DataOutputStream out = new DataOutputStream (server.getOutputStream());
	
	// Beide Argumente als Intergerzahlen an den Server senden
	double zahl1 = Double.parseDouble(d);	
	double zahl2 = Double.parseDouble(g);
	char op = f.charAt( 0 );
	
	out.writeDouble(zahl1);
	out.writeDouble(zahl2);
	out.write(op);

	// Ergebnis von Server einlesen und ausgeben
	resultat= in.readDouble();
	// Socketverbindung zu Server schliessen
	server.close();
	}
	catch(Exception ex)
	{
	System.out.println("Kommunikationsfehler");
	System.exit(1);
	}
	
}


public void ErgAnz()
{
String h=(new Double(resultat)).toString();
	ergebnis.setText(h);
	anwendungsFenster.setVisible(true);
	
}

private void hilfeActionPerformed(java.awt.event.ActionEvent evt) { 
	JTextArea Hilfetext=new JTextArea();
	Hilfetext.setVisible(true);
	} 

private void eingabeActionPerformed(java.awt.event.ActionEvent evt) { 
	EingabeDialog();	
	}


public static void main(String[] args) throws Exception
	{
	new SocketClient();
	}
}
```

Wenn ich Euch richtig verstehe, müsste er also bei der Methode OberflAnz() automatisch warten, bis ein Knopf gedrückt wird? Denn dort wird ja anwendungsFenster.setVisible(true); gesetzt. Aber das tut er nicht, sondern er ruft die nächste Methode auf, die im Konstruktor von SocketClient steht, nämlich Kommunikation(). Die soll er aber erst später aufrufen, wenn er mit dem Server kommunizieren soll. Also meine Frage lautet, wieso wartet er nicht auf einen Knopfdruck, wo ist mein Denkfehler?

Danke.

Viele Grüße, Tahomar  [/code]


----------



## WieselAc (2. Jan 2007)

nein nicht ganz der quellcode wird komplett durchlaufen und ausgeführt, bis auf den der Code, der in deinen Action Methoden steht. Dieser wird erst ausgeführt, wenn ein Knopf gedrückt wurde.


----------



## Tahomar (2. Jan 2007)

Ok, danke WieselAC,  und deswegen ist mein Ziel, dass er in Zeile 81 in OberflAnz() erstmal auf ein Knopfdruck wartet. Bin ich da auf dem Holzweg?


----------



## Tahomar (2. Jan 2007)

Habs geschafft, musste die Methoden nur anders aufrufen, so dass alles von der Oberfläche aus aufgerufen wird, ist ja auch logisch.   

Insofern gebe ich meinen Vorrednern Recht, dass es an der fehlenden OOP gelegen hat.


----------



## chamaeleon879 (2. Jan 2007)

herzlichen Glückwunsch.

wollte dir nur nochmal einen Tipp zwecks Java Editor nennen:
www.netbeans.org

--> geiler GUI Editor
--> MEINER MEINUNG nach besser als Eclipse

Viel Spaß weiterhin mit Java


----------

