Tracking changes in the swing GUI

Say, an application property page with lots of JCheckboxes, JTextfields, JLists, and other JComponents. Now I need to track the changes made by the user and save them. What would be the correct way to implement this?

+1


a source to share


5 answers


You don't need to track changes in real time (except for special needs).



You can react to the OK button, iterate on the components, retrieve their value, perhaps compared to the old one, or just blindly save all values. And of course give up everything if the user cancels.

+2


a source


Two approaches you can use:

(1) When the user clicks "OK" on the property page, pull the current values ​​from your JComponents and update your settings or whatever. This is the easiest method since you don't need ActionListeners and if the user refuses you you don't need to rollback the changes (from your question it's not clear exactly what this dialog / page does).

(2) For swing objects that implement an ActionListener, listen for the ActionEvent and handle the changes accordingly. For JTextFields, use a DocumentListener like in the example code below:



import java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

public class Test implements DocumentListener
{
  private JTextField jtf;

  public static void main(String[] args)
  { 
    javax.swing.SwingUtilities.invokeLater(new Runnable()
        {
          public void run()
          {
            Test test = new Test();
          }
        });
  }
  public Test()
  {
    JFrame jf = new JFrame();
    JPanel jp = new JPanel();
    jtf = new JTextField();
    jtf.getDocument().addDocumentListener(this);
    jp.setLayout(new BorderLayout());
    jp.add(jtf, BorderLayout.CENTER);
    jf.add(jp);
    jf.setSize(200, 100);
    jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    jf.setVisible(true);
  }

  public void changedUpdate(DocumentEvent e) 
  {
   // Do stuff here
  }
  public void insertUpdate(DocumentEvent e) 
  {
    // Do stuff here
  }
  public void removeUpdate(DocumentEvent e) 
  {
    // Do stuff here
  }
}

      

As you can guess from (1), the call from (2) occurs if the user backs out and you need to think about how you are going to rollback any changes. It really depends on what you are doing.

+1


a source


An observation pattern should help with this. Basically it allows a component (publisher) to notify other components (subscribers) about things, basically it is an ActionListener (like Catchwa's response ).

Java Sample Observer Pattern from Google

If you can check out Chapter 2 Head First Design Patterns or The Listener Tutorial

I hope this helps a little, I can't hack an example at the moment, but I hope it helps you get started.

+1


a source


Command class and serializable ArrayList or LinkedList of Commands. The commands will be generated in the actionPerformed method.

0


a source


The main question I have is what changes / events do you want to log. Clicks, text changes, button states, ....

For each event, you can add listeners to swing components. One singleton class can be the developer of the listeners you want to add to different components. these are singleton classes that you can add to various components.

When a component changes or notifies a custom listener, the singleton dispatcher is notified and can handle this event.

The manager can log events that come in and also save an EventObject that contains whatever you want to keep. List of EventObjects that you can save to disk using xstream .

-1


a source







All Articles