You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java实现TextArea未保存修改时的关闭确认提示

实现未保存笔记关闭程序时的提示功能

问题背景

我开发了一个带TextArea的Java程序,用户可以给特定经文编号添加专属笔记,数据从SQLite加载,保存按钮(Speichern)正常工作。现在需要实现:用户修改TextArea内容但未点击保存就关闭程序时,弹出「是否保存文本?」的提示。

之前尝试给TextArea加带变量的监听器,但每次加载经文更新TextArea时都会触发变更检测,导致误判。我的思路是:加载经文后把TextArea的文本存为原始值,后续只在关闭程序时对比当前值和原始值,判断是否需要提示。

以下是我当前的加载笔记方法:

private void loadNotesFromPaliVerse() throws SQLException {

    // Check if a number has been selected
    Integer selectedNumber = comboBoxVerseNr.getValue();

    if (selectedNumber == null) {
        return;
    }

    if (selectedNumber.equals(previousSelectedNumber)) {
        return;
    }

    // Retrieve verse number based on comboBoxVerseNr
    String queryNote = DatabaseMethods.notesToPaliVerse(comboBoxVerseNr.getValue());

    try (PreparedStatement statement = connection.prepareStatement(queryNote)) {
        try (ResultSet resultSet = statement.executeQuery()) {
            if (resultSet.next()) {
                // Retrieve text value from the table
                String textValue = resultSet.getString("Notes");
                // Insert text into TextArea
                notesTextArea.setText(textValue);
            } else {
                // No corresponding entry found, clear the TextArea
                notesTextArea.clear();
            }
        }
    }
}

实现步骤

1. 维护原始笔记的状态变量

在类中添加两个成员变量,用来跟踪笔记的原始状态和保存状态:

// 存储当前选中经文的原始笔记内容
private String originalNoteContent;
// 标记笔记是否已保存(避免重复判断)
private boolean isNoteSaved = true;

2. 修改加载方法,同步原始内容

在loadNotesFromPaliVerse方法中,设置完TextArea内容后,同步更新原始内容并标记为已保存:

private void loadNotesFromPaliVerse() throws SQLException {

    Integer selectedNumber = comboBoxVerseNr.getValue();

    if (selectedNumber == null) {
        return;
    }

    if (selectedNumber.equals(previousSelectedNumber)) {
        return;
    }

    String queryNote = DatabaseMethods.notesToPaliVerse(comboBoxVerseNr.getValue());

    try (PreparedStatement statement = connection.prepareStatement(queryNote)) {
        try (ResultSet resultSet = statement.executeQuery()) {
            String textValue;
            if (resultSet.next()) {
                textValue = resultSet.getString("Notes");
                notesTextArea.setText(textValue);
            } else {
                textValue = "";
                notesTextArea.clear();
            }
            // 更新原始笔记内容
            originalNoteContent = textValue;
            // 标记为已保存状态
            isNoteSaved = true;
        }
    }
    // 更新上一次选中的经文编号
    previousSelectedNumber = selectedNumber;
}

3. 给TextArea添加变更监听器,标记未保存

给notesTextArea的文档添加监听器,只要内容发生变更就标记为未保存:

// 初始化TextArea时添加监听器
notesTextArea.getDocument().addDocumentListener(new DocumentListener() {
    @Override
    public void insertUpdate(DocumentEvent e) {
        markNoteUnsaved();
    }

    @Override
    public void removeUpdate(DocumentEvent e) {
        markNoteUnsaved();
    }

    @Override
    public void changedUpdate(DocumentEvent e) {
        markNoteUnsaved();
    }
});

// 辅助方法:标记笔记未保存
private void markNoteUnsaved() {
    isNoteSaved = false;
}

4. 修改保存按钮逻辑,更新状态

点击保存按钮完成数据库操作后,同步更新原始内容并标记为已保存:

// 保存按钮点击事件方法
private void saveButtonActionPerformed(ActionEvent e) {
    try {
        Integer selectedNumber = comboBoxVerseNr.getValue();
        if (selectedNumber != null) {
            String currentNote = notesTextArea.getText();
            // 调用你的数据库保存方法
            DatabaseMethods.saveNoteToPaliVerse(selectedNumber, currentNote);
            // 更新原始内容并标记已保存
            originalNoteContent = currentNote;
            isNoteSaved = true;
        }
    } catch (SQLException ex) {
        ex.printStackTrace();
        // 可添加保存失败的提示逻辑
    }
}

5. 拦截窗口关闭事件,判断是否提示

给主窗口添加关闭事件监听器,在关闭前检查是否有未保存的更改并弹出提示:

// 假设主窗口为JFrame类型的frame
frame.addWindowListener(new WindowAdapter() {
    @Override
    public void windowClosing(WindowEvent e) {
        // 仅当笔记未保存且内容与原始值不一致时触发提示
        if (!isNoteSaved && !notesTextArea.getText().equals(originalNoteContent)) {
            int option = JOptionPane.showConfirmDialog(
                frame,
                "是否保存文本?",
                "未保存的更改",
                JOptionPane.YES_NO_CANCEL_OPTION
            );
            switch (option) {
                case JOptionPane.YES_OPTION:
                    // 执行保存后关闭窗口
                    saveButtonActionPerformed(null);
                    frame.dispose();
                    break;
                case JOptionPane.NO_OPTION:
                    // 直接关闭窗口
                    frame.dispose();
                    break;
                case JOptionPane.CANCEL_OPTION:
                    // 取消关闭操作
                    break;
            }
        } else {
            // 无未保存更改,直接关闭
            frame.dispose();
        }
    }
});

内容的提问来源于stack exchange,提问作者Jacob J.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 20:05:26