【问题标题】:How to save an edited text file in a JTextArea?如何将编辑后的文本文件保存在 JTextArea 中?
【发布时间】:2018-07-13 10:28:32
【问题描述】:

我正在尝试用 Java 编写一个文本编辑器应用程序。下面的程序读入一个文本文件,然后通过BufferedReader 方法显示它。但是,在这一点上,我完全被卡住了。可以在JFrame 窗口中编辑显示的文本。但编辑后,我不知道如何关闭并保存编辑后的文件(即如何合并事件处理程序,然后保存编辑后的文本)。

我已经尝试了很多事情,但非常感谢有关如何从这一点取得进展的帮助。我对 Java 很陌生,所以我的程序的整个结构可能是错误的 - 非常感谢任何帮助。主程序在这里,然后是它调用的显示面板创建器。程序应该会弹出一个窗口,其中包含您放置在目录中的任何名为 text.txt 的文本文件。

主要:

import java.io.*;
import java.util.ArrayList;
import static java.lang.System.out;
public class testApp4 {
    public static void main(String args[]) {
        ArrayList<String> listToSend = new ArrayList<String>();
        String file = "text.txt";
        try (BufferedReader br = new BufferedReader(new FileReader(file))) 
        {
            String line;
            while ((line = br.readLine()) != null) {
               listToSend.add(line);
            }
        br.close();
        }
        catch(FileNotFoundException e)
        {
            out.println("Cannot find the specified file...");
        }
        catch(IOException i)
        {
            out.println("Cannot read file...");
        }
        new DisplayPanel(listToSend);
    }
}

显示面板创建者:

import java.awt.Font;
import java.util.ArrayList;
import javax.swing.JFrame;// javax.swing.*;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;

public class DisplayPanel {
    public DisplayPanel(ArrayList<String> list) //constructor of the DisplayGuiHelp object that has the list passed to it on creation
    {
        JTextArea theText = new JTextArea(46,120); //120 monospaced chrs
        theText.setFont(new Font("monospaced", Font.PLAIN, 14));
        theText.setLineWrap(true);
        theText.setEditable(true);
        for(String text : list)
        {
            theText.append(text + "\n"); //append the contents of the array list to the text area
        }
        JScrollPane scroll = new JScrollPane(theText);
        scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);

        JPanel mainPanel = new JPanel();
        mainPanel.add(scroll);

        final JFrame theFrame = new JFrame();
        theFrame.setTitle("textTastico");
        theFrame.setSize(1100, 1000);
        theFrame.setLocation(550, 25);
        theFrame.add(mainPanel); //add the panel to the frame
        theFrame.setVisible(true);

        System.out.print(theText.getText()); //double check output!!!

    }
}

【问题讨论】:

  • 1) JTextArea theText = new JTextArea(46,120);JTextComponent.read(Reader ..) & write(Writer)。 2)“如何合并事件处理程序,然后保存编辑的文本”你指的是什么“事件”?用户点击按钮?文字变了?窗户被关了?爆米花做好后微波炉会“叮”的一声? .. 3) ..
  • 您也可以使用保存按钮将文本从编辑器保存(写入)到文件中;按钮的事件处理程序具有要保存的代码。此外,读取文件并填充到列表集合的代码可以简洁地编写为(使用 Java 7 或更高版本):ArrayList&lt;String&gt; listToSend = Files.readAllLines(Paths.get("text.txt"));
  • .. new Font("monospaced", Font.PLAIN, 14) 最好是 new Font(Font.MONOSPACED, Font.PLAIN, 14) 用于编译时检查。如果有一个常数,为什么使用它? 4) theFrame.setSize(1100, 1000); .. theFrame.add(mainPanel); 更多猜测。将其更改为 theFrame.add(mainPanel); .. theFrame.pack() 以在任何平台上获得正确的大小。 5) 但是您可能会注意到,对于文本区域而言,120 个字符变得非常 宽。 ;)
  • @prasad_ 似乎 Files.readAllLines(Path) 假定为 UTF-8。我在第一条评论中概述的方法正确地解释了文本文件实际使用的任何编码。
  • “用户点击了一个按钮?文本被改变了?窗口被关闭了?” 那么..是什么?我已经编写了涵盖所有这三个的代码,但是它们在一起并没有多大意义(文档侦听器使动作侦听器和窗口侦听器变得多余)。

