Wie Kann man in Java Events nach unten weitergeben?

...komplette Frage anzeigen

1 Antwort

Naja, das Problem besteht darin, dass du glaub ich gar nicht so recht weißt, was du genau möchtest - Und verstehst auch noch nicht das Problem, weshalb dein Button keine Events hat.


Also folgendes:

Deine Klasse leitet von JFrame ab. Also einem Fenster. Dem Fenster verpasst du einen Keylistener. - Du hast zumindest den Eindruck: Sobald du jetzt dein Panel mit dem Button anfügst, dass der Keylistener nicht mehr funktioniert, hab ich recht soweit?

Zum ersten: Damit ein Keylistener funktioniert, muss deine Komponente den Focus haben (also ausgewählt sein).

Dein Denkfehler setzt wohl ein, bei dem du die Annahme hast, dass der Keylistener automatisch an alle 'Childen' vererbt wird. - Das ist nicht der Fall!!

Heißt: Sobald du eine fokusierbare Komponente anfügst, nämlich den Button, wird der Keylistener vom JFrame unwirksam, da sonst der Frame keinen Focus bekommt.

Lösung für dich: du fügst deinem Button den Keylistener an.



    Knopf = new JButton("Test");
Knopf.setFont(new Font("Arial", Font.BOLD, 20));
Knopf.addKeyListener(this);
Platte.add(Knopf);



ok. am liebsten hätte ich aber den Focus von einer vokusierbaren komponente auf den Frame übertragen, d.h. der Knopf gibt das event an den frame weiter.

0
@yeretor

Auf die Art stößt du wieder auf dasselbe Problem wie bereits geschildert.

theoretisch kannst du den focus via Component#requestFocus(); erzwingen, aber das bringt dich nicht wirklich weiter, da, wie bereits gesagt, der KeyListener nur für die Komponente mit dem Focus funktioniert.

Du hast doch bereits in deiner Klasse einen Keylistener. Weis den doch einfach den Komponenten zu, die darauf reagieren sollen, also konkret: Deinem Frame und deinem Button.

So sehr du dir eine Vererbung des Listeners wünscht, das kann man nicht erzwingen. 

Aber wenn du mir erklärst was du damit bezweckst, wird es ja verständlicher.

1
@yeretor

Die Variante, bei der du dem Frame zusätzlich einen Keylistener zuweist?

Zusätzlich zu der Ergänzung von oben via:

this.addKeyListener(this);

Das erste this bezieht sich auf die Aktuelle Klasse, die Methode addKeylistener steht zur verfügung weil du von JFrame erbst. Das zweite this bezieht sich auf den Keylistener den du implementierst in der selben klasse.

1
@yeretor

ich will schlicht und einfach nicht jeder komponente einen keylistener anhängen. und woher weiß ich dann, welche komponente im focus liegt (wen ich mehrere habe)/ welche den listener angesprochen hat?

0
@KnusperPudding

nein die variante, bei der ich den focus auf meinen rahmen erzwinge (
 Platte.requestFocus(); oder this.requestFocus(); funktioniert nicht)

0
@yeretor

Das wiederum ist die 'unsaubere Methode' von der ich Sprach. 

requestFocus() setzt umgehend den Focus. - Dadurch geht aber natürlich das Keyevent verloren, um das nachzutragen wird dein Code deutlich unsauberer und länger und läuft letztendlich auf dasselbe hinaus.

1
@yeretor

ich will schlicht und einfach nicht jeder komponente einen keylistener anhängen.

Ja, exakt das ist der Punkt. Ein Keylistener funktioniert aber nun mal ausschließlich auf fokussierten Elementen und entsprechend ist bei deiner Anforderung auf alle Elemente ein Keylistener anzuhängen. 

1
@yeretor

Codeseitig über: #hasFocus(), 

Optisch unterscheidet es sich stark, je nach Komponente:

Beim Button über eine Gestrichelte Linie, Beim Textfield über den Blinkenden Cursor. - Jedoch beim Frame gar nicht.

Defaultmäßig hat der Frame auch nur dann den Focus, wenn sonst keine fokusierbaren Elemente enthalten sind. D.h. die erste Komponente, die wirklich fokusierbar ist, erhält dann beim Starten auch die den Fokus.

1
@KnusperPudding

Natürlich könntest du, sofern du keine Tastatursteuerung zulässt, alle Komponenten auf nicht fokusierbar setzen, somit würde dein Frame alle Key-Events abfangen.

D.h. du müsstest für jede Angefügte Fokusierbare Komponente 

.setFocusable(false);

setzen.

1
@KnusperPudding

ok. ich habe aber nur 1 mal die listener methoden. woher weiß ich - z.b. bei 2 textfeldern - vom programm auß, von welchem das event stammt?

0
@yeretor

Die 'Quelle' woher das Event stammt, bekommst du relativ Simpel via: KeyEvent#getSource() - Über getSource() bekommst du das Objekt zurück, welches das Event ausgelöst hat. D.h. Dein Frame oder dein Button.

0
@KnusperPudding

wie würde den ein beispielcode mit
 requestFocus(); außsehen?

 Platte.requestFocus(); oder this.requestFocus(); funktioniert nicht.

0

0
@yeretor

 funktioniert nicht.

Doch, funktioniert sehr wohl.

Wenn du deinen Frame anzeigen lässt:

frame.setVisible(true);
frame.setSize(300, 300);
frame.requestFocus();

Und dein Keylistener nur auf dem Frame liegt, dann werden genau so eingaben akzeptiert.

Fügst nach requestFocus() allerdings eine neue 'wirklich fokusierbare' Komponente an, ändert sich auch wieder der Focus.

Genauso verlierst du den Focus auf deinem Frame, sofern du eine Fokusierbare Komponente anklickst.

0
@KnusperPudding

und wie kann man vermeiden, dass der focus, sobald der knopf 1 mal gedrückt wurde dauerhaft auf ihm liegt, und nicht z.b. nach drücken des knopfs wieder auf dem frame liegt?

0
@yeretor

Am sinnvollsten indem du den Button nicht fokussierbar machst:

.setFocusable(false);

alternativ könntest du einen Actionlistener an den Button hängen, indem du dann Frame#requestFocus() aufrufst.

0
@KnusperPudding

1. würden die events vom knopf dann noch weitergegeben werden?

2. den frame hab ich ja als objekt nur in meiner main- methode.

    wie soll ich den von einer methode IN dem objekt ansprechen?

    (this.requestFocus(); funktioniert nicht!)

0
@yeretor

Zu 1.: Nein - Da ja keine Vererbung statt findet. Hat dein Button den Focus wird kein Listener des Frames aufgerufen.

Zu 2. Da kommt es dann drauf an, wie du den Rest Außenrum gestaltet hast. - Wovon leitet denn nun deine Klasse ab?

0
@yeretor

Im deinem Beispielcode leitest du ja bereits vom Frame ab. da brauchst du ja in der Main Methode keinen extra Frame

0
@KnusperPudding

und wie würdest du jetzt bei diesem konkreten beispiel den focus im Button-listener auf den frame setzen?

0

Was möchtest Du wissen?