Java Swing monitor未保存的更改

Java Swing monitor未保存的更改,java,swing,Java,Swing,我开发了一个图形界面,由12个JPanel组成,每个JPanel包含4到10个JTextFields。 我想实现一个未保存的更改警告,以防用户更改了某些JTextFields的内容,但没有将更改提交到数据库。 如何做到这一点? 我的第一个想法是使用itemstener并注册所有JTextFields。我可以为每个面板存储一个变量boolean unsavedChanges,并检查所有面板是否为false 你能想象另一种可能更有效的解决方案吗?你有两种选择 您可以在每个JTextField的文档上

我开发了一个图形界面,由12个JPanel组成,每个JPanel包含4到10个JTextFields。 我想实现一个未保存的更改警告,以防用户更改了某些JTextFields的内容,但没有将更改提交到数据库。

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

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

你有两种选择

  • 您可以在每个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);
        }
    }
    
    import java.util.*;
    导入javax.swing.text.*;
    公共类变更管理器{
    私人最终收集听众;
    公共事务经理(){
    侦听器=新的HashSet();
    }
    公共布尔值已更改(){
    for(DocumentChangeListener侦听器:侦听器){
    if(listener.hasChanged()){
    返回true;
    }
    }
    返回false;
    }
    公共无效寄存器(JTextComponent textComponent,字符串原始值){
    DocumentChangeListener=新建DocumentChangeListener(
    原始值);
    textComponent.getDocument().addDocumentListener(listener);
    添加(侦听器);
    }
    }
    
    您有两个选择

  • 您可以在每个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);
        }
    }
    
    import java.util.*;
    导入javax.swing.text.*;
    公共类变更管理器{
    私人最终收集听众;
    公共事务经理(){
    侦听器=新的HashSet();
    }
    公共布尔值已更改(){
    for(DocumentChangeListener侦听器:侦听器){
    if(listener.hasChanged()){
    返回true;
    }
    }
    返回false;
    }
    公共无效寄存器(JTextComponent textComponent,字符串原始值){
    DocumentChangeListener=新建DocumentChangeListener(
    原始值);
    textComponent.getDocument().addDocumentListener(listener);
    添加(侦听器);
    }
    }
    
    您有两个选择

  • 您可以在每个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);
        }
    }
    
    import java.util.*;
    导入javax.swing.text.*;
    公共类变更管理器{
    私人最终收集听众;
    公共事务经理(){
    侦听器=新的HashSet();
    }
    公共布尔值已更改(){
    for(DocumentChangeListener侦听器:侦听器){
    if(listener.hasChanged()){
    返回true;
    }
    }
    返回false;
    }
    公共无效寄存器(JTextComponent textComponent,字符串原始值){
    DocumentChangeListener=新建DocumentChangeListener(
    原始值);
    textComponent.getDocument().addDocumentListener(listener);
    添加(侦听器);
    }
    }
    
    您有两个选择

  • 您可以在每个JTextField的文档上注册DocumentListener

    textField.getDocument().addDocumentListener(documentListener)

    缺点:即使用户已将值更改为原始值,文本字段也会标记为已更改。要处理此问题,您可以将原始值保存在自己的文档侦听器和比较程序中