3

For school, I'm attempting to recreate Microsoft's Notepad program using Java's Swing. I'm working on the saving and opening of .txt files, and I'm trying to figure out a way for the program to detect when a change has been made to the document. If a change has been detected and the user chooses to open or create a new file, I want the program to prompt the user if they would like to save their changes before continuing.

My thought for this was to create a flag, called documentChanged, that would initially be false, and which would be set to true whenever a change was made to the JTextArea. To detect this change, I thought of using a TextListener as follows:

public class JNotepad implements ActionListener
{
    boolean documentChanged;
    JTextArea notepad;

    JNotepad()
    {
        documentChanged = false;

        notepad = new JTextArea();
        notepad.addTextListener(new TextListener() {
            public void textValueChanged(TextEvent te) {
                documentChanged = true;
            }
        });
    }
}

However, I learned that Java classes are unable to implement multiple interfaces at once, and I'm already using ActionListeners to implement the items of my notepad's menu bar.

My question is, is there any way to use both TextListener and ActionListener (or any other listener) simultaneously in the same class? If not, what would be my best plan of action for detecting a change in the document?

William Price
  • 4,033
  • 1
  • 35
  • 54

2 Answers2

3

It was answer in another post. See Text Changed event in JTextArea? How to?

And also see How to Write a Document Listener (DocumentListener) in Oracle, you will see an applet example.

Community
  • 1
  • 1
Gaara
  • 46
  • 3
2

How does your this even compile

notepad = new JTextArea();
notepad.addTextListener(new TextListener() {
   // ....
}

since TextListeners are not defined to work with JTextAreas but rather with TextAreas, a completely different beast.

You should add a DocumentListener to your JTextArea's Document.

notepad.getDocument().addDocumentListener(new DocumentListener() {
    void insertUpdate(DocumentEvent e) {
        documentChanged = true;
    }

    void removeUpdate(DocumentEvent e) {
        documentChanged = true;
    }

    void changedUpdate(DocumentEvent e) {
        documentChanged = true;
    }

});

Regarding

My question is, is there any way to use both TextListeners and ActionListeners (or any other listener) simultaneously in the same class?

Use of a DocumentListener has nothing to do with ActionListeners used elsewhere in your program since their domains are orthogonal to each other, i.e., the one has absolutely nothing to do with the other.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • Ah, that's my mistake. I was reading up on TextAreas and didn't think twice that it was a different concept entirely. Thanks for the info regarding DocumentListener--I'll give it a try and see how it works out! –  Nov 30 '14 at 04:06
  • @GordythePirate: I also strongly recommend that you not have your GUI classes implement any of the listener interfaces as that is giving them too much responsibility and leads to the creation of the dreaded "switch-board" listener. Use anonymous inner classes, or private inner classes, or stand alone classes for your listeners depending on how large and complex they are. – Hovercraft Full Of Eels Nov 30 '14 at 04:09
  • Good to know! I had no idea it was bad practice--it was just the first method we were taught for implementing listeners so I suppose it stuck with me. My code's been changed accordingly, and thanks again for all your help! –  Nov 30 '14 at 04:24