我开发了一个由12个 JPanels 组成的图形界面,每个界面包含4到10个 JTextFields。 我希望实现 unsaved-changes-warning ,以防用户更改某些JTextField的内容,但未将更改提交到数据库。
如何实现这一目标? 我的第一个想法是使用 ItemListener 并注册所有JTextFields。我可以为每个面板存储一个变量 boolean unsavedChanges ,并检查所有面板是否都为假。
您能想象另一种更有效的解决方案吗?
答案 0 :(得分:3)
您有两种选择。
您可以在每个JTextField的文档上注册DocumentListener。
textField.getDocument().addDocumentListener(documentListener)
缺点:即使用户已将值更改为原始值,文本字段也会标记为已更改。要处理此问题,您可以将原始值保存在自己的文档侦听器中,并将新值与其进行比较。方法hasChanged()为您提供所需信息。
import javax.swing.event.*;
import javax.swing.text.*;
public class DocumentChangeListener implements DocumentListener {
private boolean changed;
private final String originalValue;
public DocumentChangeListener(String originalValue) {
this.originalValue = originalValue;
}
protected void changed(DocumentEvent e) {
if (e.getDocument() instanceof PlainDocument) {
PlainDocument doc = ((PlainDocument)e.getDocument());
try {
String value = doc.getText(0, doc.getLength());
changed = originalValue == null || !originalValue.equals(value);
} catch(BadLocationException exc) {
exc.printStackTrace();
}
}
}
public void changedUpdate(DocumentEvent e) {
changed(e);
}
public boolean hasChanged() {
return this.changed;
}
public void insertUpdate(DocumentEvent e) {
changed(e);
}
public void removeUpdate(DocumentEvent e) {
changed(e);
}
}
您可以保存文本字段中显示的原始值,因为您可以在地图中的数据库中获取这些值。检查面板时,必须将文本字段的内容与原始值进行比较。
修改强>
要收集每个文本字段的更改信息,您可以使用这样的类。您在框架中创建一个实例并将其传递给所有面板。
import java.util.*;
import javax.swing.text.*;
public class ChangeManager {
private final Collection<DocumentChangeListener> listeners;
public ChangeManager() {
listeners = new HashSet<>();
}
public boolean hasChanged() {
for(DocumentChangeListener listener : listeners) {
if(listener.hasChanged()) {
return true;
}
}
return false;
}
public void register(JTextComponent textComponent, String originalValue) {
DocumentChangeListener listener = new DocumentChangeListener(
originalValue);
textComponent.getDocument().addDocumentListener(listener);
listeners.add(listener);
}
}