2017-09-22 1 views
0

Ich habe folgendes Problem:hinzufügen Action zu unbekannten Objekt

Ich habe eine Funktion wie folgt aus:

public void addActionListenerObject(Object object) { 
    object.addActionListener(this); 
} 

Mein Problem ist folgendes: Ich brauche eine Lösung, wo ich mit der jedes Objekt passieren kann addActionListener-Funktion als Parameter. Die Liste finden Sie hier: https://docs.oracle.com/javase/tutorial/uiswing/events/eventsandcomponents.html

Gibt es eine Möglichkeit, dieses Problem ohne zahlreiche Instanzen zu lösen?

Dank

+0

was 'this' Klassendefinition? erweitert/implementiert welche Klassen/Interfaces? –

+0

'this' ist ein ActionListener – qry

Antwort

1

Keeping Unterschrift

Wenn Sie Ihre Methodensignatur nicht ändern kann (dh, wenn Sie einen Object erhalten müssen, und addActionListener() nennen, wenn es ein solches Verfahren Definition ist), eine allgemeinere/robuste Lösung wäre mit Java Reflections, um zu überprüfen, ob das aktuelle Objekt eine addActionListener()-Methode definiert hat, und diese auch über Reflektionen aufrufen. Klingt sowieso sehr hacky.

ändern Signature

Wenn Sie Ihre Methodensignatur ändern können, versuchen AbstractButton (https://docs.oracle.com/javase/7/docs/api/javax/swing/AbstractButton.html#addActionListener(java.awt.event.ActionListener)) verwendet wird, welche die übergeordnete Klasse ist, die diese Methode für JButton definiert, JToggleButton und JMenuItem, zum Beispiel (siehe „Direct bekannt Subklassen "und der Klassendefinitionsbaum, um herauszufinden, wo die Methoden tatsächlich bereitgestellt werden."

Dieser zweite Ansatz funktioniert nur, wenn es tatsächlich eine einzige Superklasse gibt, die die Methode definiert. Wenn es mehr als einen gibt, müssen Sie nach den möglichen Klassen suchen, indem Sie if-else structure und instanceof + explizite Besetzung verwenden (als Sie Ihre ursprüngliche Object Signatur behalten können).

Wenn Sie mehr Informationen zu Ihrem ursprünglichen Problem (wie, warum brauchen Sie eine solche Methode), werden wir wahrscheinlich in der Lage sein, bessere Ansätze zu finden.

+0

Also der Ansatz mit dem AbstractButton ist einer, den ich schon gemacht habe, aber er verdeckt die anderen Objekte nicht. Die Reflection-Methode ist wahrscheinlich die beste, aber die Performance könnte ein Problem sein. Ich brauche die Methode, um mehrere Aktion Listener in eine Bibliothek von mir zu verpacken ... Um ehrlich zu sein, ich könnte nur den Benutzer mein Objekt als ActionListener hinzufügen, aber es fühlt sich nicht richtig an. Die if-else-Struktur ist wahrscheinlich der beste Ansatz ... – qry

+0

Die Reflektionsmethode ist robuster, da jede dritte oder zukünftige Klasse, die die Methode 'addActionListener (...) 'implementiert, ohne Codeänderung arbeitet. Auf der anderen Seite, wenn die Wahrscheinlichkeit, dass die Methode so robust sein muss, niedrig ist (was bedeutet, dass die wahrscheinliche Verwendung mit einer engen Menge von Klassen einschließlich AbstractButton usw. erfolgt), und die Wartbarkeit von Leistung und Code sind wichtigere Anforderungen, I ' d wähle den "if-else" -Ansatz. Wie immer hängt die beste Wahl vom Gesamtbild Ihres tatsächlichen Problems ab. ;) –

0

Was Sie suchen ist Polymorphismus. Alle Instanzen des Typs Component haben die addActionListener Methode. Ändern Sie Ihre Methodensignatur, um eine Component, nicht eine Object zu erwarten.

Ich dachte addActioListener wurde von Component geerbt. Es ist nicht. Die Methode wird einzeln jedem Komponententyp ohne übergeordnete Klasse hinzugefügt.

+0

Die Klassenkomponente hat nicht die Funktion addActionListener. Ich hatte die gleiche Idee, aber ich suche die richtige Klasse und kann sie nicht finden. – qry

+0

Siehe meine Bearbeitung. Ihre beste Wette ist es, für jeden benötigten Typ individuelle Methoden zu schreiben. – Strikegently

1

Pass eine funktionale Schnittstelle (> = Java 1.8 nur), wenn Sie die Unterschrift von addActionListenerObject ändern dürfen:

 
public class Just { 
    private ActionListener actionListener; 
    public void addActionListener(ActionListener actionListener) { 
     this.actionListener = actionListener; 
    } 
    public void doIt() { 
     System.out.println("Hello"); 
     actionListener.actionPerformed(new ActionEvent(this, 3, "World")); 
    } 
} 

public class MyActionListener implements ActionListener { 
    public void addActionListenerObject(Consumer<ActionListener> consumer) { 
     consumer.accept(this); 
    } 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     System.out.println(e.getActionCommand()); 
    } 
} 

Auf diese Weise sind die Klassen, die die Aktion Hörer (in meinem Beispiel hinzufügen, das ist Just) müssen keine Schnittstelle implementieren.

es verwenden:

 
Just just = new Just(); 

MyActionListener listener = new MyActionListener(); 
listener.addActionListenerObject(just::addActionListener); // Aha! 

just.doIt(); 

Diese Drucke:

 
Hello 
World 
Verwandte Themen