Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
folgendes Problem:
Ich möchte von meiner 'MenuBar' Klasse aus, nach 'actionPerformed()' eine Interface-Methode ansprechen. Anstatt in den besagten Klassen eine Methode auf Static zu stellen.
Die Klasse 'ToolBar' hat die Methode 'actionPerformed' welches die Methode 'doBarrelRoll()' in dem Interface 'doBarrelRoll' anspricht.
Und eine Custom Klasse implementiert 'doBarrelRoll'.
Entweder bin ich zu müde um das hinzubekommen, oder ich bin einfach zu müde;
Man man man,
was für ein Tag.. irgendwie geht Heute nichts.
Selbst auf der Arbeit kam ich irgendwie zu nichts ... plötzlich war meine kompletter workspace weg und musste erstmal alles neu einrichten ...
Nun denn, ich hab das Problem lösen können.
Java:
public class ToolBar implements ActionListener{
private List<FileEvent> responder;
public ToolBar(){
this.responder = new ArrayList<FileEvent>();
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand().equals("Neu"))
for(FileEvent fe : responder)
fe.newGame();
}
public void addActionListener(FileEvent e) {
responder.add(e);
}
public interface FileEvent{
public void saveGame();
public void newGame();
public void loadGame();
}
}
Java:
public class Custom implements FileEvent{
private ToolBar tb;
public Custom() {
tb = new ToolBar();
tb.addActionListener(this);
}
}
Letzte Frage wäre, wäre es möglich die 'List<FileEvent>', sowie 'addActionListener()' in eine eigene Klasse zu verschieben?
Zum Verwalten aller Events?
1) grundlegend sollte man in java alles was mit events zu tun hat (auch NICHT-gui events) von java.util.EventObject sowie von java.util.EventListener ableiten ... das ist die sog. Event-Handling-API
2) ich verstehe überhaupt nicht was du am anfang mit "static" wolltest ...
in einem normalen projekt gibt es (abgesehen von factories / singleton und utilities) nur EIN static ... und das ist MAIN ...
3) hast du schon mal was von den "Java Coding Conventions" gehört ? das solltest du dir mal googlen .. denn deine bezeichner und klassen-namen gehen mal überhaupt nicht ...
4) es heißt "Do A Barrel Roll"
5) "public class X implements ActionListener" macht man überhaupt nicht ... oder soll deine klasse ein nach außen hin öffentlicher ActionListener sein ? ich glaube wohl kaum ... dafür nutzt man "inner anonymous classes" > google
6) entkopplung vom EDT
normalerweise steckt man den code der innerhalb von irgendwelchen Listener-methoden abläuft (gerade GUI-listener) in threads um den caller-thread nicht zu blockieren ... denn events sollten grundsätzlich a-synchron laufen ... wenn es synchron sein soll braucht man kein event .. dann callt man die methode direkt ...
die fehlen noch sehr viele grundlagen ... und du versuchst gerade merhere grundlagen-bereiche mit ein ander zu verbinden von denen dein kenntnis-stand bei jedem einzelnen bereich nicht weiter geht als : hab ich mal gehört ...
du solltest schritt-für-schritt erstmal grundlagen lernen ... und dann später wie man diese verbindet ... das was du hier machst dürfte am ende in einem einzigen haufen code-wirrwarr enden durch den keiner mehr durchblickt ...
denn alleine ein nested interface zu deklarieren ... aber dies von außen implementieren wollen ... ich weis nicht mal ob das geht ... kann es mir aber erlich gesagt nicht vorstellen ...
5) nein ... so nicht direkt ... ich versuch es mal so zu erklären
wenn du an eine public class "implements WhatEver" dranhängst machst du diese klasse damit nach außen hin zu einem typ dieses interfaces ... das ist sinnvoll bei z.b. Runnable da man nicht direkt von Thread erben sollte (frag bitte nicht warum , hab dazu mal ne super erklärung gelesen die es verständlich gemacht hat) ... aber gerade bei allen Listener-interfaces aus java.awt.event sollte man das strikt vermeiden ... denn du willst deine klasse sicherlich nicht für alle anderen als z.b. einen ActionListener zur verfügung stellen ... oder ?
das macht in den wenigstens fällen sinn (eigentlich überhaupt nicht) und ist eher schlechtes design ...
es gibt natürlich auch noch ganz andere interfaces bei denen es sogar teilweise nötig ist ... aber das wäre eine andere geschichte ...
fakt ist : man sollte bei allen java.awt.event.XXXListener interfaces auf ein public implements verzichten und stattdessen mit anonymen inner classes arbeiten ... ein einfaches beispiel würde so aussehen :
was so , in anbetracht von 6) noch nicht so optimal ist ... aber schon deutlich besser als an die klasse oben "implements ActionListener" dran zu tackern ...
außerdem hat es den vorteil das man nicht prüfen muss von welchem element das ActionEvent ausgelöst wurde da dieser spezifische Listener nur an dem JButton hängt ... und so zumindest weis das event.getSource() dem JButton entspricht ...
6) die entkopplung vom EDT , oder generell die entkopplung des event-handlings vom event-produzierenden thread , ist in soweit wichtig da der thread welcher das event erzeugt alle an ihm registrierten listener lediglich informieren soll das ein event aufgetreten ist und dabei eventuell daten übergibt ...
bei GUI-listenern und dem EDT äußert sich dieses phänomen z.b. dadurch das wenn im listener direkt eine lange I/O-ops abläuft die GUI während dieser zeit "freezed" und man auf die abarbeitung warten muss ...
lagert man dies nun in einen extra thread aus läuft die I/O-ops im hintergrund und man kann die GUI weiterhin bedienen ... z.b. einen lade-balken anziegen ...
die einfache variante (um am beispiel von oben weiter zu machen) würde in etwa so aussehen :
Java:
JButton jButton=new JButton("Button");
jButton.add(new ActionListener() {
public void actionPerformed(ActionEvent event)
{
(new Thread(new Runnable() {
public void run()
{
// TO-DO
}
})).start();
}
});
somit wird die aktion im listener vom EDT entkoppelt und freezed die GUI nicht während einer längeren I/O-ops ...
das ist einer der beliebtesten anfänger-fehler von leuten die neu in GUI-programmierung sind und sich dann wundern warum die GUI freezed und das ergebnis erst am ende sichtbar wird obwohl doch alles schön programmiert ist ... das sog. BLOCK des EDT ist dafür verantwortlich ... weil der EDT nicht nur die events aufnimmt und weiterleitet sondern auch für das neu-zeichnen der GUI verantwortlich ist ...
allerdings ist gerade bei swing folgendes zu beachten : GUI-veränderungen dürfen NUR vom EDT vorgenommen werden ...
wie aber macht man das jetzt korrekt ? nun .. dafür wird weiter geschachtelt :
Java:
JButton jButton=new JButton("Button");
jButton.add(new ActionListener() {
public void actionPerformed(ActionEvent event)
{
(new Thread(new Runnable() {
public void run()
{
SwingUtilities.invokeLater(new Runnable() {
public void run()
{
// TO-DO
}
});
}
})).start();
}
});
soll der thread noch darauf warten das der EDT die änderungen übernommen hat ersetzt man invokeLater() durch invokeAndWait() ...
ein arbeitskollege der aus dem urlaub kam, konnte mir das mit custom eventlistener/eventhandler/eventinterface doch recht erklären.
wenn ich das richtig verstehe könnte ich dann in einer 'init()' einen (ich sag mal plain) 'EventHandler' initialisieren, und in die 'actionPerformed()' im 'invokedLater' Thread auf die 'EventHandler' variable zugreifen und eine methode ausführen und diese läuft dann in dem thread?
mir gefallen diese verschachtelten actionlistener nicht so ganz, nun denn, geschmackssache.