标签: java swing file-io jframe text-files


【解决方案1】:

解决此问题的一种方法是更改​​窗口关闭的默认行为并添加一个 WindowListener 来捕获窗口关闭事件并在那里进行保存。

一个可以添加到 DisplayPanel 类中的简单示例(在您创建 jFrame 对象之后):

    theFrame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
    theFrame.addWindowListener(new WindowAdapter() {
        @Override
        public void windowClosing(WindowEvent e) {
            super.windowClosing(e);
            String[] lines = theText.getText().split("\\n");
            try (BufferedWriter writer = new BufferedWriter(new FileWriter("newfile.txt"))) {
                for (String line : lines)
                    writer.write(line + "\n");
            } catch (IOException i) {
                System.out.println("Cannot write file...");
            }

            System.out.println("File saved!");
            System.exit(0);
        }
    });

当窗口关闭时,上面的代码会将修改后的文本保存到文件newfile.txt

在上面的例子中,分割成行可能是不必要的;只需执行writer.write(theText.getText());,您可能会得到正确的输出。不过,主要的收获应该是使用 WindowAdapter。

一些相关文档:

How to Write Window Listeners

【讨论】:

  • 您好 jpw 感谢您的意见。调用“theText”变量时出现错误:“无法引用封闭范围中定义的非最终局部变量 theText”。而且 BufferedWriter 和 FileWriter 也无法解析。
  • @user3329732 不知道第一个错误是什么原因,应该没问题,但是要修复第二个错误,您需要为相关类添加导入语句
【解决方案2】:

这是一个使用JButton 保存文本文件以触发事件的示例。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.io.*;

public class DisplayPanel {

    public static String textFilePath = // adjust path as needed
            "C:\\Users\\Andrew\\Documents\\junk.txt";
    private JComponent ui = null;
    private JFrame frame;
    private JTextArea theText;
    private JButton saveButton;
    private ActionListener actionListener;
    File file;

    DisplayPanel(File file) {
        this.file = file;
        try {
            initUI();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    private void saveText() {
        Writer writer = null;
        try {
            writer = new FileWriter(file);
            theText.write(writer);
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                writer.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

    public final void initUI() throws FileNotFoundException, IOException {
        if (ui != null) {
            return;
        }

        ui = new JPanel(new BorderLayout(4, 4));
        ui.setBorder(new EmptyBorder(4, 4, 4, 4));

        theText = new JTextArea(20, 120); //120 monospaced chrs
        theText.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 14));
        theText.setLineWrap(true);
        theText.setEditable(true);
        JScrollPane scroll = new JScrollPane(theText);
        scroll.setVerticalScrollBarPolicy(
                ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);

        ui.add(scroll);

        saveButton = new JButton("Save");
        ui.add(saveButton, BorderLayout.PAGE_START);

        actionListener = (ActionEvent e) -> {
            saveText();
        };
        saveButton.addActionListener(actionListener);

        Reader reader = new FileReader(file);
        theText.read(reader, file);
    }

    public void createAndShowGUI() {
        frame = new JFrame(this.getClass().getSimpleName());
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setLocationByPlatform(true);

        frame.setContentPane(getUI());
        frame.pack();
        frame.setMinimumSize(frame.getSize());

        frame.setVisible(true);
    }

    public JComponent getUI() {
        return ui;
    }

    public static void main(String[] args) {
        Runnable r = () -> {
            try {
                UIManager.setLookAndFeel(
                        UIManager.getSystemLookAndFeelClassName());
            } catch (Exception useDefault) {
            }
            File file = new File(textFilePath);
            DisplayPanel o = new DisplayPanel(file);
            o.createAndShowGUI();
        };
        SwingUtilities.invokeLater(r);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-16
    • 1970-01-01
    • 2021-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-24
    相关资源
    最近更新 更多