【问题标题】:Text Editor java Swing actionListener save file文本编辑器 java Swing actionListener 保存文件
【发布时间】:2013-12-17 13:29:30
【问题描述】:

问题 我正在使用 Swing 在 java 中制作文本编辑器。我有一个使用此方法保存文件的按钮:

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);
            }
        }
    }

savedAs 布尔值仅在第一次创建文件时为真,否则它只是保存它而不打开另存为文件选择器。当我使用该按钮时,一切正常,但是当我从键绑定中调用 save() 方法时,它会保存但由于此方法:

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

它将星号重新添加到标题中。我希望它在没有星号的情况下显示它,因为它已被保存。如何确保在操作侦听器调用 save 方法时 textAreaKeyTyped 方法不接收输入。

键绑定动作监听器:

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();
        }
    });
}

原因 我认为文本区域会拾取由用户键入 CTRL + S 引起的输入,因此将星号放在标题中。

谢谢!

【问题讨论】:

  • fout.print(textArea.getText());替换为 textArea.write(更多参见 API),如果没有带有 JTextAreas 模型(文档)硬编码字符串值的 SSCCE,剩下的问题就不清楚了

标签: java swing actionlistener text-editor key-bindings


【解决方案1】:

最可靠的方法是保留String lastSaved 对象。

当你做save()做时:

lastSaved = textArea.getText();

然后在你的textAreaKeyTyped() 做:

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

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

这将带来额外的好处,即如果用户撤消他们的更改,他们的文档将回到“未修改”状态。

我实际上会创建一个包含该代码的方法updateSaveState(),并同时保存和修改后的回调调用updateSaveState(),删除那里的重复代码并将窗口标题等的所有逻辑放在一个地方。

我也很想创建一个返回!textArea.getText.equals(lastSaved)isModified() 方法并完全删除保存的标志。有什么想知道的可以拨打isModified()

请注意,在这种情况下,编辑不会在收到 keyTyped 时应用。如果您执行SwingUtilities.invokeLater 将您的处理延迟到处理完按键之后,则应该可以解决此问题。

【讨论】:

  • 很好解释的答案谢谢。我现在正在使用你的建议!
  • 由于某种原因,在添加星号之前需要进行两次编辑。我不明白为什么?
  • 我尝试了我认为应该去的地方(在 actionListener 中): public void actionPerformed(ActionEvent e) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { save( ); } }); } 但它不会改变任何东西。我把它放在正确的地方了吗?
  • 关闭,但不完全(正确的想法,错误的功能) - 把它放在textAreaKeyTyped。出现问题是因为在处理按键结果并更改字符串之前检查字符串是否已更改。
  • 啊,我明白了,非常感谢您花时间解释!
【解决方案2】:

我认为你有两个选择:

  1. 忽略 textAreaKeyTyped 方法中的 (Ctrl+s) 键 evt。也许也忽略其他不一定编辑文本的组合键

  2. 或者保存后设置标题(不带星号)

【讨论】:

    猜你喜欢
    • 2012-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多