user3329732
user3329732

Reputation: 343

How to save an edited text file in a JTextArea?

I am trying to write a text editor app in Java. The following program reads in a text file then displays it via the BufferedReader method. However, at this point I am completely stuck. The displayed text can be edited in the JFrame window. But after editing, I don't know how I can then close and save the edited file (i.e. how to incorporate the event handler and then save the edited text).

I have tried many things but would very much appreciate help with how to progress from this point. I'm quite new to Java so maybe the whole structure of my program is wrong - any help much appreciated. The main program is here, followed by the display panel creator it calls. The program should pop out a window with any text file called text.txt you have placed in the directory.

MAIN:

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

Display panel creator:

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!!!

    }
}

Upvotes: 1

Views: 1232

Answers (2)

Andrew Thompson
Andrew Thompson

Reputation: 168825

Here is an example of saving a text file using a JButton to fire the event.

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

Upvotes: 1

jpw
jpw

Reputation: 44881

One way to handle this is to alter the default behavior of the window closing and adding a WindowListener that catches the window closing event and do the saving there.

A simple example that could be added in the DisplayPanel class (right after you create the jFrame object):

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

The code above will save the altered text to the file newfile.txt when the window is closed.

In the example above the splitting into lines is probably unnecessary; you would likely get the correct output by just doing writer.write(theText.getText());. The main take away should be the use of the WindowAdapter though.

Some relevant documentation:

How to Write Window Listeners

Upvotes: 1

Related Questions