| 95.106 - Design and Implementation of Computer Applications |
2001 |
5 Menus and Dialogs |
| 5.1 Creating Menus |

JMenuItem findItem = new JMenuItem("Find");
JMenuItem replaceItem =
new JMenuItem("Replace");
searchMenu.add(findItem);
searchMenu.add(replaceItem);
fileMenu.add(searchMenu);
JMenuItem helpItem = new JMenuItem("help");
JMenuItem inspectItem =
new JMenuItem("inspect");
popupMenu.add(helpItem);
popupMenu.add(inspectItem);
popupMenu.setInvoker(getContentPane());
| 5.2 Menu Events |
//We left some code out
here. Menu items must be added to menus.
...
//The event handler is used to
dispatch menu selections
public void actionPerformed(ActionEvent event){
if
(event.getSource() == newItem)
reactToNewMenuSelection();
else if
(event.getSource() == openItem)
reactToOpenMenuSelection();
}
// Enable the menu items
inside constructor
public
FileMenuExample(...) {
...
newItem.addActionListener(this);
openItem.addActionListener(this);
...
}
//These are the react methods
(called by the event handler)
//We could have placed this code right into
the event handler above
public
void reactToNewMenuSelection()
{
System.out.println("reacting to 'new' selection from
menu");
}
public void reactToOpenMenuSelection() {
System.out.println("reacting to 'open' selection from menu");
}
}
In this example, we investigate the use of a menubar with
menus as well as cascaded menus and a popup menu. The example has no
purpose other than to show you how the different menus are created and
used. Here are screen snapshots that show the menus that we'll
create in this example:
A standard menu |
A cascaded menu |
A menu with radio buttons |
A pop-up menu |
The example shows how the use of many menu items can lead to a lot of instance variables. In addition, we use a common event handler for all menu items and apply a dispatching strategy which calls the appropriate react method for the given menu item. We could have omitted the react methods and merely placed all this code within the single event handler but this could look messy if the react methods are large.
How would the example look if we used anonymous classes instead of one event handler ? It may not save much in code size but we only need to update the class in one place instead of two when a menu item is added or removed! Also, we might not need to keep all the menu items in instance variables! Why not give it a try and see what it looks like.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;public class FileMenuExample extends JFrame implements ActionListener {
// Use instance variables to keep track of menu items and popup menus}
JMenuItem thinkItem = new JMenuItem("Think", new ImageIcon("brain.gif"));
JMenuItem copyItem = new JMenuItem("Copy");
JMenuItem newItem = new JMenuItem("New");
JMenuItem openItem = new JMenuItem("Open");
JMenuItem saveAsItem = new JMenuItem("Save As");
JMenuItem findItem = new JMenuItem("Find");
JMenuItem replaceItem = new JMenuItem("Replace");// Some items for use in the Settings menu
JMenuItem appleItem = new JRadioButtonMenuItem("Apples");
JMenuItem orangeItem = new JRadioButtonMenuItem("Oranges");
JMenuItem bannanaItem = new JRadioButtonMenuItem("Bannanas");// Use instance variables to keep track of a popup menu and its items
JPopupMenu popupMenu = new JPopupMenu();
JMenuItem helpItem = new JMenuItem("help");
JMenuItem inspectItem = new JMenuItem("inspect");// Add a constructor for our frame.
public FileMenuExample(String title) {super(title);}// Create a menu bars and its pull-down menus
JMenuBar menuBar = new JMenuBar();
JMenu fileMenu = new JMenu("File");
JMenu editMenu = new JMenu("Edit");
JMenu settingsMenu = new JMenu("Settings");
JMenu searchMenu = new JMenu("Search");// set menu accelerators for Alt keys
fileMenu.setMnemonic('F');
editMenu.setMnemonic('E');
settingsMenu.setMnemonic('S');
newItem.setMnemonic('N');
openItem.setMnemonic('O');// set receiver as the object to handle menu item selection requests
newItem.addActionListener(this);
openItem.addActionListener(this);
saveAsItem.addActionListener(this);
thinkItem.addActionListener(this);
copyItem.addActionListener(this);
findItem.addActionListener(this);
replaceItem.addActionListener(this);
helpItem.addActionListener(this);
inspectItem.addActionListener(this);ButtonGroup fruits = new ButtonGroup();
fruits.add(appleItem);
fruits.add(orangeItem);
fruits.add(bannanaItem);// add menu items in the menus
fileMenu.add(newItem);
fileMenu.add(openItem);
fileMenu.add(saveAsItem);
editMenu.add(thinkItem);
editMenu.add(copyItem);
searchMenu.add(findItem);
searchMenu.add(replaceItem);
settingsMenu.add(appleItem);
settingsMenu.add(orangeItem);
settingsMenu.add(bannanaItem);// add items to the popup menu
popupMenu.add(helpItem);
popupMenu.add(inspectItem);//create the cascaded menu
editMenu.add(searchMenu);// add menus to the menu bar
menuBar.add(fileMenu);
menuBar.add(editMenu);
menuBar.add(settingsMenu);// add menu bar to window and popup menu to the window pane
setJMenuBar(menuBar);// add popup menu to the window pane
popupMenu.setInvoker(getContentPane());// register the event handler for the popup menu
getContentPane().addMouseListener(new MouseInputAdapter() {
public voidmouseClicked(MouseEvent event){
if (event.getModifiers() == InputEvent.BUTTON3_MASK)
popupMenu.show(getContentPane(), 100, 100);
}});
// Set the background of the frame
setBackground(Color.lightGray);
// dispatch menu selections
public void actionPerformed(ActionEvent event){if (event.getSource() == newItem)}
reactToNewMenuSelection();
else if (event.getSource() == openItem)
reactToOpenMenuSelection();
else if (event.getSource() == saveAsItem)
reactToSaveAsMenuSelection();
else if (event.getSource() == copyItem)
reactToCopyMenuSelection();
else if (event.getSource() == thinkItem)
reactToThinkMenuSelection();
else if (event.getSource() == findItem)
reactToFindMenuSelection();
else if (event.getSource() == replaceItem)
reactToReplaceMenuSelection();
else if (event.getSource() == helpItem)
reactToHelpMenuSelection();
else if (event.getSource() == inspectItem)
reactToInspectMenuSelection();
// Here are all the react methods for the menu items
public void reactToNewMenuSelection() {
System.out.println("reacting to NEW selection from menu");
}
public void reactToOpenMenuSelection() {
System.out.println("reacting to OPEN selection from menu");
}
public void reactToSaveAsMenuSelection() {
System.out.println("reacting to SAVE AS selection from menu");
}
public void reactToThinkMenuSelection() {
System.out.println("reacting to THINK selection from menu");
}
public void reactToCopyMenuSelection() {
System.out.println("reacting to COPY selection from menu");
}
public void reactToFindMenuSelection() {
System.out.println("reacting to FIND selection from menu");
}
public void reactToReplaceMenuSelection() {
System.out.println("reacting to REPLACE selection from menu");
}
public void reactToHelpMenuSelection() {
System.out.println("reacting to HELP selection from popup menu");
}
public void reactToInspectMenuSelection() {
System.out.println("reacting to INSPECT selection from popup menu");
}
public static void main(String args[]) {
FileMenuExample frame = new FileMenuExample("FileMenu Example");
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setSize(300, 300);
frame.setVisible(true);
}
| 5.3 Dialog Boxes |

Notice that the model is used as the "middle-man" between the two windows:
import javax.swing.*;We also pass the client as a parameter to the dialog box so that the dialog box can send one of these two interface messages to the client upon closing. The dialogFinished message is sent when the OK button is clicked, otherwise the dialogCancelled is sent.
public interface DialogClientInterface {
public void dialogFinished(JDialog aDialog);
public void dialogCancelled(JDialog aDialog);
}
Here is a BankAccountDialog that modifies a BankAccount's owner name. We use the BankAccount class that was used in 95.105. In this example, we'll just bring up the dialog box directly, but the client will be simple, with no window.
To start, we'll make a JPanel to form the "view" for the dialog box:
// Make a get method so that the
owner can access this component
public JTextField getOwnerTextField() { return ownerTextField;
}
// Add a constructor that takes
a BankAccount
public
BankAccountPanel (BankAccount account) {
// Fill
in the components with bank account information
ownerTextField.setText(account.getOwnerName());
idTextField.setText(String.valueOf(account.getAccountNumber()));
balanceTextField.setText(String.valueOf(account.getBalance()));
//
Disallow changing of balance and bank account number
balanceTextField.setEnabled(false);
idTextField.setEnabled(false);
// Set
the layoutManager and add the components
setLayout(new
GridLayout(3,3,5,5));
add(new JLabel("Name:"));
add(ownerTextField);
add(new JLabel("ID:"));
add(idTextField);
add(new JLabel("Balance"));
add(balanceTextField);
}
}
public static void main(String args[]) {
JFrame frame = new JFrame("Test for BankAccount Panel");
frame.getContentPane().add(new BankAccountPanel(new BankAccount("Bob", 100)));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 100);
frame.setVisible(true);JFrame frame2 = new JFrame("Test for BankAccount Panel");
frame2.getContentPane().add(new BankAccountPanel(new BankAccount("Betty", 500)));
frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame2.setSize(300, 100);
frame2.setVisible(true);
}
Now we'll make the actual Dialog box. This is like a combined "controller" and "view" for the interface which will handle the button presses and model changes accordingly. Here is what it will look like:

