Domanda

Problem I am making a text editor in java using Swing. I have a button which saves the file, using this method:

private void save() {
        if (savedAs) {
            try {
                PrintWriter fout = new PrintWriter(savedAsFile);
                fout.print(textArea.getText());
                fout.close();
                this.setTitle("Text Editor - " + fileName);
                saved = true;
            } catch (FileNotFoundException ex) {
                Logger.getLogger(TextEditorFrame.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

The savedAs boolean is true only when a file is first created, otherwise it just saves it without opening the save as file chooser. When I use the button everything works, however when I call the save() method from the key bindings it saves but due to this method:

private void textAreaKeyTyped(java.awt.event.KeyEvent evt) {                                  
    this.setTitle("Text Editor - *" + fileName);
    saved = false;
}         

It adds the asterisk back on to the title. I want it to display it without the asterisk because it has been saved. How can I make sure that the textAreaKeyTyped method does not pick up input while the action listener is calling the save method.

Key bindings actionlistener:

public void initBindings() {
    textArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(
            KeyEvent.VK_S, java.awt.event.InputEvent.CTRL_DOWN_MASK), "actionMapKey");
    textArea.getActionMap().put("actionMapKey", new AbstractAction() {
        @Override
        public void actionPerformed(ActionEvent e) {
            save();
        }
    });
}

Cause I think that the text area picks up input caused by the user typing CTRL + S, therefore puts the asterisk in the title.

Thanks!

È stato utile?

Soluzione

The most robust way would be to keep a String lastSaved object.

When you do save() do:

lastSaved = textArea.getText();

Then in your textAreaKeyTyped() do:

boolean unchanged = textArea.getText.equals(lastSaved);

if (!unchanged) {
   // add *, enable save, etc
} else {
   // remove *, disable save, etc
}

This will have the added benefit that if a user reverses their changes their document will go back to a "not modified" state.

I would actually create a method updateSaveState() containing that code and have both save and the modified callback call updateSaveState(), removing the duplicated code there and putting all the logic for window title etc in one place.

I'd also be tempted to create an isModified() method that returns !textArea.getText.equals(lastSaved) and remove the saved flag completely. Anything that wants to know can just call isModified().

Note that in this case the edit will not be applied yet at the point the keyTyped is received. If you do a SwingUtilities.invokeLater to delay your processing until after the keypress has been processed that should fix this problem.

Altri suggerimenti

I think you have two choices:

  1. Disregard the (Ctrl+s) key evt in your textAreaKeyTyped method. Maybe also disregard other key combinations that don't necessarily edit the text

  2. Or set the title (without the asterisk) after you have saved

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top