इसका सामान्य उत्तर "उपयोग DocumentListener
" है। हालांकि, मुझे हमेशा वह इंटरफ़ेस बोझिल लगता है। सच में इंटरफ़ेस अति-इंजीनियर है। पाठ के सम्मिलन, हटाने और प्रतिस्थापन के लिए इसकी तीन विधियाँ हैं, जब इसे केवल एक विधि की आवश्यकता होती है: प्रतिस्थापन। (एक सम्मिलन को कुछ पाठ के साथ बिना पाठ के प्रतिस्थापन के रूप में देखा जा सकता है, और एक निष्कासन को इस पाठ के साथ कुछ पाठ के प्रतिस्थापन के रूप में देखा जा सकता है।)
आमतौर पर आप जो भी जानना चाहते हैं वह यह है कि जब बॉक्स में पाठ बदल गया है , तो एक विशिष्ट DocumentListener
कार्यान्वयन में तीन विधियों को एक विधि कहा जाता है।
इसलिए मैंने निम्नलिखित उपयोगिता विधि बनाई, जो आपको एक के ChangeListener
बजाय एक सरल उपयोग करने देता है DocumentListener
। (यह जावा 8 के लैम्ब्डा सिंटैक्स का उपयोग करता है, लेकिन यदि आवश्यक हो तो आप इसे पुराने जावा के लिए अनुकूलित कर सकते हैं।)
/**
* 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);
}
दस्तावेज़ में सीधे श्रोता को जोड़ने के विपरीत, यह (असामान्य) मामले को संभालता है जो आप एक पाठ घटक पर एक नया दस्तावेज़ ऑब्जेक्ट स्थापित करते हैं। इसके अतिरिक्त, यह जीन-मार्क एस्टेसाना के उत्तर में वर्णित समस्या के आसपास काम करता है , जहां दस्तावेज़ कभी-कभी ज़रूरत से ज़्यादा घटनाओं को आग लगा देता है।
वैसे भी, यह विधि आपको कष्टप्रद कोड को बदलने देती है जो इस तरह दिखता है:
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();
}
});
साथ में:
addChangeListener(someTextBox, e -> doSomething());
सार्वजनिक डोमेन के लिए जारी किया गया कोड। मज़े करो!