schön dass Du mir helfen willst – sorry erstma wegen der verpatzen Codewiedergabe – aber vielleicht kannstes ja einfach kopieren.
Also:
Der Titel sagts ja schon “Reihenfolge der listeners ändern”
Im Quelltext dann, 2 listener, der erste wird aber zuerst aufgerufen — ist bei allen swing-listeners so — macht für mich keinen Sinn und für mein Vorhaben ist das sehr hinderlich — Für mich ist die Frage: ob man die Reihenfolge der Aufrufe umdrehen kann. Würde von allein denken dass der erste Listener zuerst aufgerufen wird – das ist leider nicht so ;-(
Hi Klaus – das ist lediglich ein Beispielcode, der das Prinzip vereinfachen soll(es geht letztendlich um das Binding einer Variable - was aber eigentlich gar nichts zur Sache tun)
Grundsätzlich gehe ich als Programmierer davon aus das der erste implementierte Listener auch als erstes ausgeführt wird --> das ist leider nicht so --> siehe funktionierendes Beispiel
//Warum zweimal den exakt gleichen Listener am gleichen Textfeld
Stell Dir vor das ganze ist vererbt und Listener 1 ist Grundfunktionalität - Listener 2 baut jemand der die Komponente verwenden will
Mit Listenern ist das so eine Sache, weil die gemultiplexed werden, wobei eigentlich gar keine Reihenfolge festgelegt werden kann, soweit ich weiß.
Den Listener würde ich mit
super.addDocumentListener(myListener);
bei der Klasseninitialisierung übergeben und die Methode in der Klasse überschreiben (nebst “removeDocumentListener()”). Die durch diese Methode geaddeten Listener würde ich dann in einer Liste speichern, die von deinem Listener abgearbeitet wird, sobald er mit den Grundfunktionen durch ist.
Allerdings muss ich dazu sagen, dass mir das spanisch vorkommt, denn Komponenten verändert man nicht über Listener, sondern direkt. Listener sind dann nur dazu da, registrierte Programmabschnitte über diese Änderungen zu informieren, ohne dass Letztere noch etwas daran ändern können sollten.
genau überlegen, ob du das wirklich willst. Warum spielt die Reihenfolge eine Rolle? Man kann oder sollte sich nicht darauf verlassen. Wenn die Reihenfolge eine Rolle spielt, sollte man eine andere Lösung in Betracht ziehen.
Die gedengelte Lösung wäre das hier - nicht schön:
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.AbstractDocument;
import javax.swing.text.Document;
public class TestWeg {
public static void main(String[] args) {
// Frame
JFrame myFrame = new JFrame("test");
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.setBounds(100, 100, 450, 180);
myFrame.setVisible(true);
// Panel
JPanel myPanel = new JPanel();
myPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
myFrame.setContentPane(myPanel);
myPanel.setLayout(null);
// Elements
// -------------------------------------------------------
JLabel myLabelFN = new JLabel("The Text");
myPanel.add(myLabelFN);
myLabelFN.setBounds(25, 28, 76, 14);
myLabelFN.setVisible(true);
JTextField myTF = new JTextField();
myPanel.add(myTF);
myTF.setBounds(100, 25, 300, 20);
myTF.setVisible(true);
addAsFirst(myTF.getDocument(), new DocumentListener() {
@Override
public void changedUpdate(DocumentEvent e) {
changeIt();
} // end changedUpdate()
public void removeUpdate(DocumentEvent e) {
changeIt();
} // end removeUpdate()
public void insertUpdate(DocumentEvent e) {
changeIt();
} // end insertUpdate()
public void changeIt() {
System.out.println("Erste Änderung");
} // end changeIt()
} // end new
);
addAsFirst(myTF.getDocument(), new DocumentListener() {
@Override
public void changedUpdate(DocumentEvent e) {
changeIt();
} // end changedUpdate()
public void removeUpdate(DocumentEvent e) {
changeIt();
} // end removeUpdate()
public void insertUpdate(DocumentEvent e) {
changeIt();
} // end insertUpdate()
public void changeIt() {
System.out.println("Zweite Änderung");
} // end changeIt()
} // end new
);
} // end main()
private static void addAsFirst(
Document document, DocumentListener documentListener)
{
if (document instanceof AbstractDocument)
{
AbstractDocument abstractDocument = (AbstractDocument)document;
DocumentListener[] oldListeners =
abstractDocument.getListeners(DocumentListener.class);
for (DocumentListener oldListener : oldListeners)
{
document.removeDocumentListener(oldListener);
}
document.addDocumentListener(documentListener);
for (DocumentListener oldListener : oldListeners)
{
document.addDocumentListener(oldListener);
}
}
}
} // end TestWeg
Also, ich denke auch, dass deine Architektur daneben ist, aber falls du sowas wirklich brauchst, wäre es auch eine Möglichkeit, einen “Über-Listener” zu schreiben, der deine Listener in Reihenfolge aufnehmen kann:
public class MasterListener implements DocumentListener {
private List<DocumentListener> subListeners = new ArrayList<>();
public void addListener(DocumentListener listener) { subListeners.add(listener); }
@Override
public void changeUpdate(DocumentEvent e) {
subListeners.forEach(l -> l.changeUpdate(e));
}
...
}
Natürlich musst du dann deine Listener dort und nur dort registrieren. Aber noch mal zur Warnung:
Warum die Warnung? Das ist ziemlich genau das, was ich bei
im Kopf hatte. Das gepostete ist halt die „generischste“ Form, d.h. das public class sollte in der Praxis bestenfalls ein class sein. Aber ansonsten: Wenn man die Reihenfolge berücksichtigen muss, dann muss irgendeine übergeordnete Instanz dafür sorgen, dass sie berücksichtigt wird …