Lab: Gaining Experience with Modifying an Existing GUI
Instructions:
Answer the following questions one at a time. After answering each question,
check your answer (by clicking on the check-mark icon if it is available)
before proceeding to the next question.
Getting Ready:
Before going any further, you should:
-
Setup your development environment.
-
Download the following files:
to an appropriate directory/folder. (In most browsers/OSs, the
easiest way to do this is by right-clicking/control-clicking on
each of the links above and then selecting Save as...
or Save link as....)
-
This lab is a simulation of a part of the process that is being
used to create a product
named Taxeze for the
(hypothetical) company FreeMarket.
The team is using an incremental process known as Scrum, which
divides the work up into sprints.
If you have not already done so, you must complete
the lab on serialization
before you can start this lab.
1. Understanding an Existing GUI:
This part of the lab will give you experience understanding an existing
GUI.
-
Review the
TaxezeWindow
class, paying particular
attention to the sections that involve the menu bar.
-
Review the
TaxezeController
class, paying particular
attention to the sections of the actionPerformed()
method that involve the menu bar.
-
Review the
read()
method in
the TaxezeController
class, paying particular
attention to how the FileNameExtensionFilter
is used
and to how tax calculations are enabled after the files are read.
2. Tasks:
Recall that in the earlier lab you did not satisfy all of the acceptance
criteria. The remaining aspects of the sprintable stories have been decomposed
into the following tasks.
-
Copy
Open.png
into the project (from a file explorer into
Eclipse).
-
Add the "constants"
OPEN
and WRITE
to the
TaxezeWindow
class.
static final String OPEN = "Open";
static final String WRITE = "Write";
-
Add an
OPEN
JButton
(with the
icon Open.png
) to the left of the CALCULATE
button.
private JButton calculateButton, openButton;
// ...
openButton = createJButton("Open.png", OPEN);
//
toolBar.add(openButton);
-
Add an
OPEN
JMenuItem
to the FILE
menu.
item = new JMenuItem(OPEN);
item.addActionListener(controller);
menu.add(item);
-
Add the
WRITE
JMenuItem
to the
UTILITIES
menu (and disable it in an appropriate place).
private JMenuItem writeItem;
// ...
item = new JMenuItem(WRITE);
writeItem = item;
writeItem.setEnabled(false);
item.addActionListener(controller);
menu.add(item);
-
Why does the
WRITE
JMenuItem
need to be an
attribute and not a local variable?
Because it will need to be enabled by the TaxezeController
after a .tax
file is read.
-
Add a method with the following signature to the
TaxezeWindow
class:
public void enableWrite(boolean enable)
that can be used to disable/enable writeItem
.
public void enableWrite(boolean enable)
{
writeItem.setEnabled(enable);
}
-
Declare and instantiate a
FileNameExtensionFilter
in
the TaxezeController
class that can be used
for .txs
files.
private FileNameExtensionFilter txsFilter;
// ...
txsFilter = new FileNameExtensionFilter(DATA_FILES, "txs");
-
Add a
write()
method to
the TaxezeController
class (modeled after the
read()
method) that can be called in response to
WRITE
requests.
private void write()
{
fileChooser.setFileFilter(txsFilter);
fileChooser.setDialogTitle(WRITE);
fileChooser.setSelectedFile(new File("temp.txs"));
int result = fileChooser.showSaveDialog(null);
if (result == JFileChooser.APPROVE_OPTION)
{
String path = fileChooser.getSelectedFile().getPath();
String extension = txsFilter.getExtensions()[0];
if (path.endsWith(extension))
{
String name = path.substring(0, path.length()-4);
try
{
schedule.write(name);
}
catch (IOException ioe)
{
JOptionPane.showMessageDialog(null, ERROR_OPENING_FILE, ERROR, JOptionPane.ERROR_MESSAGE);
}
}
else
{
JOptionPane.showMessageDialog(null, INVALID_FILE_TYPE, ERROR, JOptionPane.ERROR_MESSAGE);
}
}
}
-
Add code to the
actionPerformed()
method in the
TaxezeController
class that calls the write()
method in response to WRITE
requests.
else if (ac.equals(WRITE)) write();
-
Add an
open()
method to
the TaxezeController
class (modeled after the
read()
method) that can be called in response to
OPEN
requests.
private void open()
{
fileChooser.setFileFilter(txsFilter);
int result = fileChooser.showOpenDialog(null);
if (result == JFileChooser.APPROVE_OPTION)
{
String path = fileChooser.getSelectedFile().getPath();
String extension = txsFilter.getExtensions()[0];
if (path.endsWith(extension))
{
String name = path.substring(0, path.length()-4);
try
{
schedule = TaxSchedule.open(name);
setTaxScheduleIsAvailable(true);
Set<String> keys = schedule.keySet();
for (String filingStatus: keys) window.addFilingStatus(filingStatus);
}
catch (IOException ioe)
{
JOptionPane.showMessageDialog(null, ERROR_OPENING_FILE, ERROR, JOptionPane.ERROR_MESSAGE);
}
}
else
{
JOptionPane.showMessageDialog(null, INVALID_FILE_TYPE, ERROR, JOptionPane.ERROR_MESSAGE);
}
}
}
-
Add code to the
actionPerformed()
method in the
TaxezeController
class that calls the open()
method in response to OPEN
requests.
else if (ac.equals(OPEN)) open();
-
Add code to the
setTaxScheduleIsAvailable()
method in the
TaxezeController
class that enables the
WRITE
menu item.
window.enableWrite(available);
-
Test this new functionality.
-
Refactor your code to eliminate duplication in the
read()
and open()
methods.
// Replace read() and open() with the following load() method.
/**
* Handle OPEN and READ requests.
*/
private void load(FileNameExtensionFilter filter, String title)
{
fileChooser.setFileFilter(filter);
fileChooser.setDialogTitle(title);
int result = fileChooser.showOpenDialog(null);
if (result == JFileChooser.APPROVE_OPTION)
{
String path = fileChooser.getSelectedFile().getPath();
String extension = filter.getExtensions()[0];
if (path.endsWith(extension))
{
String name = path.substring(0, path.length()-4);
try
{
if (extension.equals("txs"))
{
schedule = TaxSchedule.open(name);
Set<String> keys = schedule.keySet();
for (String filingStatus: keys) window.addFilingStatus(filingStatus);
}
else
{
TaxTable table = new TaxTable();
table.read(name);
String filingStatus = table.getFilingStatus();
schedule.put(filingStatus, table);
window.addFilingStatus(filingStatus);
}
setTaxScheduleIsAvailable(true);
}
catch (IOException ioe)
{
JOptionPane.showMessageDialog(null, ERROR_OPENING_FILE, ERROR, JOptionPane.ERROR_MESSAGE);
}
}
else
{
JOptionPane.showMessageDialog(null, INVALID_FILE_TYPE, ERROR, JOptionPane.ERROR_MESSAGE);
}
}
}
// Change actionPerformed() as follows
else if (ac.equals(OPEN)) load(txsFilter, OPEN);
else if (ac.equals(READ)) load(taxFilter, READ);