# ActionListener mit JPanel?



## para_ (5. Dez 2006)

Hi, 

ich habe ein JPanel mit einem Button drauf (100% Size, er füllt das Panel komplett aus). (ist eine Extra Klasse) Kann ich dem JPanel einen ActionListener hinzufügen, so dass bei einem Klick auf den Button die Action ausgeführt wird?

das ganze sieht ungefähr so aus bei mir:


```
//...
class MyButton extends JPanel
implements ActionListener, MouseListener, MouseMotionListener{
    
        String text;
        JButton b;

        public MyButton(String s) {
            this.text = s;
            b = new JButton(s);
            add(b);
            b.addMouseListener(this);
            b.addMouseMotionListener(this);
        }

        // hab hier mal versucht zu überschreiben, damit der Button auch einen ActionListener bekommt
        public void addActionListener(ActionListener a) {
            b.addActionListener(a);                     // <- das müsste müll sein, mir ist aber nichts besseres eingefallen :(
                                                                       // müsste warscheinlich die source so setzen, dass das MyButton objekt als source
                                                                       // an das hauptprogramm übergeben wird.. nur wie mach ich das? 
        }

//...weiteres zeug
}
```

Im Hauptprogramm (implementiert ActionListener) habe ich dann so etwas:


```
// ...
       MyButton b = new MyButton("test");
       b.addActionListener(this);
       // ...
       public void actionPerformed(ActionEvent e) {
            Object source = e.getSource();
            if ( source == b ) machWas();
       }
       // ...
```

Leider passiert da garnichts 

Bin für jede Hilfe dankbar


----------



## The_S (5. Dez 2006)

Du musst die ActionListener beim Adden z. B. in einer collection speichern und wenn dann dein ActionEvent auftreten soll über alle geaddeden ActionListener iterieren und die jeweilige Methode aufrufen.


----------



## para_ (5. Dez 2006)

Hm, ich habe irgendwie Probleme damit. Der Button verdeckt das ganze JPanel in meinem Programm (habe ich oben vergessen, das JPanel hat ein GridLayout), also kommt es nie zu einem actionPerformed im Hauptprogramm 
Das mit der Collection versteh ich nich so recht. Die müsste ich ja im Hauptprogramm erstellen. Aber weil ich ja einen Button drücke und nicht wirklich das JPanel selbst, kommt, wie schon geschrieben nie ein actionPerformed.  

Ich habe jetzt ausserdem die überschriebene Methode rausgenommen (addActionListener)  und jetzt kann ich dem JPanel natürlich keinen ActionListener mehr hinzufügen.
Also habe ich einen MouseListener hinzugefügt, das GridLayout mit einem FlowLayout ersetzt und mouseClicked abgefragt, wenn ich nun in das JPanel klicke, aber halt außerhalb des Buttons bleibe, funktioniert alles wie ich möchte. Ich möchte halt dass ich den Button klicken kann.

Weisst was ich meine?


----------



## The_S (5. Dez 2006)

para_ hat gesagt.:
			
		

> Weisst was ich meine?



Net wirklich, aber ich post dir gleich mal nen Beispielcode  .


----------



## The_S (5. Dez 2006)

```
import java.awt.event.*;
import javax.swing.*;
import java.util.*;

public class ActionPanel extends JPanel implements MouseListener {
	
	private ArrayList<ActionListener> listener = null;
	
	public ActionPanel() {
		
		listener = new ArrayList<ActionListener>();
		addMouseListener(this);
	}
	
	protected void fireUpdate(ActionEvent evt) {
		
		for (ActionListener al : listener) {
			al.actionPerformed(evt);
		}
	}
	
	public void addActionListener(ActionListener al) {
		listener.add(al);
	}
	
	public void removeActionListener(ActionListener al) {
		listener.remove(al);
	}
	
	
	public void mouseClicked(MouseEvent evt) {
		fireUpdate(new ActionEvent(this, 0, "command"));
	}
	
	public void mousePressed(MouseEvent evt) {}
	public void mouseEntered(MouseEvent evt) {}
	public void mouseReleased(MouseEvent evt) {}
	public void mouseExited(MouseEvent evt) {}
	
	public static void main(String[] args) {
		
		JFrame frame = new JFrame();
		ActionPanel ap = new ActionPanel();
		frame.setContentPane(ap);
		frame.setSize(400, 300);
		ap.addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent evt) {
				System.out.println("Da hat wer was geklickt");
			}
		});
		frame.setVisible(true);
	}
}
```

Zum Selbstauführen und lernen  . Wenn de das ActionPanel dann verwendest schmeiße vorher natürlich die main-Methode raus  .


----------



## para_ (6. Dez 2006)

Wow, das funktioniert schon beinahe so wie ich es möchte 
Was jetzt noch nicht geht ist sicher ein nur ein kleinerer Fehler, das krieg ich bestimmt allein hin, vielen vielen Dank 

(wieder was gelernt ^-^)


----------



## para_ (6. Dez 2006)

So, ich musste natürlich statt

```
bt[i].addActionListener(new ActionListener() {
         
         public void actionPerformed(ActionEvent evt) {
               blablabla[i]=bla[i]+blabla[i];
               //mein zeugs
         }
      });
```


```
bt[i].addActionListener(this);
```
nehmen weil ich sonst eine ArrayOutOfBoundsException kriege (habe ein ganzes Array von diesen JPanels  ) 
Ich gehe jetzt in meinem actionPerformed einfach alle JPanels im Array durch und frage ob das aktuelle== e.getSource() ist.

Jetzt geht alles. Nochmal danke


----------



## The_S (6. Dez 2006)

Hä? Bezogen auf was?


----------



## para_ (6. Dez 2006)

Hm was meinst du? 

Dein ActionPanel funktioniert super, habe die Methoden daraus in mein Panel eingebaut.

Da ich aber viele dieser Panel in mein JFrame einbaue, habe ich diese in ein Array gepackt (weil ich vorher nicht weiss, wieviele dieser Panels hinzugefügt werden, es liest nämlich alle Methoden der Klasse eines übergebenen Objektes aus und erstellt für jede public Methode solch ein Panel, wenn man dieses klickt wird die Methode ausgeführt, ich habe dann noch weitere Arrays zb. für die Parameter der Methoden. Darum gehe ich im actionPerformed des Hauptprogrammes (nicht des ActionPanels) alle ActionPanels durch und schaue, ob das geklickte das bt_ ist. Könnte den Quelltext posten zum besseren Verständnis, aber is ca. 800 Zeilen lang.)_


----------



## The_S (6. Dez 2006)

Achso, hab mir deinen Code nicht wirklich angeschaut  . Dann passt alles soweit


----------

