【问题标题】:Swing monitor unsaved changesSwing 监视器未保存的更改
【发布时间】:2014-11-06 12:12:06
【问题描述】:

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

如何做到这一点? 我的第一个想法是使用 ItemListener 并注册所有 JTextField。我可以为每个面板存储一个变量 boolean unsavedChanges 并检查所有面板是否为假。

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

【问题讨论】:

标签: java swing


【解决方案1】:

你有两个选择。

  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. 您可以保存在文本字段中显示的原始值,因为您从地图或类似的数据库中获取它们。检查面板时,您必须将文本字段的内容与原始值进行比较。

编辑

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

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

【讨论】:

  • 感谢您的全面回答。我仍然不确定如何通过一堆 Jpanels 将更改的信息传递到 MainClass JFrame。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-30
  • 1970-01-01
  • 2012-03-18
  • 1970-01-01
  • 1970-01-01
  • 2011-12-20
相关资源
最近更新 更多