# Daten umherschieben zwischen zwei Klassen



## Anto (31. Okt 2011)

Ich habe eine starterklasse, die von JFrame erbt und in der ein Objekt der Klasse Field angelegt wird.
Dieses Objekt heißt field.

In der Klasse Field steht mein ganzer Paint-Kram.
Nun habe ich eine weitere Klasse Controller, die meine KeyListener implementiert und zudem von Thread erbt. 
Wie in aller Welt komme ich jetzt aus Controller an die Daten in field?

Ich komme AN die Daten indem ich in der starterklasse noch ein Controllerobjekt anlege dem ich field übergebe, aber ich sehe keine Möglichkeit, die Daten in field auf Tastendruck zu resetten.

Was übersehe ich?

Vielen Dank

Anto


----------



## Gast2 (31. Okt 2011)

> Ich habe eine starterklasse, die von JFrame erbt und in der ein Objekt der Klasse Field angelegt wird.
> Dieses Objekt heißt field.
> 
> In der Klasse Field steht mein ganzer Paint-Kram.
> ...


Du solltest die Instanz von Field in deinem Controller erzeugen und die Referenz darauf an den View übergeben. Dann teilen sich die beiden Klassen das selbe Field Objekt.


----------



## Anto (31. Okt 2011)

Das geht deswegen nicht, weil ich besagte Instanz ja auf meine Starterklasse aufsetzen muss -field ist schließlich ein JPanel. Davon abgesehen ist der Anfang des Codes vorgegeben.


----------



## Gast2 (31. Okt 2011)

Zeig mal etwas Code, das ganze hört sich ein wenig nach falschem Design an.


----------



## Anto (31. Okt 2011)

Das kann ich schlecht, wenn mein Tutor hier evtl. mitliest.

Mein Hauptproblem ist, dass ich zwei GUI-Klassen habe sonst könnte ich das ja notfalls so machen wie Du willst. und ich bekomme es nicht hin, dass die wechselseitig aufeinander zugreifen können.


----------



## winSharp93 (31. Okt 2011)

Anto hat gesagt.:


> Das kann ich schlecht, wenn mein Tutor hier evtl. mitliest.


Tja - was soll man dazu jetzt sagen 

Aber generell zu dem Problem: Wenn zwei Objekte miteinander kommunizieren sollen, müssen sie irgendwie einander bekannt sein (direkt oder indirekt).

An einer Stelle musst du also deinem Controller das "field" übergeben. Dann kann dein "Field" eine Methode bereitstellen, die du in Folge eines Tastendruckes aufrufst und die dann die Daten zurücksetzt.

Konkreteres kann man da ohne eine weitere Beschreibung des Problems allerdings nicht sagen.

Aber auch für mich klingt das eher nach suboptimalem Design - warum reißt du den Controller und die für's Zeichnen verantwortliche Klasse auseinander, wenn du sie danach doch so eng verbinden möchtest?
Du solltest dir evtl. ein paar Gedanken machen, wie du die Logik besser aufteilen kannst bzw. von der Darstellung trennen kannst.


----------



## Anto (31. Okt 2011)

Weil vorgegeben ist, dass die beiden unter gar keinen Umständen in derselben Klasse liegen dürfen.
Der Controller fängt Listener ab, sonst nichts.
Hm, geht das evtl per PN oder icq? Ich denke mal dass ich das nicht öffentlich posten möchte, ist nachvollziehbar?


----------



## winSharp93 (1. Nov 2011)

[OT]


Anto hat gesagt.:


> Hm, geht das evtl per PN oder icq? Ich denke mal dass ich das nicht öffentlich posten möchte, ist nachvollziehbar?