Notice that the ID and Balance are "greyed out". This indicates that
they are disabled and cannot be changed.
Here is the code:
public class BankAccountDialog
extends JDialog {
// Store a pointer to the model for changes later
private
BankAccount account;
// The buttons and main
panel
private JButton okButton =
new JButton("OK");
private JButton cancelButton = new
JButton("Cancel");
private BankAccountPanel bankAccountPanel;
// The client (i.e. caller of
this dialog box)
private
DialogClientInterface client;
// A constructor that takes the
model and client as parameters
public BankAccountDialog(Frame owner, String
title, boolean modal,
BankAccount anAccount, DialogClientInterface aClient){
super(owner,title,modal);
// Store
the model and client into instance variables
client = aClient;
account = anAccount;
// Make
the dialog box by adding the panel and buttons
bankAccountPanel =
new BankAccountPanel(account);
JPanel panel = new
JPanel();
panel.setLayout(new GridLayout(1,2,5,5));
getContentPane().setLayout(new GridLayout(2,1,5,5));
getContentPane().add(bankAccountPanel);
panel.add(okButton);
panel.add(cancelButton);
getContentPane().add(panel);
//
Listen for ok button click
okButton.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent
event){
okButtonClicked();
}
}
);
//
Listen for cancel button click
cancelButton.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent
event){
cancelButtonClicked();
}
}
);
//
Listen for window closing: treat like cancel button
addWindowListener(
new WindowAdapter() {
public
void windowClosing(WindowEvent event) {
cancelButtonClicked();
}
}
);
}
// Normal termination of
Dialog
private void okButtonClicked(){
//
Update model to show changed owner name
account.setOwnerName(bankAccountPanel.getOwnerTextField().getText());
if (client !=
null)
client.dialogFinished(this);
dispose();
}
// Cancel termination of
Dialog
private void
cancelButtonClicked(){
if (client != null)
client.dialogCancelled(this);
dispose();
}
}
import java.awt.*;
import
java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class BankAccountDialogTester extends Object implements
DialogClientInterface {
private
BankAccount account = new BankAccount("Dwight", 500.0f);
public BankAccountDialogTester(){
BankAccountDialog dialog
= new BankAccountDialog (null,
"Bank Account Dialog", true, account,
this);
System.out.println("Here is the original account: " + account);
System.out.println("About to open the dialog box ...");
dialog.setSize(200,
200);
dialog.setVisible(true);
// This
line should never be displayed
System.out.println("Finished openning the dialog box !");
}
public void dialogFinished(JDialog aDialog){
System.out.println(account);
System.exit(0);
}
public void dialogCancelled(JDialog aDialog){
System.out.println(account);
System.exit(0);
}
public static void main(String
args[]) {
new
BankAccountDialogTester();
}
}
| 5.4 Standard Dialog Boxes |
When using a dialog box, you get to specify:

Here are the dialog boxes that will appear.
Plain Message Box:
Information Message Box:
Error Message Box:
Information Message Box:
Confirmation Dialog Box:
Confirmation Dialog Box with Cancel:
Select Option Dialog Box:
Input Dialog Box:
Option Dialog Box:
Here is the code:
import java.awt.*;
import
java.awt.event.*;
import javax.swing.*;
// Dialog Box Test Program
public class StandardDialogTester
extends JFrame implements ActionListener {
public StandardDialogTester (String title) {
super(title);
getContentPane().setLayout(new GridLayout(3, 3));
JButton aButton = new
JButton("Plain Message Box");
getContentPane().add(aButton);
aButton.addActionListener(this);
aButton = new
JButton("Warning Message Box");
getContentPane().add(aButton);
aButton.addActionListener(this);
aButton = new
JButton("Error Message Box");
getContentPane().add(aButton);
aButton.addActionListener(this);
aButton = new
JButton("Information Message Box");
getContentPane().add(aButton);
aButton.addActionListener(this);
aButton = new
JButton("Confirmation Dialog Box");
getContentPane().add(aButton);
aButton.addActionListener(this);
aButton = new
JButton("Confirmation Dialog Box with Cancel");
getContentPane().add(aButton);
aButton.addActionListener(this);
aButton = new
JButton("Multiple Option Dialog Box");
getContentPane().add(aButton);
aButton.addActionListener(this);
aButton = new
JButton("Input Dialog Box");
getContentPane().add(aButton);
aButton.addActionListener(this);
aButton = new
JButton("Chooser Dialog Box");
getContentPane().add(aButton);
aButton.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
if
(e.getActionCommand().equals("Plain Message Box"))
{
JOptionPane.showMessageDialog(this, "This is a plain
message !!!",
"Read This", JOptionPane.PLAIN_MESSAGE);
}
else if
(e.getActionCommand().equals("Warning Message
Box")) {
JOptionPane.showMessageDialog(this, "Don't eat yellow
snow.", "Warning",
JOptionPane.WARNING_MESSAGE);
}
else if
(e.getActionCommand().equals("Error Message Box"))
{
JOptionPane.showMessageDialog(this,
"Your program has stopped working !", "Error",
JOptionPane.ERROR_MESSAGE);
}
else if
(e.getActionCommand().equals("Information Message
Box")) {
JOptionPane.showMessageDialog(this, "You better pass
the final exam " +
"or else...", "Information", JOptionPane.INFORMATION_MESSAGE);
}
else if
(e.getActionCommand().equals("Confirmation Dialog
Box")) {
int
result = JOptionPane.showConfirmDialog(this, "Do you
want me to erase "
+ "your hard drive ?", "Answer
this Question",
JOptionPane.YES_NO_OPTION);
if
(result == 0)
System.out.println("OK, I'm erasing it now
...");
else
System.out.println("Fine then, you clean it
up!");
}
else if
(e.getActionCommand().equals("Confirmation Dialog Box with
Cancel")) {
int
result = JOptionPane.showConfirmDialog(this, "Do you
want to " +
"overwrite the file ?", "Answer
this Question",
JOptionPane.YES_NO_CANCEL_OPTION);
switch(result) {
case
0: System.out.println("OK, but don't come crying to me once
its gone");break;
case
1: System.out.println("Well you should pick a new name
then");break;
case
2: System.out.println("OK, I'll ask you again
later");break;
}
}
else if
(e.getActionCommand().equals("Multiple Option Dialog
Box")) {
Object[] options = { "Outstanding", "Excellent", "Good", "Fair", "Poor" };
int
result = JOptionPane.showOptionDialog(this, "What do
you think of " +
"these notes ?", "Pick an
Option", JOptionPane.DEFAULT_OPTION,
JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
System.out.print("So,...,you think the notes are " +
options[result] + " ...");
if
(result < 3)
System.out.println("Thank you!");
else
System.out.println("but I put a lot of work into them
!");
}
else if
(e.getActionCommand().equals("Input Dialog Box"))
{
String inputValue = JOptionPane.showInputDialog("Please
input your name");
System.out.println("Your name is " +
inputValue);
}
else if
(e.getActionCommand().equals("Chooser Dialog Box"))
{
Object[] options = { "Apple", "Orange", "Strawberry", "Bannana", "Cherry" };
Object selectedValue = JOptionPane.showInputDialog(this,
"Choose your favorite fruit", "Fruit Information",
JOptionPane.INFORMATION_MESSAGE, null, options, options[1]);
System.out.println(selectedValue + "s sure do taste
yummy.");
}
}
public static void main(String
args[]) {
StandardDialogTester frame = new StandardDialogTester("Standard Dialog
Tester");
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.pack(); //chooses reasonable window size based on component prefered
sizes
frame.setVisible(true);
}
}
Notice when running the code the output that appears in the console. You should be able to figure out how to get information easily from your dialog boxes from this example.
There is another useful standard dialog box in Java that is used for selecting files. It is called a JFileChoser.
Here is what it looks like:

Here is some code that opens up a FileChoser dialog box and displays the filename (no path) that the user selects.
JFileChooser chooser = new JFileChooser();
int
returnVal = chooser.showOpenDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION)
{
System.out.println("You chose to open this file: "
+
chooser.getSelectedFile().getName());
}
There are more options available that allow you to set the filters and
starting directories. Take a look at the Swing API.
| 5.5 E-mail Buddy Dialog Box Example |
What exactly is an e-mail buddy ? Well we've decided what information is to be kept, so we can easily develop a model of an EmailBuddy as follows:
// This class represents a "buddy" whose email
address is kept.
// An additional
boolean indicates whether or not this is a
// friend that is "hot" (i.e. contacted often)
public class EmailBuddy
{
private String name;
private String address;
private boolean onHotList;
// Here are some
constructors
public EmailBuddy() {
name = "";
address = "";
onHotList = false;
}
public EmailBuddy(String aName, String anAddress) {
name = aName;
address = anAddress;
onHotList = false;
}
// Here are the get
methods
public String getName() {
return name; }
public String
getAddress() { return address; }
public boolean onHotList() { return onHotList; }
// Here are the set
methods
public void
setName(String newName) { name = newName; }
public void setAddress(String newAddress) { address = newAddress;
}
public void onHotList(boolean
onList) { onHotList = onList; }
// The appearance of the
buddy
public String toString()
{
return(name);
}
}
As can be seen, there is nothing difficult here ... just your standard "run-of-the-mill" model class. However, this class along is not really the model since we will have many of these EmailBuddy objects. So, we'll make a Vector of them when we make the interface.

Notice that the interface does not show the e-mail addresses in the list. It would be kinda cluttered looking. Perhaps we could have made a second list box or something that would show the e-mail addresses. Here is a good exercise: make a JTextField just beneath the list that will show the e-mail address of the currently selected Buddy in the list. This is not hard to do. Nevertheless, it is not necessary for the purposes of explaining this dialog box example.
How can we build the view for this interface ? We'll start with a JPanel. We will use GridBagLayout to allow nice resizing.
import java.awt.*;
import
java.awt.event.*;
import javax.swing.*;
// This is the Panel that contains represents the
view of the
// Email buddy
application.
public class EmailBuddyPanel
extends JPanel {
private JButton addButton;
private JButton removeButton;
private JList
buddyList;
private JCheckBox
hotListButton;
// These are the get methods that
are used to access the components
public JButton getAddButton() { return addButton; }
public JButton getRemoveButton() {
return removeButton; }
public
JCheckBox getHotListButton() { return hotListButton; }
public JList getBuddyList() { return
buddyList; }
// This is the default
constructor
public EmailBuddyPanel(){
super();
// Use a
GridBagLayout (lotsa fun)
GridBagLayout layout =
new GridBagLayout();
GridBagConstraints
layoutConstraints = new GridBagConstraints();
setLayout(layout);
// Add the
buddy list
buddyList = new JList();
buddyList.setPrototypeCellValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
JScrollPane scrollPane =
new JScrollPane( buddyList,
ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
layoutConstraints.gridx =
0;
layoutConstraints.gridy = 0;
layoutConstraints.gridwidth =
3;
layoutConstraints.gridheight = 5;
layoutConstraints.fill =
GridBagConstraints.BOTH;
layoutConstraints.insets = new Insets(10, 10, 10, 10);
layoutConstraints.anchor =
GridBagConstraints.NORTHWEST;
layoutConstraints.weightx =
1.0;
layoutConstraints.weighty = 1.0;
layout.setConstraints(scrollPane, layoutConstraints);
add(scrollPane);
// Add the
Add button
addButton = new JButton("Add");
layoutConstraints.gridx =
3;
layoutConstraints.gridy = 0;
layoutConstraints.gridwidth =
1;
layoutConstraints.gridheight = 1;
layoutConstraints.fill =
GridBagConstraints.BOTH;
layoutConstraints.insets = new Insets(10, 10, 10, 10);
layoutConstraints.anchor =
GridBagConstraints.EAST;
layoutConstraints.weightx = 0.0;
layoutConstraints.weighty =
0.0;
layout.setConstraints(addButton, layoutConstraints);
add(addButton);
// Add the
Remove button
removeButton = new JButton("Remove");
layoutConstraints.gridx =
3;
layoutConstraints.gridy = 1;
layoutConstraints.gridwidth =
1;
layoutConstraints.gridheight = 1;
layoutConstraints.fill =
GridBagConstraints.BOTH;
layoutConstraints.insets = new Insets(10, 10, 10, 10);
layoutConstraints.anchor =
GridBagConstraints.EAST;
layoutConstraints.weightx = 0.0;
layoutConstraints.weighty =
0.0;
layout.setConstraints(removeButton, layoutConstraints);
add(removeButton);
// Add the
ShowHotList button
hotListButton = new
JCheckBox("Show Hot List");
layoutConstraints.gridx =
3;
layoutConstraints.gridy = 3;
layoutConstraints.gridwidth =
1;
layoutConstraints.gridheight = 1;
layoutConstraints.fill =
GridBagConstraints.BOTH;
layoutConstraints.insets = new Insets(10, 10, 10, 10);
layoutConstraints.anchor =
GridBagConstraints.EAST;
layoutConstraints.weightx = 0.0;
layoutConstraints.weighty =
0.0;
layout.setConstraints(hotListButton, layoutConstraints);
add(hotListButton);
}
}
Notice that there is nothing really new here either. This is just like
a review. We did however, make some get methods for the components so that
we can access them from outside this class.
Here are some more questions that need to be answered:

Don't forget that we needed to add the OK and CANCEL buttons as well. Also, there is no need to be able to resize the dialog box so we can just disable the resizing.
Here is a method that will be called from our dialog class to add the components to the dialog box. It will take as parameters the container (i.e. from a call to getContentPane()) and an EmailBuddy object. We pass in the container so that all components are added to it. Can you figure out why we'd pass in a Buddy ? Well, when the dialog box opens, we'll want to have some values appearing in the text fields indicating the Buddy's information. This parameter will represent the model to which the dialog box affects.
// This code adds the necessary
components to the interface
private void buildDialogWindow(Container aContainer, EmailBuddy
aBuddy) {
// Use no
layout
aContainer.setLayout(null);
// Add the
name label
aLabel
= new JLabel("Name:");
aLabel.setLocation(10,10);
aLabel.setSize(80, 30);
aContainer.add(aLabel);
// Add the
name field
nameField = new JTextField(aBuddy.getName());
nameField.setLocation(110,
10);
nameField.setSize(400, 30);
aContainer.add(nameField);
// Add the
address label
aLabel = new JLabel("Address:");
aLabel.setHorizontalAlignment(JLabel.LEFT);
aLabel.setLocation(10,50);
aLabel.setSize(80, 30);
aContainer.add(aLabel);
// Add the
address field
addressField = new JTextField(aBuddy.getAddress());
addressField.setLocation(110,
50);
addressField.setSize(400, 30);
aContainer.add(addressField);
// Add the
onHotList button
hotListButton = new JCheckBox("On Hot
List");
hotListButton.setSelected(aBuddy.onHotList());
hotListButton.setLocation(110, 100);
hotListButton.setSize(120,
30);
aContainer.add(hotListButton);
// Add the
Ok button
okButton = new JButton("Ok");
okButton.setLocation(300,
130);
okButton.setSize(100, 40);
aContainer.add(okButton);
// Add the
Cancel button
cancelButton = new JButton("Cancel");
cancelButton.setLocation(410,
130);
cancelButton.setSize(100, 40);
aContainer.add(cancelButton);
}
We'll now look at the code needed to create the dialog box and get its behaviour working correctly.
import java.awt.*;
import
java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class BuddyDetailsDialo extends JDialog {
// This is a pointer to the email
buddy that is being edited
private
EmailBuddy aBuddy;
// This is the client that is
informed when the dialog box is closed
private DialogClientInterface client;
// These are the components of the
dialog box
private
JLabel aLabel;
private JTextField
nameField;
private
JTextField addressField;
private JCheckBox hotListButton;
private
JButton okButton;
private
JButton cancelButton;
public BuddyDetailsDialog(Frame owner, String title,
boolean modal,
EmailBuddy bud, DialogClientInterface cli){
super(owner,title,modal);
// Store
these parameters into the instance variables
client = cli;
aBuddy = bud;
// Put all
the components onto the window and given them initial values
buildDialogWindow(getContentPane(), aBuddy);
// Add
listeners for the Ok and Cancel buttons as well as window closing
okButton.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent event){
okButtonClicked();
}
}
);
cancelButton.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent event){
cancelButtonClicked();
}
}
);
addWindowListener(
new WindowAdapter() {
public void windowClosing(WindowEvent event) {
cancelButtonClicked();
}
}
);
// Set the
size of the window
setSize(526, 214);
}
// This code adds the necessary
components to the interface
private void buildDialogWindow(Container aContainer, EmailBuddy
aBuddy) {
// This code is given above
}
private void okButtonClicked(){
aBuddy.setName(nameField.getText());
aBuddy.setAddress(addressField.getText());
aBuddy.onHotList(hotListButton.isSelected());
if (client !=
null)
client.dialogFinished(this);
dispose();
}
private void cancelButtonClicked(){
if (client !=
null)
client.dialogCancelled(this);
dispose();
}
}
Once again, we see that we just add listeners for the OK and CANCEL buttons as well as the window closing event. Then we merely make methods that are called for each.
Notice that when the ok button is clicked, the 3 pieces of changed
buddy data are stored in the model buddy so that the buddy will have been
altered by this dialog box. Then we inform the client that OK was
pressed. For the cancel button, there is no work to do, just informing the
client that CANCEL was pressed.
We'll call the class EmailBuddyApp and it will extend JFrame. It will be the class that opens the dialog box and so it must implement the DialogClientInterface. We'll need to store the buddies that we'll be making, so we make a vector as an instance variable. We'll first make the application work such that we'll be able to add buddies to the list. Here is the basic framework for the application:
import java.awt.*;
import
java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import
java.util.*;
public class EmailBuddyApp
extends JFrame implements DialogClientInterface {
// Store the model as a vector of email buddies
private Vector
buddies;
// Store the view that contains
the components
EmailBuddyPanel view;
// Here are the component
listeners
ActionListener theAddButtonListener;
// Here is the default
constructor
public EmailBuddyApp(String title){
super(title);
//
Initially, no buddies
buddies = new
Vector();
// Make a
new viewing panel and add it to the pane
view = new
EmailBuddyPanel();
getContentPane().add(view);
// Make a
listener for the add button
theAddButtonListener =
new ActionListener() {
public
void actionPerformed(ActionEvent event){
addBuddy();
}
};
// Start
off with everything updated properly
update();
}
// Enable all
listeners
private void
enableListeners() {
view.getAddButton().addActionListener(theAddButtonListener);
}
// Disable all
listeners
private void
disableListeners() {
view.getAddButton().removeActionListener(theAddButtonListener);
}
// This is called when the user
clicks the add button
private
void addBuddy() {
EmailBuddy aBuddy = new EmailBuddy();
// Add the
buddy to the end of the Vector
buddies.addElement(aBuddy);
// Now
bring up the dialog box
BuddyDetailsDialog dialog =
new BuddyDetailsDialog(null, "Buddy Details
Dialog",
true, aBuddy, this);
dialog.setVisible(true);
}
// Called when the dialog box is
closed with the Ok button
public
void dialogFinished(JDialog aDialog) {
update();
}
// Called when the dialog box is
closed with the cancel button or manually closed
public void dialogCancelled(JDialog
aDialog) {
// Remove the latest buddy that was added if in add
mode
buddies.removeElement(buddies.lastElement());
}
// Update the list
private void updateList() {
// Update
the list contents and select the last buddy
view.getBuddyList().setListData(buddies);
view.getBuddyList().setSelectedValue((EmailBuddy)buddies.lastElement(),
true);
}
// Update the GUI
private void update() {
disableListeners();
updateList();
enableListeners();
}
// Code that starts the
application
public static
void main(String args[]) {
EmailBuddyApp frame =
new EmailBuddyApp("Email Buddy
Application");
frame.setSize(600,300);
frame.setVisible(true);
}
}
Perhaps the most interesting portions of the code are the addBuddy, dialogCancelled and updateList() methods. When the user adds a buddy, we:
if (aBuddy !=
null) {
buddies.remove(aBuddy);
update();
}
}
private void updateRemove() {
view.getRemoveButton().setEnabled(view.getBuddyList().
getSelectedValue() != null);
}
for
(int i=0; i<buddies.size(); i++) {
EmailBuddy aBuddy = (EmailBuddy)buddies.get(i);
if
(aBuddy.onHotList())
temp.add(aBuddy);
}
view.getBuddyList().setListData(temp);
}
else
view.getBuddyList().setListData(buddies);
}
What if we want to edit a buddy, not just add one ? We will have to decide what action will cause the editing to take place. One approach is to have the user double click on the buddy in the list and the dialog box will come up with that buddy's details within it. We can then make changes to the data and close the dialog box.
To do this, notice that we currently have some small problems:
Here is the final code. Notice that we've added a selectedBuddy instance variable which is used throughout.
import java.awt.*;
import
java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import
java.util.*;
public class EmailBuddyApp
extends JFrame implements DialogClientInterface {
// Store the model as a vector of
email buddies
private
Vector buddies;
private EmailBuddy selectedBuddy;
private boolean inAddMode;
// Store the view that contains
the components
EmailBuddyPanel view;
// Here are the component
listeners
ActionListener
theAddButtonListener;
ActionListener
theRemoveButtonListener;
ActionListener hotListListener;
ListSelectionListener
buddyListSelectionListener;
MouseListener
doubleClickSelectionListener;
// Here is the default
constructor
public EmailBuddyApp(String title){
super(title);
buddies = new
Vector();
selectedBuddy
= null;
inAddMode
= false;
// Make a
new viewing panel and add it to the pane
view = new
EmailBuddyPanel();
getContentPane().add(view);
// Make a
listener for the add button
theAddButtonListener =
new ActionListener() {
public
void actionPerformed(ActionEvent event){
addBuddy();
}
};
// Make a
listener for the revove button
theRemoveButtonListener =
new ActionListener() {
public
void actionPerformed(ActionEvent event){
removeBuddy();
}
};
// Make a
listener for the hot list button
hotListListener = new
ActionListener() {
public
void actionPerformed(ActionEvent event){
toggleHotList();
}
};
// Make a
listener to allow selection of buddies from the list
buddyListSelectionListener =
new ListSelectionListener() {
public
void valueChanged(ListSelectionEvent event){
selectBuddy();
}
};
// Make a
listener to allow double click selections from the list for editing
doubleClickSelectionListener
= new MouseAdapter() {
public
void mouseClicked(MouseEvent event){
if
(event.getClickCount() == 2)
editBuddy();
}
};
// Start
off with everything updated properly
update();
}
// Enable all
listeners
private void
enableListeners() {
view.getAddButton().addActionListener(theAddButtonListener);
view.getRemoveButton().addActionListener(theRemoveButtonListener);
view.getHotListButton().addActionListener(hotListListener);
view.getBuddyList().addListSelectionListener(buddyListSelectionListener);
view.getBuddyList().addMouseListener(doubleClickSelectionListener);
}
// Disable all
listeners
private void
disableListeners() {
view.getAddButton().removeActionListener(theAddButtonListener);
view.getRemoveButton().removeActionListener(theRemoveButtonListener);
view.getHotListButton().removeActionListener(hotListListener);
view.getBuddyList().removeListSelectionListener(buddyListSelectionListener);
view.getBuddyList().removeMouseListener(doubleClickSelectionListener);
}
// This is called when the user
clicks the add button
private
void addBuddy() {
EmailBuddy aBuddy = new EmailBuddy();
// Add the
buddy to the end of the Vector
buddies.add(aBuddy);
selectedBuddy = aBuddy;
inAddMode = true;
// Now
bring up the dialog box
BuddyDetailsDialog dialog =
new BuddyDetailsDialog(null, "Buddy Details
Dialog",
true, aBuddy, this);
dialog.setVisible(true);
//No need
to call update() here since dialogFinished() calls it for us
}
// This is called when the user
clicks the remove button
private
void removeBuddy() {
// Remove the currently
selected buddy from the list
if (selectedBuddy !=
null) { //not needed since Remove Button is disabled
when nobody is selected
buddies.remove(selectedBuddy);
update();
}
}
// This is called when the user
selects a buddy from the list
private void selectBuddy() {
selectedBuddy =
(EmailBuddy)(view.getBuddyList().getSelectedValue());
update();
}
// This is called when the user
double clicks on an item in the list
private void editBuddy() {
// Now
bring up the dialog box
inAddMode =
false;
BuddyDetailsDialog dialog = new BuddyDetailsDialog(null, "Buddy Details Dialog",
true, selectedBuddy, this);
dialog.setVisible(true);
//No need to call
update() here since dialogFinished() calls it for us
}
// This is called when the user
clicks the hot list button
private
void toggleHotList() {
update();
}
// Called when the dialog box is
closed with the Ok button
public
void dialogFinished(JDialog aDialog) {
update();
}
// Called when the dialog box is
closed with the cancel button or manually closed
public void dialogCancelled(JDialog
aDialog) {
if
(inAddMode) {
// Remove the latest buddy that was added if in add mode
buddies.remove(buddies.lastElement());
selectedBuddy = null;
}
inAddMode =
false;
update(); // Not really needed since nothing has
changed
}
// Update the remove
button
private void
updateRemove() {
view.getRemoveButton().setEnabled(selectedBuddy != null);
}
// Update the list
private void updateList() {
boolean foundSelected =
false;
// If the
hot list is on, find all buddies that are on the hot list
if
(view.getHotListButton().isSelected()) {
Vector temp = new Vector();
for
(int i=0; i<buddies.size(); i++) {
EmailBuddy aBuddy = (EmailBuddy)buddies.get(i);
if
(aBuddy.onHotList()) {
temp.add(aBuddy);
if (aBuddy == selectedBuddy)
foundSelected = true;
}
}
view.getBuddyList().setListData(temp);
if
(!foundSelected)
selectedBuddy = null;
}
else
view.getBuddyList().setListData(buddies);
if (selectedBuddy !=
null)
view.getBuddyList().setSelectedValue(selectedBuddy, true);
}
// Update the GUI
private void update() {
disableListeners();
updateList();
updateRemove();
enableListeners();
}
// Code that starts the
application
public static
void main(String args[]) {
EmailBuddyApp frame =
new EmailBuddyApp("Email Buddy
Application");
frame.setSize(600,300);
frame.setVisible(true);
}
}