This lab gives you a chance to practice program design using several concepts from the semester.
In class yesterday, we talked through the structure of the Sprites program from lab 16, paying particular attention the question of which classes are responsible for which information. The work we did during class is available as a starting point for you to use on a fresh try at what we tried to do in lab 16.
Clone the new starting code:
hg clone /cslab/class/csci235/labs/lab17 cd lab17
Things to recall from class:
Sprite
class; format
method and the new constructor (from a
String
) do the conversions.
Sprites
class; there are methods
readSprites()
and writeSprites()
that read
from/write to an already-opened file.
Sprites
can do that
for reading, and the SaveListener
's
saveSprites()
can do it for writing. These blocks of
code are the ones that will need to catch exceptions.
Notice that the SaveListener
has access to a label
messageField
in the dialog that it can use to communicate
status to the user.
There is one more thing that needs to be fixed in the program: if
the user provides bad input in the dialog to add a sprite, the parsing
in AddListener.finishSprite()
throws an exception. Fix
this method so that any parsing exception is caught there; you should
leave the dialog visible (and not make the sprite) if something goes
wrong.
Once you have that done, turn in your program as
lab17
:
/cslab/class/csci235/bin/handin lab17 *.java
Java's Swing library provides some pre-constructed classes for
common kinds of user interactions. You can learn more about them on
your own by looking at the on-line
Java tutorial. The JFileChooser
class was described
at the end of the file I/O handout from class; a copy of
that can be found here.
A modal dialog is one that suspends other interactions until the user dismisses it. The dialog classes discussed here are all modal.
One requirement for using a modal dialog is that you must construct
it with the window (JFrame
) to which it is
related—we call that window the dialog's parent. That
means that you'll have to find some way to pass that. In the
constructor for the Sprites
class, there is already a
local variable window
of class SimWindow
.
You can get the JFrame
you need by calling
window.getWindow()
.
The simplest predefined dialog class simply displays a message with
a button for the user to press after reading it. The class
JOptionPane
provides a static method that will display
such a message and wait for the user to press 'OK'. All you have to
do is call
JOptionPane.showMessageDialog(parent, "message to display");
If you would like to be very slightly fancier, you can add two more parameters, as in
TheJOptionPane.showMessageDialog(parent, "message to display", "title string", messageKind);
messageKind
should be one of
JOptionPane.ERROR_MESSAGE
,
JOptionPane.INFORMATION_MESSAGE
,
JOptionPane.WARNING_MESSAGE
, or
JOptionPane.PLAIN_MESSAGE
.
A good for use for this would be to display a message when the user
provides bad input to the "add sprite" dialog. The parent in that
case would be the AddListener
frame.
JFileChooser
dialog
The familiar file-browser dialogs are provided by the class
JFileChooser
.
Here are the methods you need to know:
JFileChooser(directory)
Construct a chooser. The directory can be nothing, in
which case it will use the user's home directory, or it can be a
path to a directory to start in ("."
is a likely
choice, so that it looks in the directory from which the program was run.)
You will specify the parent window when
you show the dialog with one of the next two methods.
int showOpenDialog(JFrame parent)
int showSaveDialog(JFrame parent)
These two instance methods show the dialog to select a file for
reading or for writing, respectively. If the user hits the
button indicating they want the action, the value returned will be
JFileChooser.APPROVE_OPTION
; any other return value
indicates that no action should be taken.
File getSelectedFile()
This returns the name of the selected file, but it does so as the
type java.io.File
, which you will need to import.
You can pass the File
value to a constructor for either
PrintWriter
or FileInputStream
. If you
want to get the name of the File
as a string, call its
getPath()
method.
You can use a JFileChooser
to replace the
SaveListener
's JFrame
and its components;
you'll end up calling showSaveDialog()
to let the user
select file. (The parent here will be the window from the
Sprites
instance.)
Because of the way this dialog is structured, you won't need an additional
FinishSaveListener
class with it.
lab17b
.