Ich persönlich helfe aus Prinzip nicht via PN weiter - ich finde, das hat dann nichts mehr mit freiwilliger, communitybasierter Hilfe zu tun.
IMHO sollte man daher - wenn man Hilfe in einem Forum sucht - auch berücksichtigen, dass quasi alle Helfer dort ehernamtlich tätig sind und daher Fragen möglichst so zu stellen, dass man den Zusatzaufwand für die Antwortenden möglichst gering hält.
Bei persönlicher Betreuung per PN übersteigt - zumindest für mich - der Aufwand allerdings klar den Spaß, den es macht, auf Fragen in Foren zu antworten.
Insofern: Nein, das kann ich nicht nachvollziehen 

Trotzdem helfe ich natürlich gerne im Rahmen dieses Threads.
[/OT]



Anto hat gesagt.:


> Der Controller fängt Listener ab, sonst nichts.


Ok - und warum kann er dann nicht einfach auch eine Referenz auf das Field erhalten (z.B. via Setter oder Konstruktor?


----------



## Anto (1. Nov 2011)

Ich verstehe Dein Problem, Du meines aber hoffentlich auch.

Eine solche Referenz gab es ja gerade. Ich habe ein Controllerobjekt in meiner Startklasse erstellt und dem mein field übergeben. Damit konnte ich dann auf field zugreifen. 
Das Problem dahinter: Ich will ja eigentlich mittels den Listenerfunktionen im Controller die Werte in Field verändern. Und DAS ging dann nicht mehr.
Da bin ich auch ehrlich überfragt, ohne einen riesigen Umweg übers Model erscheint mir das bis jetzt nicht machbar.


----------



## Anto (1. Nov 2011)

Das Problem ist, ich habe dadurch, dass Java nur einfachvererbung kennt, jedes Mal dasselbe Problem. Ich brauche eine Klasse die von JFrame erbt und eine die von JPanel erbt.
Dann dazu noch eine die den Listener implementiert und von Thread erbt. Das sind, wegen Einfachvererbung, schonmal definitiv drei Klassen, die alle auf dasselbe Objekt zugreifen müssen.

Dazu darf, wegen MCV, keine andere Klasse auf die Klasse Zugriff haben, die die Listener implementiert und die paintmethode darf  nicht im Controller stehen.
Wie man das noch durch die Landschaft reichen soll, ohne gleich mit Observern um sich zu werfen, ist mir ein Rätsel.


----------



## winSharp93 (1. Nov 2011)

Anto hat gesagt.:


> Das Problem dahinter: Ich will ja eigentlich mittels den Listenerfunktionen im Controller die Werte in Field verändern. Und DAS ging dann nicht mehr.


Das kann ich jetzt nicht nachvollziehen: Ein Objekt kann ja sowohl Listener eines anderen Objektes sein und eine Referenz darauf halten.
Sofern die Listener-Beziehung durch bspw. Interfaces entkoppelt ist, besteht auch keine zirkuläre Referenz.

Verwendest du MVC und das Model benachrichtigt den Controller via Observer-Pattern über Änderungen?
Dann ist ja eine Abhängigkeit vom Controller auf das Model quasi unvermeidlich: Dieser muss ja das Model auslesen, um entsprechend das View steuern zu können.

//EDIT:
Ah - gerade deine zweite Antwort gesehen:
Ich glaube, Interfaces könnten dich der Lösung schon einmal deutlich näher bringen - dadurch kannst du ja quasi "Mehrfachvererbung" realisieren (wenn auch nur Vererbung der Schnittstelle - aber das willst du ja bei den Listenern).


----------



## Anto (1. Nov 2011)

Nein, die Vorgabe ist anders: der Controller sollte eigentlich über Getter und Setter an das Model kommen, das Model greift selbst auf überhaupt gar nichts zu, die Gui hat allerdings über Observer Zugriff auf das Model.

Allerdings ist das jetzt gerade nur eine Version die "irgendwie" laufen soll, ich wollte die Observer etc. gerade noch nicht drin haben, auch auf Kosten des Patterns.

Aber anscheinend ist das, was ich haben will, technisch völlig unmöglich?

Ich habe bisher weder mit Observern noch mit runnable gearbeitet und wollte halt erst einfach mal testen  - nur um dann festzustellen, dass es völlig unmöglich zu sein scheint, das im Controller einfach meine Listenerfunktionen stehen welche dann die Daten von field neu setzen.


----------



## winSharp93 (1. Nov 2011)

Meinen Edit hattest du gesehen?



> Dann dazu noch eine die den Listener implementiert und von Thread erbt. Das sind, wegen Einfachvererbung, schonmal definitiv drei Klassen, die alle auf dasselbe Objekt zugreifen müssen.


In diesem Zusammenhang sind die sogenannten anonymen Klassen hilfreich: Lasse nicht deinen Controller erben / implementieren, sondern verwende diese anonymen Klassen, die dann Zugriff auf alle Member der Controllerklasse haben.



> paintmethode darf nicht im Controller stehen


...aber erst recht nicht im Model.
Und da scheinst du sie ja zur Zeit zu platzieren, oder?



> der Controller sollte eigentlich über Getter und Setter an das Model kommen, das Model greift selbst auf überhaupt gar nichts zu, die Gui hat allerdings über Observer Zugriff auf das Model.


Das ist soweit kein Problem: Du musst nur - wie gesagt - ein Interface als Listenertyp verwenden. Das Model soll also nicht konkret das View oder den Controller kennen, sondern nur ein allgemeines Interface (wie bspw. _ModelListener_) informieren.
Dieses Interface kann dann vom View (und evtl. auch vom Controller implementiert werden).
Wichtig: Selbst wenn du dann quasi schemenhaft 
	
	
	
	





```
model.addListener(view);
```
 aufrufst, heißt das nicht, dass das Model auch das View "kennt" - dies ist nur der Fall, wenn du _keine_ Interfaces verwendest. 



> das im Controller einfach meine Listenerfunktionen stehen welche dann die Daten von field neu setzen.


Wie gesagt: Der Controller braucht in jedem Fall Zugriff auf das Model.


----------



## Anto (1. Nov 2011)

Ja, habe ich gesehen.

Genau sowas wollte ich ja vermeiden: Die Kiste soll möglichst in 3-4 Klassen irgendwie laufen ohne mehr Interfaces als den KeyListener.

Nein, paint steht im Moment in Field und Field gehört zur Gui. 
Aktuell habe ich noch kein Modell. Wie gesagt, es soll nur irgendwie anspringen, falls möglich würde ich das in zwei Klassen schreiben wenn ich nicht drei wegen der Vererbung bräuchte. 
Es geht im Moment um eine irgendwie lauffähige Version die, weil lauffähig, bestehen würde. Direkt "schön" zu programmieren traue ich mich nicht, denn was hilft mir das, wenn ich dann aus Zeitgründen durchfalle? Dann besser erstmal was hingerotztes was besteht und wenn die fertig ist das ganze nochmal in hübsch.


----------



## winSharp93 (1. Nov 2011)

Anto hat gesagt.:


> Aktuell habe ich noch kein Modell.


Aha - da haben wir ja das Problem; MVC ohne "M" ist relativ witzlos 

Hintergrund ist ja: Das View stellt sich aufgrund des Models dar - dein Field sollte im Idealfall folglich keinerlei "Zustand" haben.
Dieser gehört ins Model!

Dann kannst du in deinem Controller nämlich einfach das Model zurücksetzen (woraufhin dann das View als Listener benachrichtigt wird) und dein "Field" erneut zeichnen kann.
Somit brauchst du vom Controller aus gar nicht auf das Field zuzugreifen - du änderst etwas am Model und das View "zieht nach".

Alternativ kannst du (zumindest vorerst) - da der Controller ja Zugriff auf das View hat - dein Frame einfach um eine Methode erweitern, die dann die Resetmethode des Fields aufruft.


----------



## Anto (1. Nov 2011)

Der Controller hat gerade KEINEN Zugriff auf die View und ich habe auch keine Ahnung dass ich bewerkstelligen soll wie er das hat, das ist doch das Problem!

Ich habe in der View ein Controllerobjekt erzeugt und diesem ein viewobjekt übergeben, auf die Art komme ich vom Controller aus an die Daten von View, aber der Rückweg funktioniert nicht!


----------



## Anto (1. Nov 2011)

Dazu kommt noch, mein Model müsste dann von Thread und Observable gleichzeitig erben, und das geht ja nun nicht.


----------



## winSharp93 (1. Nov 2011)

Anto hat gesagt.:


> Der Controller hat gerade KEINEN Zugriff auf die View [...] Ich habe in der View ein Controllerobjekt erzeugt und diesem ein viewobjekt übergeben


Das ist widersprüchlich: Wenn der Controller eine Referenz auf die View hat, hat er auch Zugriff darauf ???:L

Im Moment stelle ich mir das ganze wie folgt vor:

```
public class View {
  private Field field; //Für's Zeichnen zuständig
  private Model model; //Das Model, das dargestellt wird

  public void setModel(Model model) {
     //... - Model setzen und Anzeige aktualisieren
  }

  //evtl:
  public void resetDrawing() {
    field.//...;
  }
}

public class Controller {
  private View view;
  private Model model;
  //...
  
   private void Foo() {
    view.resetDrawing();
    //oder
    model.resetData();
  }
}

//Programm:
Model model = new Model(); //Existiert noch nicht, aber geplant
View view = new View();
Controller controller = new Controller (model, view);
```

In der Methode Foo hast du doch jetzt Zugriff auf das View und kannst beliebig resetten, oder?



> Dazu kommt noch, mein Model müsste dann von Thread und Observable gleichzeitig erben, und das geht ja nun nicht.


Wie gesagt: Anonyme Klassen und/oder Interfaces.


----------



## Anto (1. Nov 2011)

Das erinnert mich gerade an jemanden....aber gut.....

Du bist nicht zufällig aus Brandenburg? Also, dem Bundesland?


Danke auf jeden Fall, ich glaube, mit dem Hinweis schreibe ich das morgen nochmal neu....zum vierten Mal......hab' ja noch eine Woche dafür.

Grüße

Anto


----------



## winSharp93 (1. Nov 2011)

[OT]





> Du bist nicht zufällig aus Brandenburg? Also, dem Bundesland?


Brandenburg? :shock:
Nö - Baden 
[/OT]


----------



## Anto (1. Nov 2011)

Hm da hätte ich doch dasselbe Problem wie vorher: view.resetDrawing würde nicht funktionieren da mein Modelobjekt nur im Konstruktor des Kontrolers existiert. Ich hätte auf das Objekt selbst keinerlei Zugriff. GENAU DAS ist doch mein problem in der Version von gestern Abend!


----------



## Marcinek (1. Nov 2011)

Hallo,

du hast grundlegende Defizite, was Nachrichtenaustausch zwischen Objekten oder Klassen betrifft.

Du suchst hier nach Hilfe und möchtest keine Komplettlösung haben. Poste deinen Code oder bezahle eine Nachhilfe. Wenn der Tutor das nicht erlaubt, dann solltest du dich an ihn wenden um weitere Hilfe zu bekommen oder an deine Komilitonen..

So wie das hier in dem Thread geht, wirst du noch Jahre brauchen, weil der eine User, der dir helfen möchte nur am raten ist und hofft dein Problem zu lösen. Aber deine Defizite machen es unmöglich.

Gruß,

Martin


----------



## GUI-Programmer (1. Nov 2011)

http://www.java-forum.org/awt-swing-swt/121859-mvc-jframe-mehrere-jpanels.html


----------



## Anto (1. Nov 2011)

Marcinek: Naja mir fehlt ja im Grunde nur eine einzige Zeile Pseudocode:
Mit welchem Befehl sette ich von einer Klasse aus Code in einem Objekt einer anderen Klasse?

Dass das geht, weiß ich.

Wie es geht, ist mir ein Rätsel.

+, das ist mir aber jetzt erst klargeworden: ich dachte, es sei klar, dass resetDrawing (oder anders, repaint) in field stehen muss, einfach weil das, was neugemalt wird, ja das Panel ist und weil man nur dafür überhaupt eine Klasse Field hat.


----------



## Marcinek (1. Nov 2011)

Da bin ich nun gespannt:

## irgentwo im Code ##

MeinKunde einKunde = new MeinKunde ();

einKunde.setName("Hans");

## Ende es Codes

## In der Klasse MeinKunde ##


```
public class MeinKunde {

  public void setName(String name) {
    -----
  }

}
```


----------



## Anto (1. Nov 2011)

Das funktioniert aber nur genau so lange wie Du einKunde in genau der Klasse erzeugt hast, in der Du es auch settest. Dieser Fall ist einfach. Was aber tut man, wenn das nun gerade nicht der Fall ist?


----------



## Marcinek (1. Nov 2011)

Entweder geht das dann nicht oder du musst die Referenz übergeben.

Eigentlich habe ich ja keine Lust ein Beispiel zu posten, weil ich denke, dass das in jedem Buch auf Seite spätestens 3 steht:


```
public class MeinKunde

   public MeinKunde( MeinKunde einAndererKunde ) {
       einAndererKunde.setName("Bla Bla");
    }
```

## IWo anders im Code:


```
MeinKunde einKunde = new MeinKunde ( new MeinKunde () );
```

ist genau das gleiche wie

```
MeinKunde einAndererKunde = new Kunde();

MeinKunde einKunde = new MeinKunde (einAndererKunde);
```

###


----------



## Anto (1. Nov 2011)

Danke...+...aber da muss ich nochmal drüberschauen wenn ich wieder vor dem Rechner sitze....ich DENKE mein Problem hat sich gerade in Luft aufgelöst ich dachte bis eben, die Klasse die run implementiert muss zwingend von Thread erben, dabei muss sie das ja gar nicht.


----------



## Gast2 (1. Nov 2011)

> ich DENKE mein Problem hat sich gerade in Luft aufgelöst ich dachte bis eben, die Klasse die run implementiert muss zwingend von Thread erben, dabei muss sie das ja gar nicht.


Du willst aber nicht Vererbung einsetzen, nur damit du Zugriff auf ne Variable oder ne Methode hast oder?


----------



## bERt0r (1. Nov 2011)

Ich würde mal sagen: "Halt stop!" Du hast da was grundlegendes nicht kapiert und willst jetzt bei schwierigeren Themen weitermachen. Das geht nicht. Ich würde dir rateb lies dir mal dieses Kapitel durch (das ganze) Galileo Computing :: Java ist auch eine Insel - 3 Klassen und Objekte 
Teste den Code der dort steht auch selber nach bzw. schreib es nach, nur so lernt mans.


----------



## Anto (2. Nov 2011)

Teilweise schon oder geht das beispielsweise beim Observer anders?


----------



## Marcinek (2. Nov 2011)

Ja das geht anders.

Aber ich habe ka was du machen willst ^^ - Threads, run-Methode Observer, Daten zwischen zwei Klassen.

Ein böser Tutor -.-

Dieser Thread ist ein fail. Poste die Aufgabenstellung und Code.:rtfm: Oder lies ein Buch.


----------



## Anto (2. Nov 2011)

Java ist eine Insel lese ich ja die ganze Zeit schon.

Dem Tutor würde ich das gar nicht zur Last legen, wenn der Teile von meinem Code im Internet findet, bin ich eben durchgefallen - durch die ganze Veranstaltung, nicht nur durch den einen Übungszettel.
So ist bei uns die Regelung.
Das bedeutet, das kostet mich ein Semester.
Ich finde die Regelung sogar gut, dass der Tutor böse ist, habe ich nie gesagt.

Wie könnte ich da irgendwem die Aufgabenstellung oder den Code posten?

+, in "Java ist auch eine Insel" steht drin, dass die Klasse, die beobachtet wird (im Normalfall das Model bei MCV) von der Klasse Observable erbt. Die Beobachterklassen implementieren das Interface Observer.

Und ihr sagt jetzt, das sei alles falsch?


----------



## Marcinek (2. Nov 2011)

Mir kannst du alles schicken, aber dann bitte gegen €.

Dein Statement oben im zusammenhang mit Eike Statement sagt mir, dass du, weil du auf eine Variable oder Methdoe zugreifen möchtest einfach von der anderen Klasse erbst.

Es gibt aber mehr als nur erben oder nur in der Klasse implementieren oder nur Referenzen. OOP baut auf allen diesen Methoden auf. Die musst du können.

Java ist auch eine Insel eignet sich für dich nicht so gut. Du brauchst ein didaktisch anders aufgebautes Buch. Was nutzt den der Tutor? Vielecht die Bücher von w3l?


----------



## Anto (2. Nov 2011)

Nicht persönlich nehmen, aber bevor ich jemand anderen meine Abgaben schreiben lasse studiere ich liebe 20 Jahre länger. Für mich ist das schlicht Betrug weiter nichts.

Was bringt das eigentlich?

Man stellt hier eine Frage, und was kommt sind "Lass jemand anderen Deine Abgabe machen" oder "Nimm Dir ein Jahr Zeit, um Folgendes zu lernen:....."


Erstere Lösung kommt für mich nicht in Frage, letztere mag in Ordnung sein für Leute die vor dem Studium schon programmieren konnten, für alle anderen von uns ist das vollkommen illusorisch. Und "alle anderen" umfasst bei uns dann doch gut 50%.


----------



## Mofi (2. Nov 2011)

Ich will mich da nicht zu sehr einmischen, da ich auch nicht den ganzen Thread gelesen habe, aber ich bezweifel, dass dir hier jeder geraten hat entweder zu betrügen oder länger zu studieren.

Das Problem ist, dass man beim Programmieren sehr schlecht helfen kann, wenn man den Code nicht sehen kann. Wenn du den Code nicht posten darfst, ist das zwar ein Grund das wir ihn nicht sehen, aber das reduziert mal die Möglichkeiten dir zu helfen...


Aber warum fragst du nicht deinen Tutor um Rat? Ich mein der ist doch dazu da um dir zu helfen oder nicht?


----------



## Anto (2. Nov 2011)

Na gut dann versuchen wir es mal codiert:


```
Class A extends Jframe {

void start(){

Gem gem = new Gem();
this.add(gem);
.....
this.addKeyListener(gem)

}
}

Class Gem extends JPanel implements KeyListener{

private Color b = Color.b;


    @Override
    protected void paintComponent(final Graphics g) {


this.setBackground(b);}

public void keyTyped(KeyEvent e){}


public voidkeyReleased(KeyEvent e){}

   public void keyPressed(KeyEvent e) {

System.out.prinln("Hallo");
       this.b =Color.GREEN;
       this.repaint();

    }



}
```


So long. Der Printbefehl springt an, der Listener springt also auch grundsätzlich an.
Nur: Am Bild scheint sich rein gar nichts zu ändern. Wo liegt mein Denkfehler?


----------



## Mofi (2. Nov 2011)

Also wenn du deinen Code zum laufen bringen willst...
Ich hab deinen Code (zu mindestens die Gemklasse) und ein wenig umgeändert.
Waren auch nur zwei Zeilen. 

```
@Override
	protected void paintComponent(final Graphics g){
		g.setColor(b);
		g.fillRect(0, 0, this.getWidth(), this.getHeight());
//		this.setBackground(b);
	}
```

Deine Zeile hatte ich nur auskommentiert. Aber so wird bei mir die Farbe dann zu grün geändert, wenn ich eine Taste drücke (und natürlich Hallo ausgegeben)

Ich bin mir jetzt nicht sicher warum das 
	
	
	
	





```
this.setBackground(b);
```
 nicht funktioniert, aber die anderen beiden Codezeilen bewirken:
1. Das das Graphicsobjekt eine neue Farbe zugewiesen bekommt (in diesem Falle die Farbe die die Variable b inhält)
2. Ein Rechtec´kt ausgefüllt wird, dass bei 0, 0 anfängt und die Größe des Panels hat.


Ich hoffe, dass hilft dir erstmal ein wenig weiter.

Aber ich würde ganz ehrlich gesagt NICHT in einem Panel in dem ich zeichne auch ein KeyListener tun. Die mach ich normalerweise in eine extra Klasse oder in die Klasse die die auch hinzugefügt bekommt.

Edit:
Wobei nach einigem überlegen, muss ich zugeben, dass hier der KeyListener evtl ganz gut da ist bzw. ich spontan auch keine bessere Idee hätte ohne alles umzuschreiben 

Problematisch wird es halt dann, wenn der KeyListener noch mehr machen soll als nur die Farbe von diesem Panel ändern, weil dann gehört es dort nicht mehr hin. Wobei man sich bei sowas immer streiten kann und jeder vermutlich seine eigene Art hat sowas zu programmieren (Listener meine ich)


----------



## Anto (2. Nov 2011)

Das Problem ist dass der Code ja nicht identisch war.

In Wirklichkeit setze ich ja nicht die Farbe neu ich tue etwas anderes. Es ist auch ganz egal was ich tue, der Repaintbefehl funktioniert einfach nicht.

Ich hätte den Fehler jetzt bei addKeyListener vermutet, übergebe ich dem denn das richtig?


----------



## Mofi (2. Nov 2011)

Anto hat gesagt.:


> Das Problem ist dass der Code ja nicht identisch war.
> 
> In Wirklichkeit setze ich ja nicht die Farbe neu ich tue etwas anderes. Es ist auch ganz egal was ich tue, der Repaintbefehl funktioniert einfach nicht.
> 
> Ich hätte den Fehler jetzt bei addKeyListener vermutet, übergebe ich dem denn das richtig?



Hast du meinen Code mal benutzt? (Also meine paintComponent statt deiner benutzt?) Weil bei mir funktioniert repaint...

Asonsten wenn du diese Zeile meinst 
	
	
	
	





```
this.addKeyListener(gem)
```
Ja die ist richtig solange gem ein KeyListener ist (diesen implementiert). Aber wäre gem keiner hätte dir das der Compiler schon gesagt.

Der KeyListener ist definitiv an dem Frame angedockt. Ansonsten hättest du auch keine Konsolenausgabe.

Du könntest in deinen Methoden die im KeyListener aufegrufen werden sollen mal ein paar Konsolenausgaben machen. Und bei der Methode wo die letzte Ausgabe erfolgt und danach nichts mehr obwohl noch was kommen sollte, wird wohl ein Fehler liegen 
(So mach ich das meistens zumindestens...  )


----------



## bERt0r (2. Nov 2011)

Ich zeig dir mal an einem Beispiel wie sowas funktionieren kann.

```
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

class A extends JFrame {

	A(){

		Gem gem = new Gem();
		gem.setBackground(Color.green);
		this.add(gem,BorderLayout.CENTER);
		JButton button=new JButton("Klickmich");
		button.addActionListener(new MyActionListener(gem));
		this.add(button,BorderLayout.SOUTH);
	}

	class Gem extends JPanel 
	{
		int clickCount=0;
		public void paintComponent(Graphics g)
		{
			super.paintComponent(g);
			int x=(int) this.getBounds().getCenterX();
			int y=(int) this.getBounds().getCenterY();
			g.drawString("Ich wurde "+clickCount+" mal geklickt.",x,y);
		}

		public void doStuffAfterClick()
		{
			clickCount++;
			this.repaint();
		}


	}
	
	class MyActionListener implements ActionListener
	{
		Gem myGem;
		MyActionListener(Gem g)
		{
			myGem=g;
		}
		
		public void actionPerformed(ActionEvent e)
		{
			myGem.doStuffAfterClick();
		}

	}
	
	public static void main(String args[])
	{
		A a=new A();
		a.setVisible(true);
	}
}
```


----------

