Lecture 8
Containers
Read
on for an overview of some Swing containers - JPanels , JFrames,
JMenus and JDialogs .
Container
Basics
Swing
Containers
Adding
Components To Containers
Panels
Creating
Panels
Nesting
Panels
Menus
Menu
Hierarchy
Creating
Menus
Popup
Menus
Dialogs
Creating
Standard Ok Dialogs
Creating
Yes/No/Cancel Dialog
Customising
the Standard Dialogs
Frames
Creating
Frames
Applets
that Run Application
Container
Basics
Containers can contain
components and other containers. You need to know about some of most useful
Swing containers, how to add containers to other containers and how to add
components to a container.
Swing
Containers
A container is a
component, which can contain other components. Examples of Swing containers
would be JPanels , JFrames , JDialogs and JApplets .
Containers help you organise placing of components. You cannot use a
component unless it is placed within a container. A JMenu is
usually considered to be a component but it can contain menu items.
Remember, all Swing components
and containers start with the letter J .
Top-Level
& General Containers
JApplets ,
JDialogs and JFrames are
examples of top-level containers. A JPanels is a general
container. Also, an JApplet is
a subclass of the Panel class. So really a JApplet
is a kind of Panel .
|
A
pure container. It is not a window; it's sole purpose is to help you
organise your components. A JPanel is a general purpose
container.
|
|
A fully functioning window which may contain a pull-down menu and have a border,
a title and buttons for closing it. Applications typically us a Frame .
|
|
A pop-up window generally used to
display message to users.
Example: - "Are you sure you
want to quit without saving?"
|
|
A subclass of Applet .
JApplets are run by
browsers just like Applets .
|
Note:
-- When using Swing components you must import the Swing package:-
import javax.swing.*;
Most Swing programs also need to
import the two main AWT packages:
import java.awt.*;
import java.awt.event.*;
Finally, if you want
to use Swing components in an applet , you need to use JApplet .
Your class declaration would be:-
public class
AnApplet extends JApplet {
|
Adding
Components to Containers
A component is placed
into a container using the add method. The syntax is:-
container.add(component
or container reference);
As an example,
let's create an applet and add a JButton to to it.
Remember a
JApplet is a subclass of Panel so a JApplet is a container to which we can
add
components and other containers.
import
javax.swing.*;
import java.awt.*;
public class SwingApplet extends JApplet {
public void init() {
JButton myFirstButton = new
JButton("First Button");
getContentPane().add(myFirstButton);
}
}
|
Let's
explain the code.
The
line:-
JButton myFirstButton = new
JButton("First Button");
creates
a new instance of a JButton which is referenced by the
variable myFirstButton . This JButton instance
will have the caption "First Button". You can name
your variable something other than myFirstButton if you wish.
Now,
every
top-level container contains an intermediate container known as a content
pane . As a rule, the content pane
of a container holds any components added to the container.
An
applet window has a content pane to which components
can be added. So the line:-
getContentPane().add(myFirstButton);
added
the JButton
instance to the content pane of the applet.
Now,
my HTML code for this applet is:-
<html>
<body>
<applet
code="SwingApplet.class" width = 100
height = 50 > </applet>
</body>
</html>
|
Look
at what happens to my button if I increase the size of my applet window from 100
by 50 to say to 200 by 100 .
I
guess my button is being drawn the exact size of the applet drawing area or content
pane .
There
are a few ways of controlling the size and positioning of components in a
container. We shall investigate using containers within containers, in
particular Panels .
Panels
Panels
are convenient for organising components. The only thing you can do with a
Panel is place other components within it.
Creating
Panels
You can create a
Swing Panel as follows:-
JPanel myPanel
= new JPanel();
This creates an
instance of a JPanel which is referenced by the variable myPanel
.
Once we have a JPanel
we can add it to another container. An applet content pane
for example. Remember, the syntax for adding components or containers to a
container is:-
container.add(component
or container reference);
So to add a JPanel
to the content pane of an applet we would type:-
getContentPane().add(myPanel);
Let's change our
previous code to the following. The changes are shown in bold font:-
import javax.swing.*;
import java.awt.*;
public class SwingApplet extends JApplet {
public void init() {
JPanel myPanel = new JPanel();
JButton myFirstButton = new JButton("First Button");
getContentPane().add(myPanel);
myPanel.add(myFirstButton);
}
}
|
This time a JPanel
instance was created and referenced by a variable called myPanel :-
JPanel myPanel = new JPanel();
This time, the JPanel instance was added to the content pane
of the applet:-
getContentPane().add(myPanel);
The JButton instance referenced by myFirstButton
is then added to the JPanel :-
myPanel.add(myFirstButton);
The applet window
above is set to 200 by 100 . However, now the
button does not take up the whole of the applet window.
We can add some code
to see where the edges of containers are. This will help you in later exercises.
Add the following line to the bottom of the previous init method.
myPanel.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(Color.red),myPanel.getBorder()));
|
Don't worry too much
about what the line means. Just notice that the borders of the JPanel
are highlighted in red.
Nesting
Panels
We can also nest
panels - place panels within other panels. You can nest panels as many levels
deep as you like. Before we do this, let's create four more buttons
and see how they arrange themselves in one panel.
Add the following code
to end of the init method of your previous code.
JButton secondButton = new JButton("Second Button");
myPanel.add(secondButton);
JButton thirdButton = new JButton("Third Button");
myPanel.add(thirdButton);
JButton fourthButton = new JButton("Fourth Button");
myPanel.add(fourthButton);
JButton fifthButton = new JButton("Fifth Button");
myPanel.add(fifthButton);
|
Some of the buttons
are not shown. Why is this? Well I left the applet window size at 200
by 100 . As shown below, increasing the applet window height
to 200 fixes this.
Try changing the
applet window size to say 300 by 150 . Notice how
the buttons are arranged now.
The default layout for
a Panel is the Flow Layout . This
means components are arranged from left to right in rows. As soon as one
row is full, components are arranged along the next row. We will be
looking at Layout Managers in a future tutorial which
will help us organise components in different ways.
Now let's nest some
panels. Time to start again and create some new code:-
import javax.swing.*;
import java.awt.*;
public class NestedPanels extends JApplet {
public void init() {
JPanel myPanel = new JPanel();
JPanel subPanel2 = new JPanel();
JPanel subPanel1 = new JPanel();
JButton myFirstButton = new JButton("First Button");
JButton secondButton = new JButton("Second Button");
JButton thirdButton = new JButton("Third Button");
JButton fourthButton = new JButton("Fourth Button");
JButton fifthButton = new JButton("Fifth Button");
//add the main panel to the applet content pane
getContentPane().add(myPanel);
myPanel.add(myFirstButton); //add first button to the main panel
myPanel.add(subPanel1); //add a sub panel to the main panel
myPanel.add(subPanel2); //add another sub panel to the main panel
subPanel1.add(secondButton); //add a button to subPanel1
subPanel1.add(thirdButton); //add a button to subPanel2
subPanel2.add(fourthButton); //add a button to subPanel2
subPanel2.add(fifthButton); //add a button to subPanel2
}
}
|
Let's add some code to
the end of the init method so we can see where the borders of each
panel and subpanel are.
myPanel.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(Color.red),myPanel.getBorder()));
subPanel1.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(Color.blue),subPanel1.getBorder()));
subPanel2.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(Color.green),subPanel2.getBorder()));
|
Let's examine the
code. An instance of a Panel was created, referenced by the
variable myPanel . Two other panel instances were created
referenced by the variables subPanel1 and subPanel2 .
Two buttons were added to subPanel1 and two to subPanel2 .
myPanel was added to the content pane of
the applet. Then the JButton instance myFirstButton
was added to myPanel then subPanel1 and then subPanel2 ,
in that order.
The order of adding
containers and components to other containers is important.
~Try the activity~
Activity 8A |
1. Rearrange the order of
adding the subpanels to the main panel so that fourthButton
and fifthButton are placed in a row above secondButton
and thirdButton .
2. Resize your applet
window so that all the buttons are displayed in a row.
|
Menus
You can add menus to
both applets and applications. There are seven menu components you need to
understand:-
Have a quick look at
the menu class hierarchy below.
Menu
Hierarchy
Here is a picture of
the inheritance hierarchy for the menu-related classes:
Surprisingly, it
appears that JMenus and JMenuItems are kind of buttons
since they inherit from the JAbstractButton class.
Creating
Menus
How can you add menus to
applets and applications? First you have to create a JMenuBar
instance. A JMenuBar is a container that will hold JMenu
objects. JMenuItems can then be placed within JMenu
objects.
Let's check out the differences
between JMenuBar s, JMenus and JMenuItems .
Well, a JMenuBar
is just a horizontal container for holding the JMenu objects. Look
at the applet below. The JMenuBar holds a JMenu
object labelled File and another JMenu object
with the title Edit . If you click on the File
menu it will drop down to show you it's JMenuItems . In this
case there are two JMenu Items labelled New
and Open . The Edit JMenu
object does not have any JMenuItems to display.
Click
on each menu - one menu has menu items to display.
Let's start you off
writing the code for creating menus:-
import javax.swing.*;
import java.awt.*;
public class Menu extends JApplet {
public void init() {
//create menubar object
JMenuBar myMenuBar = new JMenuBar();
//set the menubar into the applet window
setJMenuBar(myMenuBar);
//create menu objects
JMenu menuFile = new JMenu("File");
JMenu menuEdit = new JMenu("Edit");
//create menu items
JMenuItem menuItemNew= new JMenuItem("New");
JMenuItem menuItemOpen = new JMenuItem("Open");
//add menus to menu bar
myMenuBar.add(menuFile);
myMenuBar.add(menuEdit);
//add menus items to menus
menuFile.add(menuItemNew);
menuFile.add(menuItemOpen);
}
}
|
So, we can create a JMenuBar
instance with a line like:-
JMenuBar myMenuBar = new
JMenuBar();
and set the JMenuBar
into the applet window using:-
setJMenuBar(myMenuBar);
We can create a JMenu
instance with a line like:-
JMenu menuFile = new JMenu("File");
where the
string in the parentheses will be the JMenu title; in this case "File".
To add JMenus
to the JMenuBar , we just use the J MenuBar's
add method, specifying the name of the JMenu we
wish to add. I.e.
myMenuBar.add(menuFile);
To add JMenu Items
to a JMenu we use the JMenu's add method, specifying
the name of the JMenu Item we wish to add.
I.e.
MenuFile.add(menuItemNew);
~Now
try the activity~
Activity 8B |
1. Create a menu like the
one below, including the separator line in the File
menu and the submenu in the Insert menu.
Click
on each menu.
Hint : the addSeparator
method can be used to add separator lines to menus. E.g. the
line:-
menuFile.addSeparator();
would add a separator line
to my menuFile menu.
Also, to create submenus,
just add a menu to another menu. E.g. suppose I created two menus, one
called menuInsert and the other called subMenuInsert
with some menu items added. Then the line:-
menuInsert.add(subMenuInsert) ;
would add the sub menu subMenuInsert
to the menu menuInsert .
|
Popup
Menus
A popup menu is
invisible until the user makes a specific mouse action, such as pressing the
right mouse button over a component that is popup-enabled. The popup menu then
appears under the mouse cursor.
Here is an example of
a popup menu where the popup-enabled component is the applet window.
Right-click
the applet window.
The code requires
event handlers, so we will wait for the event handling tutorial to examine
code that produces popup menus.
Dialogs
Dialogs are popup
windows that are not as flexible as frames. They are often used to
display messages or for letting the user set application options and settings.
You can create simple standard dialogs using the JOptionPane class
or your own dialogs by creating a custom class that inherits from the JDialog
class.
Three other classes
are useful - ProgressMonitor , JFileChooser and JColorChooser .
ProgressMonitor displays a dialog that shows the progress of an
operation. JFileChooser displays a standard file choosing
dialog. JColorChooser displays a standard color choosing
dialog.
Overview
of Standard Dialogs
Standard dialogs
supplied by the JOptionPane class are modal. This means that the user
cannot supply input to any other window belonging to the application while the
dialog is displayed. A non-modal dialog allow input to other windows
belonging to the application while the dialog is displayed. You must use
the JDialog class directly to create your own dialog if
you want a non-modal dialog.
There are several
standard dialogs you can create using the JOptionPane class.
Some of the JOptionPane methods we can use to creates different types of dialogs
are listed below :-
|
showMessageDialog method
|
|
showConfirmDialog
method
|
|
showOptionDialog
method
|
Creating
Standard OK Dialogs
You can create a
simple OK dialog using the following method:-
showMessageDialog(component
object reference, message string);
The component
object reference argument inside the parentheses expects a reference
to a parent, which must be a frame, an applet, a component inside a frame or
applet, or null. If you specify a frame or an applet, then the dialog will
appear over the center of the frame or applet, and depend on that parent
container.
If you specify a
component inside a frame or applet, then the dialog will appear over the center
of that component, and depend on that component's top container. If you specify
null, then the dialog is generally positioned in the center of the screen, and
the dialog doesn't depend on any visible frame or applet.
The message
string argument inside the parentheses expects a String .
The String will be displayed in the main area of the
dialog.
As an example, suppose
my main container is an applet and I want my dialog to display the message
"Twas brillig and the slithy toves ". Then I would write:-
JOptionPane.showMessageDialog(this,
"Twas brillig and the slithy toves");
I have supplied a component
object reference - this refers to my applet
instance
I have supplied a message string
- "Twas brillig and the slithy toves"
The picture below
shows this dialog:-
Note:
-- You can split the message over several lines by putting
newline (\n ) characters inside the message string. For example:
"Twas brillig \n and the slithy toves"
|
Now,
suppose I want a bit more control over what is displayed in the title bar and
over the icon that displayed. I can use an alternative showMessageDialog
constructor to the one above:-
showMessageDialog(component
object reference, message string, title string, icon type);
This showMessageDialog
constructor has four arguments inside the parentheses, two more than the first showMessageDialog
constructor I used.
The first two arguments
are the same. The next argument title string
expects a String that will be displayed in the title bar of
the dialog. The icon type argument
expects a constant value that refers to the type of icon you wish to be
displayed.
Icons you can have
are...
As an example, suppose
my main container is an applet and I want my dialog to display the message
"Did gyre and gimble in the wabe. " with "Warning"
displayed in the title bar and a warning icon. Then I would write:-
JOptionPane.showMessageDialog(this,
"Did gyre and gimble in the wabe.",
"Warning",
JOptionPane.WARNING_MESSAGE);
I have supplied a component
object reference - this refers to my applet
instance
I have supplied a message string
- "Did gyre and gimble in the wabe."
I have supplied a title
string to be used in the title bar - "Warning"
I have specified a
standard icon type - JOptionPane.WARNING_MESSAGE
The picture below
shows this dialog:-
You
can specify any of the four icon types using:-
Use the applet below
to view the OK dialogs - each with a different icon - and the code I used to
create them.
~Now
try the activity~
Activity 8C |
1. Create an applet that
displays a simple OK dialog, with the message "My
first dialog!" .
2. Change the dialog so
the error icon is used and the message is "My second
dialog." and the title is "A dialog
attempt".
Hint:
just put the code for creating a dialog into the applet's init
method.
|
Creating
Yes/No/Cancel Dialogs
You can create a
simple
Yes/No/Cancel dialog using the following method:-
showMessageDialog(component
object reference, message string);
The component
object reference argument inside the parentheses expects a reference
to a parent, which must be a frame, an applet, a component inside a frame or
applet, or null.
The message
string argument inside the parentheses expects a String .
This String will be displayed in the main area of the
dialog.
As an example of a
Yes/No/Cancel dialog, suppose my main container is an applet and I want my
dialog to display the message "Would you like some more of the poem? "
. Then I would write:-
int result = JOptionPane.showConfirmDialog(
this, "Would you like some more of the poem?");
I have supplied a component
object reference - this refers to my applet
instance
I have supplied a message string
- "Would you like some more of the poem?"
I have supplied a
variable to catch which button the user clicks - int result
The picture below
shows this dialog:-
You can see that by
default the question icon is displayed and three buttons with Yes ,
No and Cancel as button
captions.
The only thing I can
really specify using the simplest JOptionPane.showConfirmDialog constructor
is the message I want displayed in the dialog window.
Now,
suppose I want a bit more control over what is displayed in the title bar and
over the icon that displayed. I can use an alternative showConfirmDialog
constructor to the one above:-
showConfirmDialog(component
object reference, message string, title string, option type, icon type);
This showConfirmDialog
constructor has five arguments inside the parentheses, two more than the first showConfirmDialog
constructor I used.
The arguments specify (in order)...
-
component
object reference - a reference
to a parent, which must be a frame, an applet, a component inside a frame or
applet, or null..
-
message string
- a String
that will be displayed in the main area of the dialog.
-
title string
- a String that will be displayed in the title bar of
the dialog.
-
option type
- the button combination you want
-
icon type
- refers to the standard icon you wish to be
displayed.
As an example of a Yes/No
dialog without the Cancel button, suppose my main container
is an applet and I want my dialog to display the message "How about even more of the poem? " with the string "A Yes/No Dialog"
displayed in the title bar and buttons displaying Yes and No .
Then I would write:-
int result = JOptionPane.showConfirmDialog(
this, "How about even more of the poem?",
"A Yes/No Dialog",
JOptionPane.YES_NO_OPTION);
I have supplied a component
object reference - this refers to my applet
instance
I have supplied a message string
- "How about even more of the poem?"
I have supplied a title string
to be used in the title bar - "A Yes/No Dialog"
I have supplied an option type
specifying the buttons - JOptionPane.YES_NO_OPTION
I haven't
specified an icon type so the default 'question' icon will be
displayed.
I have supplied a
variable to catch which button the user clicks - int result
The picture below
shows this dialog:-
Use the applet below
to view the Confirm dialogs - each with a different icon - and the code I used to
create them.
~Now
try the activity~
Activity 8D |
1. Create an applet that
displays a simple Confirm dialog, with the standard Yes ,
No and Cancel buttons and the message "My
first confirm dialog!" .
2. Change the dialog so
the warning icon is used and the message is "Do you
really want to do this thing?" and the title is "A
Confirm dialog attempt".
Hint:
just put the code for creating a dialog into the applet's init
method.
|
Customising
the Standard Dialogs
You can create a modal
dialog using the following method with more specific buttons than the
standard OK and Confirm dialogs using the following
method:-
showOptionDialog(component
object reference, message string, title string, option type, icon type,
custom icon, object[], object);
This showOptionDialog
constructor has seven arguments inside the parentheses.
The arguments specify (in order)...
-
component
object reference - a reference
to a parent, which must be a frame, an applet, a component inside a frame or
applet, or null..
-
message string
- a String
that will be displayed in the main area of the dialog.
-
title string
- a String that will be displayed in the title bar of
the dialog.
-
option type
- the button combination you want
-
icon type
- refers to the standard icon you wish to be
displayed.
-
custom
icon - refers to a custom icon. Specify null if you
want a standard icon.
-
object[]
- normally refers to an array of Strings for the buttons.
-
object
- refers to the default button to be selected.
Use the applet below
to view my custom dialog - and the code I used to
create it.
You can customise the
standard dialogs in various ways using the showOptionDialog
method. I will leave the subject here.
This section
is OPTIONAL.
Only look at
this if you are way ahead and up-to-date in all tutorials and exercises.
Frames
Frames
allow you to create separate windows for your stand-alone applications.
You can also use frames to run your applets outside of a browser window. I
will only cover Frames briefly since our course covers
applets and not stand-alone applications.
Creating
Frames
You can create Swing Frames
as follows:-
JFrame myFrame
= new JFrame();
This will create an
invisible frame without a title in the title bar
JFrame myFrame
= new JFrame("my First Frame");
This will create a
frame with a title but it will still be invisible.
Presumably we want to
see our frames. To make a frame visible we have to give it a size and then
we can show it. We can do this as follows:-
myFrame.show();
You can easily hide a
frame again:-
myFrame.hide();
An alternative to the show
and hide methods is the setVisible method:-
myFrame.setVisible(true);
//shows the frame
myFrame.setVisible(false);
//hides the frame
We can specify
the size of the frame using...
myFrame.pack();
...which sizes the
frame so that all its contents are at or above their preferred sizes.
When the pack method is used, the layout manager
for the Frame is in charge of setting the size.
Alternatively we
could use...
myFrame.setSize(new
Dimension(int, int));
...if the layout
manager doesn't set the size the way we like using the pack
method.
Note: the
arguments (int, int) refer to the width and
height of the application and you must put in real values or variables with int
values.
Finally, we must add the
code:-
myFrame.addWindowListener(new
WindowAdapter() {
public void windowClosing(WindowEvent e){System.exit(0);} });
This adds a window
listener to the frame. The listener's implementation makes the program exit when
the user closes the frame. If the program didn't exit, then it would continue to
run but have no visible GUI and no way of making any GUI visible.
The program would continue to take up the computer's memory.
Now,
let's create a simple applet and then convert it to an application:-
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class HelloWorldGUI extends JApplet {
public void init() {
JPanel myPanel = new JPanel();
getContentPane().add(myPanel);
JLabel myLabel = new JLabel("Hello World!");
myPanel.add(myLabel);
}
}
|
To
convert it to an application we need to make the following changes and
additions to the code:-
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class HelloWorldGUI extends JFrame {
public HelloWorldGUI() {
super("HelloWorldGUI");
JPanel myPanel = new JPanel();
getContentPane().add(myPanel);
JLabel myLabel = new JLabel("Hello World!");
JLabel myLabel2 = new JLabel("This is my first GUI application.");
myPanel.add(myLabel);
myPanel.add(myLabel2);
}
public static void main(String s[]) {
HelloWorldGUI myFrame = new HelloWorldGUI();
myFrame.setSize(new Dimension(200,100));
myFrame.setVisible(true);
myFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {System.exit(0);}
});
}
}
|
A
picture of the application is shown below.
What
does the new code do?
Change
JApplet to JFrame : First my JApplet
is changed to a JFrame , since it is now going to be an
application. That is done on the line:-
public class HelloWorldGUI extends JFrame
Then
I must get rid of the init method since that is for applets and
add a constructor for the application. That is done on the line:-
public HelloWorldGUI()
This
constructor will be run when an instance of my class HelloWorldGUI
is created. Like the original applet's init method, it
creates the panels and labels.
Add
a main method: An application must have a main
method so it knows where to start running your code. This main
method creates an instance of HelloWorldGUI and runs the HelloWorldGUI
constructor. That is done on the line:-
HelloWorldGUI myFrame = new HelloWorldGUI();
The
rest of the code inside main , sizes the HelloWorldGUI
instance, makes it visible and adds the window listener code.
Applets That Run Applications
Why can I only show
you a picture of the application above?
Your answer should
be that applications cannot be run by browsers.
However, you could
get around this by creating an applet in a browser that starts an
application. I won't go into details here because you don't know about
event handling yet and there are other concerns such as applet
security. Just check it out the applet below that starts the HelloWorldGUI
application.
Don't forget
to close the application.
That is folks!!
Now try the Containers
exercise
|