Jawaban yang biasa untuk ini adalah "gunakan a DocumentListener
". Namun, saya selalu menemukan antarmuka yang rumit. Sejujurnya antarmuka over-engineered. Ini memiliki tiga metode, untuk penyisipan, penghapusan, dan penggantian teks, ketika hanya membutuhkan satu metode: penggantian. (Penyisipan dapat dilihat sebagai pengganti tanpa teks dengan beberapa teks, dan penghapusan dapat dilihat sebagai penggantian beberapa teks tanpa teks.)
Biasanya yang Anda inginkan adalah mengetahui kapan teks dalam kotak telah berubah , jadi ini tipikalDocumentListener
implementasi memiliki tiga metode yang memanggil satu metode.
Karena itu saya membuat metode utilitas berikut, yang memungkinkan Anda menggunakan yang lebih sederhana ChangeListener
daripada DocumentListener
. (Menggunakan sintaks Java 8, tetapi Anda dapat mengadaptasinya untuk Java lama jika diperlukan.)
/**
* Installs a listener to receive notification when the text of any
* {@code JTextComponent} is changed. Internally, it installs a
* {@link DocumentListener} on the text component's {@link Document},
* and a {@link PropertyChangeListener} on the text component to detect
* if the {@code Document} itself is replaced.
*
* @param text any text component, such as a {@link JTextField}
* or {@link JTextArea}
* @param changeListener a listener to receieve {@link ChangeEvent}s
* when the text is changed; the source object for the events
* will be the text component
* @throws NullPointerException if either parameter is null
*/
public static void addChangeListener(JTextComponent text, ChangeListener changeListener) {
Objects.requireNonNull(text);
Objects.requireNonNull(changeListener);
DocumentListener dl = new DocumentListener() {
private int lastChange = 0, lastNotifiedChange = 0;
@Override
public void insertUpdate(DocumentEvent e) {
changedUpdate(e);
}
@Override
public void removeUpdate(DocumentEvent e) {
changedUpdate(e);
}
@Override
public void changedUpdate(DocumentEvent e) {
lastChange++;
SwingUtilities.invokeLater(() -> {
if (lastNotifiedChange != lastChange) {
lastNotifiedChange = lastChange;
changeListener.stateChanged(new ChangeEvent(text));
}
});
}
};
text.addPropertyChangeListener("document", (PropertyChangeEvent e) -> {
Document d1 = (Document)e.getOldValue();
Document d2 = (Document)e.getNewValue();
if (d1 != null) d1.removeDocumentListener(dl);
if (d2 != null) d2.addDocumentListener(dl);
dl.changedUpdate(null);
});
Document d = text.getDocument();
if (d != null) d.addDocumentListener(dl);
}
Berbeda dengan menambahkan pendengar langsung ke dokumen, ini menangani kasus (tidak umum) yang Anda instal objek dokumen baru pada komponen teks. Selain itu, ia bekerja di sekitar masalah yang disebutkan dalam jawaban Jean-Marc Astesana , di mana dokumen itu terkadang menembakkan lebih banyak peristiwa daripada yang diperlukan.
Bagaimanapun, metode ini memungkinkan Anda mengganti kode yang menjengkelkan yang terlihat seperti ini:
someTextBox.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
doSomething();
}
@Override
public void removeUpdate(DocumentEvent e) {
doSomething();
}
@Override
public void changedUpdate(DocumentEvent e) {
doSomething();
}
});
Dengan:
addChangeListener(someTextBox, e -> doSomething());
Kode dirilis ke domain publik. Selamat bersenang-senang!