Swing监视未保存的更改

时间:2014-11-06 12:12:06

标签: java swing

我开发了一个由12个 JPanels 组成的图形界面,每个界面包含4到10个 JTextFields。 我希望实现 unsaved-changes-warning ,以防用户更改某些JTextField的内容,但未将更改提交到数据库。

如何实现这一目标? 我的第一个想法是使用 ItemListener 并注册所有JTextFields。我可以为每个面板存储一个变量 boolean unsavedChanges ,并检查所有面板是否都为假。

您能想象另一种更有效的解决方案吗?

1 个答案:

答案 0 :(得分:3)

您有两种选择。

  1. 您可以在每个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);
        }
    }
    
  2. 您可以保存文本字段中显示的原始值,因为您可以在地图中的数据库中获取这些值。检查面板时,必须将文本字段的内容与原始值进行比较。

  3. 修改

    要收集每个文本字段的更改信息,您可以使用这样的类。您在框架中创建一个实例并将其传递给所有面板。

    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);
        }
    }