CS 3230 - Lab 10

File / Exception Lab

Last lab, gang. Here goes.

Overview

Today you guys will make a little text editor

Screenshot

Here's some detail of the menu:

You guys will need to make a Lab10.java file that does this.

Overview of Features

Specifications

You will need to make 1 (one!) class: a Frame called Lab10. It will derive from the JFrame class and implement the ActionListener interface. All told, it will have 2 properties and 3 methods.

The Properties

  1. A String that will store the name of the save file (call it saveFile). Initialize it to null (no save file).
  2. A JTextArea that you will use to display the text file. Instantiate a new one on the line where you declare it.

The main Method

Surely you guys know how to write this one by now.

Oh, okay... Make a new instance of the Lab10 class and call its show() method.

The Constructor

Set up the frame: by calling setTitle(), setDefaultCloseOperation() and setSize().

Add the text area: by adding it to a JScrollPane and then putting the scroll pane in the center of the frame. (Look at this JScrollPane constructor which shows how to set the policy for displaying the scrollbars.)

Create the menu: Look at the Lab8 notes for a refresher on how to do this. In a nutshell, you:

  1. Make N menu items (JMenuItem)
  2. Give each menu item a different action command (setActionCommand())
  3. Tell the menu items that the frame will listen for events (addActionListener())
  4. Add all the menu items to a menu (JMenu)
  5. Add the menu to a menu bar (JMenuBar)
  6. Add the menu bar to the frame (JFrame.setJMenuBar())

Create the toolbar: This process is very similar to the menu:

  1. Make N buttons, passing them the name of a file to use for an icon (new JButton(new ImageIcon("imgfile.gif")))
  2. Give each button a different action command (setActionCommand())
  3. Tell the buttons that the frame will listen for events (addActionListener())
  4. Add all the buttons to a toolbar (JToolBar)
  5. Add the toolbar to the north part of the frame

For the button images, feel free to use these:


new.gif

open.gif

save.gif

exit.png

Hints on the menu items and toolbar buttons: You can make the code more compact by using a couple String arrays that contain label names and image file names and then use a for loop to create the menu items and buttons and add them to their containers. You can then re-use the labels as the action command strings. See UsesActionCommands.java for an example. Also, see this entry in the Q&A section below.

The actionPerformed() Method

You inherit this method from the ActionListener interface. This is where the real meat of your program is.

"Save" event: Do the following:

  1. First, if the user has not previously chosen a save file (saveFile == null), instantiate a new JFileChooser
  2. Call JFileChooser.setCurrentDirectory(new File(".")) so that it will display the files in the current directory.
  3. Then call JFileChooser.showSaveDialog()
  4. If the user clicks the "Save" button (see the JFileChooser docs for how to do this), store the path to the file by calling JFileChooser.getSelectedFile().getCannonicalPath(). You should also call JFrame.setTitle() and set it to the file name.
  5. Now that you have a save file name, write the contents of the text area to the file by instantiating a new PrintWriter / FileWriter combo (see the Ch 11-12 notes) and call PrintWriter.println(textArea.getText()) to write the text in the text area to the file.

Note#1: You will need to handle all of the various exceptions that could be thrown by the file I/O methods. Consult the Ch 11-12 notes for details.

Note#2: You should set up your code such that the user only needs to see the save dialog once. The first time he clicks "Save", the save dialog should be displayed. Thereafter, it should just use the previously chosen save file name and re-save it.

Note#3: You do not have to bother with setting up a file filter for the file chooser dialog, just let it display all files. (You're welcome.)

"Open" event: The code you will write for this event handler is very similar to the "Save" event:

  1. Instantiate a new JFileChooser, set it to the current directory, and call JFileChooser.showOpenDialog(). (Again, just show all files.)
  2. If they click "Open", store the file name, set the title of the frame, and clear the text area by calling JTextArea.setText("").
  3. Read from the file by making a new FileReader / BufferedReader combo. Then call BufferedReader.readLine() in a loop (you're done when you read null), and add each line to the text area by calling JTextArea.append(). (Again, consult the Ch 11-12 notes for details.) You'll find that you'll need to add a trailing newline as well. (Just make another call to JTextArea.append().)

"New" event: clear the text area, reset the save file to null, and set the frame's title to "[No File]".

"Exit" event: by calling System.exit(0) (you don't have to prompt the user to save before closing; this is not a user friendly app)

Questions and Answers

What packages do I need to import?

Not telling. Find 'em yourself.

Do I have to apply a filter (like *.txt) to the FileChooser dialogs?

No, that is tedious and difficult. Moreover, not all text files end with .txt (such as HTML and other docs). Just let it display the default of "all files".

It's saving my files in the wrong directory!

When you get the name of the file the user has chosen, do not type:

saveFile = chooser.getSelectedFile().getName();
Instead, type:
saveFile = chooser.getSelectedFile().getCannonicalPath();
which will retrieve the full path to where the file is stored.

Can you show me how to set up the menu and toolbar items in the loop?

I will take pity on you this time and offer you the following source code snippet. It should go inside your frame's constructor.

// set up menu & toolbar
String[] labels = {"New", "Open", "Save", "Exit"};
String[] tbFiles = {"new.gif", "open.gif", "save.gif", "exit.png"};
String[] tooltips = {"Create a new file", "Open an existing file",
	"Save the current file", "Close the application"};
JMenu fileMenu = new JMenu("File");
JToolBar toolbar = new JToolBar();
for (int i = 0; i < labels.length; i++) {
	// menu item setup
	JMenuItem mi = new JMenuItem(labels[i]);
	mi.setActionCommand(labels[i]);
	mi.addActionListener(this);
	mi.setToolTipText(tooltips[i]);
	fileMenu.add(mi);

	// toolbar button setup
	JButton btn = new JButton(new ImageIcon(tbFiles[i]));
	btn.setActionCommand(labels[i]);
	btn.addActionListener(this);
	btn.setToolTipText(tooltips[i]);
	toolbar.add(btn);
}
// add menubar to frame
JMenuBar mb = new JMenuBar();
mb.add(fileMenu);
setJMenuBar(mb);

// add toolbar to frame
getContentPane().add(toolbar, BorderLayout.NORTH);

Your exit button looks gross.

Yeah, I know.

Do I have to put my name, course number and lab number at the top of the page?

Only if you want credit.

How about my Application Project?

Those of you that are doing a text editor will find this lab a good start. I would expect you to add a few more features though, like: search and replace, checking to see if the buffer has changed before exit / new are clicked; support for cut / copy / paste; and possibly support for undo / redo. (Not to mention a cute little 'About' dialog.)