Hi,

I hope there will be a suitable function or easy way to enable/disable save button until something is really changed in the GUI(frame). My frame consists of several panels, textboxes, Jtable,Jtree e.t.c. How can I design some function until some infomation is manually chnaged by the user to enable the save button?

I saw eclipse handles it well, untill something is changed in the code the save button is inactive and when the changes are reverted save button is automatically disabled. I would like to have one search method for my form.

Any help is appreciated.

thanks

You can add a TextListener to each text field (and ChangeListeners to radio buttons etc etc). You can use the same listener code for all of them - all it has to do is enable the Save button.

Hi,

To disable or enable a button in java, you can use the setEnabled method :

Click Here

Now, to detect changes in the frame, you must add a listener to the components you want to watch, every component has its own events.

@JamesCherrill

  • please why AWT, disagree

  • TextListener to each text field (for AWT TextField), note DocumentListener isn't shareable, there isn't possible to add more that one JTextComponent to DocumentListener, solution is create an util.List with pairs for every JTextComponent(s) and DocumentListener/Filter(s)

  • and ChangeListeners to radio buttons (I think that ItemListener, for a maximum of emergency is there ActionListener)

@yamini222

you would need to add validation for all JComponents created/are required to create a set of information

Sorry - my mistake, it should have been DocumentListener, not TextListener. (Old habits maybe?)

Because the listener is just going to enable the save button, I can't see any reason why all the text fields cannot call the same one-line listener? It's not in any way dependent on, nor does it change, the state of the text field.

What's the problem with ChangeListener for JRadioButton?

there is one simple way (invoked by - What's the problem with ChangeListener) usage of PropertyChangeListener, every JComponents are accesible for PropertyChangeSupport, then every JComponents will call only one Swing Action/ActionListener by firePropertyChange(mySwingAction, oldValue, newValue) ... done!!! (in the case that user will fills JComponents from top left to the right bottom, otherwise there must runs validation for all required JComponents, every time, when/after user moving with focus)

________________________________________________________________________________

I can't see any reason why all the text fields cannot call the same one-line listener? == simple this is not possible (API and decision by Swing Team), and DocumentListener is heavy listener, potential performance issue to add/remove one DocumentListener on runtime, forgot to add one DocumentListener to List<JTextField> you can to freeze current Swing GUI (never debugged this issue, too lazy),

________________________________________________________________________________

What's the problem with ChangeListener for JRadioButton? == you have to override and fireChangeEvent programatically, maybe this is advantage (too lazy bothering with, easiest /number of used chars/ is to test for SELECTED/DESELECTED from ItemListener, I'm suggest to use this listener always for JComboBox, JToggleButton, JRadioButton, JCheckBox)

So I tried a small demo program. With a bit of tuning it looked like this:
First the universal listener...

   class Saver implements DocumentListener, ActionListener {

        private int count = 0;

        @Override
        public void insertUpdate(DocumentEvent e) {
            System.out.println("Event " + count++);
        }

        @Override
        public void removeUpdate(DocumentEvent e) {
            System.out.println("Event " + count++);
        }

        @Override
        public void changedUpdate(DocumentEvent e) {
            System.out.println("Event " + count++);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("Event " + count++);
        }

    }

    private final Saver listener = new Saver();

(that uses prints to confirm what's happening. The real thing would replace all those with a setEnabled(true); for the save button).

Then I did a simple test window with a checkbox and a couple of text fields, which I hooked up with

        cb.addActionListener(listener);
        tf1.getDocument().addDocumentListener(listener);
        tf2.getDocument().addDocumentListener(listener);

and hey presto - any change to the text fields or check box trigger the event / Save button enabling.
Isn't that what the OP was looking for?

  • again:-) your GUI will freeze in the case that you'll add more JTextComponents to one DocumentListener/Filter, is quite heavy in some cases is required usage of invokeLater(delaying to the end of EDT), nor that there is orders of JTextComponents in DocumentWhatever,

  • I'll search for real workaround (described in English Language), there isn't another way (my view)

edit:

mKorbel - do you have any links or refernces I can follow up re problems in sharing a DocumentListener?
For this specific case, where the document is completely ignored in the listener (and the callback is always single-threaded on the EDT), I can't see any potential for freeezes, but I'm always ready to learn...

Do you have any links or refernces I can follow up re problems in sharing a DocumentListener? -- no only experiences, but there is very simple way to confirm, how do you want to get JTextComponent from DocumentWhatever, in most of Listener is event.getSource(e.i.), there is only getDocument, do you have to traversing throught Components tree, not it isn't shareable, but source is testable (my love and very usefull) by get/put(Client)Property only,

edit

get/put(Client)Property for arrays of (e.g.) JButton without needs to put that to the array, this method haven't limits, any nor numbers of, one of ways for PropertyChangeListener

edit (e.g. ), again don't do that, nor chaining Document or add/append document, part of Document or simgle char (KeyTyped) from one JTextComponent to another in the case that are member of one DocumentWhatever

textField = new JTextField(20);
textField.setFont(new Font("Dialog", Font.BOLD, 24));
textField.addActionListener(new MyTextActionListener());
textField.getDocument().addDocumentListener(new MyDocumentListener());
textField.getDocument().putProperty("name", "Text Field");
textArea = new JTextArea();
textArea.setFont(new Font("Dialog", Font.BOLD, 24));
textArea.getDocument().addDocumentListener(new MyDocumentListener());
textArea.getDocument().putProperty("name", "Text Area");

class MyDocumentListener implements DocumentListener {

    final String newline = "\n";

    @Override
    public void insertUpdate(DocumentEvent e) {
        updateLog(e, "inserted into");
    }

    @Override
    public void removeUpdate(DocumentEvent e) {
        updateLog(e, "removed from");
    }

    @Override
    public void changedUpdate(DocumentEvent e) {
        //Plain text components don't fire these events.
    }

    public void updateLog(DocumentEvent e, String action) {
        Document doc = (Document) e.getDocument();
        int changeLength = e.getLength();
        displayArea.append(changeLength + " character"
                + ((changeLength == 1) ? " " : "s ")
                + action + " " + doc.getProperty("name") + "."
                + newline + "  Text length = " + doc.getLength() + newline);
        displayArea.setCaretPosition(displayArea.getDocument().getLength());
    }
}

Yes, I'm sure there are problems with sharing a listener when you want to do stuff like finding the text area or updating its state.
What I am asking is: what's the problem when the whole code for the listener is just like

@Override
public void insertUpdate(DocumentEvent e) {
  mySaveButton.setEnabled(true);
}

... it doesn't need to get the source, or the DocumentEvent, or reference the document or the text area(s) in any way.

what's the problem when the whole code for the listener is just like

  • there isn't some, any issue, in this and given form, maybe should be delayed in invokeLater()

... it doesn't need to get the source, or the DocumentEvent, or reference the document or the text area(s) in any way.

  • for real validations you would need to know that, for an answer to the forum, to this question, you are right doesn't matter

OK yes :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.