Đây là mã của tôi:Tại sao JTextField.setText sẽ kích hoạt removeUpdate() của DocumentListener trước khi changedUpdate()?
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);
}
}
Khi tôi bấm vào JButton cho lần đầu tiên, chỉ insertUpdate()
sẽ được gọi là:
insertUpdate from txt1
insertUpdate from txt2
Nhưng nếu tôi nhấp vào nút một lần nữa, removeUpdate()
sẽ được gọi trước insertUpdate()
:
removeUpdate from txt1
insertUpdate from txt1
removeUpdate from txt2
insertUpdate from txt2
Đây có phải là hành vi mong đợi hoặc có điều gì đó sai trong mã của tôi không?
Tôi có thể đặt insertUpdate
phương thức duy nhất được gọi khi thực hiện JTextField.setText
không? Tôi muốn đảm bảo rằng removeUpdate
chỉ được gọi khi người dùng xóa văn bản trong trường văn bản. Làm thế nào để làm điều đó?
Lý do là để mô phỏng ràng buộc JTextField vì setText() không bị ràng buộc. Khi nói đến liên kết lẫn nhau, nó phải là: thay đổi sang thuộc tính ràng buộc khác sẽ được truyền tới JTextField.text; và gọi đến JTextField.text nên được truyền tới thuộc tính bị ràng buộc. Nhưng những gì thực sự xảy ra bây giờ là thay đổi để JTextField.text đôi khi sẽ cháy 1 hoặc 2 sự kiện nghe tài liệu và thật khó để quyết định khi nào để ngăn chặn các ràng buộc lẫn nhau. – jocki