listener kennt benötigte instanz doch garnacht
-
wenn ich zum Beispiel eine Klasse ferngesteurtesAuto habe, die wiefolgt aussieht:
[java]
class ferngesteurtesAuto
{
ferngesteurtesAuto()
{
//lade Baterie über hauseigennen Kernreaktor auf
}
drive()
{
// Auto fährt irendwo hin
}
}[/code]und eine Klasse itemListing die so aussieht:
[java]
class itemListing implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
; // wird eh jedesmal überschrieben
}
}[/code]jetzt Fehlt noch ein Menü, dass als Fernsteuerng für das Auto dient:
[java]
m = new JMenu("Fernsteuerng");
mi = new JMenuItem("fahr los");
mi.addActionListener(new itemListing()
{
public void actionPerformed(ActionEvent e)
{
// hier leigt das problem
}
});
m.add(mi);[/code]von der klasse ferngesteurtesAuto wird selbstverständlich irgendwo noch eine instance gebildet.
Mein Problem ist jetzt eigendlich, dass über das Menuitem mi die methode drive() der ferngesteurtesAuto-Instance aufgerufen werden soll, aber die Überladene Methode actionPerformed diese ferngesteurtesAuto-Instance nicht kennt.
[ Dieser Beitrag wurde am 03.05.2003 um 10:16 Uhr von stevg editiert. ]
-
hi, du brauchst keine 2 ActionListener..
mi.addActionListener(new itemListing());
würde zB genügen, eine anonyme Klasse brauchst du daras nicht mehr abzuleiten..
oder du läßt die ItemListing - Klasse weg und leitest direkt von ActionListener ab:
mi.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { // hier leigt das problem } });
in actionPerformed kann dein Programm sehr wohl über das ferngesteuerte Auto wissen...du mußt einfach nur eine Referenz davon in der selben Klasse haben oder falls du das 2. Beispiel von oben mit einer anonymen Klasse verwendest, reicht es sogar schon wenn die übergeordnete Klasse ne Referenz drauf hat..
wenn du ne Extra-Klasse für den ActionListner verwendest kannst du es so machen, daß im Konstruktor ne Referenz aufs Auto übergeben wird...
class ItemListing implements ActionListener { private FerngesteuertesAuto auto; public ItemListing(FerngesteuertesAuto auto) { this.auto=auto; } public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals("fahr los") auto.drive(); } }
-
ItemListing wollte ich auch für andere menü elemente verwenden. also das ich eine klasse für alle items nehme und die actionPerformed entsprechend überschreibe, sodass actionPerformed mal auf eine auto, mal auf ein flugzeug oder mal auf raketensilo zugreift.
ich hatte diese problem erst mit einer sogenaten runtimeManger-Klasse gelöst. eine instanz dieser klasse besitz alle benötigeten referenzen auf die instanzen der auto,flugzeug und raketensilo klasse. dann besitzt sie z.B eine Methode
[java]
void driveCar()
{
this.carRef.drive();
} [/code]
die halt das entsprechende auto fahren lässt.die itemListing klasse würde dann so aussehen:
[java]
class itemListing implements ActionListener
{
runtimeManger rm;
itemListing(runtimeManger rm)
{
this.rm = rm;
}
public void actionPerformed(ActionEvent e)
{
; // wird eh jedesmal überschrieben
}
}[/code]und die überladene actionPerformed für die autofernbedienung so:
[java]
mi.addActionListener(new itemListing()
{
public void actionPerformed(ActionEvent e)
{
this.rm.driveCar();
}
});[/code]oder für das flugzeug so:
[java]
mi2.addActionListener(new itemListing()
{
public void actionPerformed(ActionEvent e)
{
this.flugzeugRef.fly();
}
});[/code]das problem hierbei ist, das man bei einem menü mit 10-20 Items schnell den überblick im code verliert. Gibt es nicht noch irgendwie eine 'saubere' Lösung ?
-
da gibts sicher einige Möglichkeiten, man könnt zB die Items (autos, Raktensilos whatever) selber ActionListener implementieren lassen, je nachdem welches ActionCommand ankommt ruft man dann einfach Methoden der eigenen Klasse auf
class Auto extends Irgendwas implements ActionListener { ... public void drive() { blabalba } public void actionPerformed(ActionEvent ae) { String cmd=ae.getActionCommand(); if (cmd.equals("drive")) drive(); .. } } ... Auto myCar=new Auto(); .. m = new JMenu("Fernsteuerng"); mi = new JMenuItem("fahr los"); mi.setActionCommand("drive"); mi.addActionListener(myCar);
für jede Klasse dann einen ActionListener implementen..
[ Dieser Beitrag wurde am 03.05.2003 um 16:32 Uhr von crass editiert. ]
-
diese herrangehensweise gefällt mir.
da die jeweilige actionPerformed an die passende klasse gebunden ist, wird der code wesentlich übersichlicher. danke