To jest mój kod:Dlaczego JTextField.setText uruchomi removeUpdate() DocumentListener przed changeUpdate()?
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.Document;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Frame extends JFrame {
private JTextField txt1 = new JTextField(10);
private JTextField txt2 = new JTextField(10);
private JButton btn = new JButton("Set Text");
public Frame() {
super("Latihan");
setLayout(new FlowLayout());
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
txt1.setText("TEST"); txt2.setText("TEST2");
}
});
txt1.getDocument().addDocumentListener(new TheDocumentListener("txt1"));
txt2.getDocument().addDocumentListener(new TheDocumentListener("txt2"));
add(txt1);
add(txt2);
add(btn);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
public static void main (String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Frame();
}
});
}
}
class TheDocumentListener implements DocumentListener {
private String source;
public TheDocumentListener(String source) {
this.source = source;
}
@Override
public void insertUpdate(DocumentEvent e) {
System.out.println("insertUpdate from " + source);
}
@Override
public void removeUpdate(DocumentEvent e) {
System.out.println("removeUpdate from " + source);
}
@Override
public void changedUpdate(DocumentEvent e) {
System.out.println("changedUpdate from " + source);
}
}
Kiedy klikam na JButton po raz pierwszy, tylko insertUpdate()
będzie nazwane:
insertUpdate from txt1
insertUpdate from txt2
Ale gdybym ponownie kliknij przycisk, removeUpdate()
zostanie wywołana przed insertUpdate()
:
removeUpdate from txt1
insertUpdate from txt1
removeUpdate from txt2
insertUpdate from txt2
jest to oczekiwane zachowanie lub coś złego w moim kodu?
Czy mogę wykonać insertUpdate
jedyną metodę, która została wywołana podczas wykonywania JTextField.setText
? Chcę się upewnić, że wywoływana jest removeUpdate
tylko wtedy, gdy użytkownik usunie tekst w polu tekstowym. Jak to zrobić?
Powodem jest symulacja wiązania JTextField, ponieważ metoda setText() nie jest powiązana. Jeśli chodzi o wzajemne powiązanie, powinno być: zmiana na inną powiązaną właściwość będzie propagowana do JTextField.text; i wywołanie JTextField.text powinno być propagowane do właściwości bound. Ale to, co naprawdę się stało, to zmiana na JTextField.text czasami wyzwala 1 lub 2 zdarzenia detektora dokumentów i ciężko jest zdecydować, kiedy przerwać wzajemne wiązanie. – jocki