Transcript Tutorial 2
MT311 (Oct 2006)
Java Application Development
Tutorial 2
Graphical User
Interface
Tutor Information
Edmund Chiu (Group 1)
Email: [email protected] OR
[email protected]
Please begin your email subject with [MT311]
Webpage: http://learn.ouhk.edu.hk/~t439934
PART I
GUI Components
Containers
Components
Events and Listeners
Layout Managers
Java GUI Framework
In early day, Java GUI are supported by Abstract
Window Toolkit (AWT)
–
–
Based on native widget in different platform
Buggy and not really portable
Java Foundation Class (JFC) was introduced in Java
1.1
–
–
AWT was replaced by Swing (javax.swing.*)
Other package in JFC provides 2D advanced graphics,
pluggable look and feel, drag and drop and other facilities
Containers
Originated from AWT
Logical grouping of other containers and
components
Top level containers appear as windows and
define your application areas
–
–
With title bar, system buttons and frame
Can be resized, moved and closed
JFrame
Basic windowing supports such as title, positioning
and resizing
Steps to use JFrame
1.
Create the frame with a particular title
JFrame frame = new JFrame(“Hello World”);
2.
Add containers and/or controls to the frame
JButton button = new JButton(“Say Hello”);
frame.getContentPane().add(button);
3.
Arrange the controls
frame.pack()
4.
Make the frame visible
frame.setVisible(true);
Sample Code (JFrame)
import javax.swing.*;
public class FrameDemo {
public static void main (String[] args) {
JFrame frame =
new JFrame (“Demo”);
frame.setSize(200,200);
frame.setVisible(true);
}
}
Other Issues on JFrame
The close button only closes your JFrame, but not
ends your application
–
Solution:
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
You can set the initial size of your JFrame using
setSize(int width, int height)
You should explore the way to use other methods in
JFrame by using the API specification
JDialog
Simple window used for short-lived interactions such
as
–
–
Prompting user for responses
Informing user of certain events
To create a dialog
JDialog dlg = new JDialog(owner, title, modality);
– Modal dialog is used if you need user’s response before
proceeding
– Non-modal dialog is used to present information that is safe to
be ignored
JOptionPane is used for generating common use
standard dialogs
JOptionPane’s Message Dialog
Generate using:
JOptionPane.showMessageDialog(null,
“I’m the light of the world.”, “Hello World”,
JOptionPane.INFORMATION_MESSAGE);
JApplet
Applets are lightweight applications that can be
embedded in a browser
–
Restricted from accessing and/or using local system
resources
No main methods
–
init() method do the initialization and kick off job
Sample Applet
import javax.swing.*;
public class AppletDemo extends JApplet {
public void init() {
JButton button =
new JButton("Say Hello");
getContentPane().add(button);
}
}
Intermediate Containers
Intermediate containers are components that can
contain other components
–
–
Cannot stand alone
Can be nested – containers can be placed inside a container
JPanel is the most common intermeidate containers
–
–
JPanel does not have a visual realization
In general, it is used to group other controls to create
More logical organization
Easier positioning and resizing
JScrollPane
A JScrollPane provides a scrollable view of a
component
–
Horizontal and vertical scrollbars are given to move
the component inside when it is larger than the
physical area on the screen
JSplitPane
Used to split an area into two distinct and independent
partitions
–
splitPane = new JSplitPane(
JSplitPane.HORIZONTAL_SPLIT,
listScrollPane, pictureScrollPane);
JTabbedPane
You can have several components (usually
panels) share the same space.
–
By selecting the individual tab, one of the
components can be shown at a time
How to use:
1.
2.
Create a JTabbedPane
Add components to the JTabbedPane
E.g.: tabbedPane.addTab("Tab 1", panel1);
JToolBar
JToolBar is a container that groups several
components (usually buttons with icons) into a
row or column
Often, tool bars provide easy access to
functionality that is also in menus
Controls (JComponents)
Controls differ from containers in that they actually do
something on an interface
Some common controls:
–
–
–
–
–
–
JLabel – display read-only text and icons support HTML
formatting
Buttons – includes JButton, JRadioButton, and JCheckBox
Text Components – includes JTextField (single line text input)
and JTextArea (multi-line editing)
Selection – JComboBox (drop-down list) and JList
Menus – JMenuBar, JMenu, JMenuItem, JCheckBoxMenuItem,
and JRadioButtonMenuItem
Others – JSlider, JSpinner, Progress bars and etc.
JComponent Methods
Common methods for the components
–
–
–
–
get/setText
setEnabled
isSelected
Millions of methods are supported by different components.
You should review Java API specification and the respective
online Java Tutorial to understand how to use them
One last point on JRadioButton
–
–
They should be grouped into ButtonGroup in order to make
only one radio button in the group being selected
However ButtonGroup is NOT a component and cannot be
added to the container
Common Controls
There are still
many other!!
More Complex Components
Building a Swing Interface
Step 1 – choose a top-level container
–
JFrame? JApplet?
Step 2 – choose an intermediate container (if
necessary)
Step 3 – place your components (labels, buttons and
etc.) onto the intermediate container(s)
Step 4 – add your intermediate container(s) to the toplevel container
Step 5 – arrange the frame and show the window
Sample Program in Building
Swing GUI
import javax.swing.*; // import the Swing components
public class HelloWorldSwing {
public static void main(String[] args) {
JFrame frame = new JFrame("Hello World");
JPanel pane = new JPanel();
JLabel label = new JLabel("Hello World");
JButton button = new JButton("Say Hello");
pane.add(label);
pane.add(button);
frame.getContentPane().add(pane);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
Event-Driven Programs
In conventional procedural programs
–
–
–
Flow of control depends on input data only, deal with one input
channel at a time (single-threaded)
Example: program wait for keyboard input and ignore other
input until the first input is received
Disadvantage – most events are random in no particular order
Event-driven program deals with any event when it
arrives
–
–
–
User actions generate events
If you want to react to an event, you attach an event listener
When an event fires (happens), the event handler is invoked
Events
An event is generated whenever there is a
change to a component
–
–
Component resized component event
Mouse clicked mouse event
A component can generate multiple event
–
–
A button “clicked” maybe mouse, maybe
keyboard
We should handle semantic events (button clicked –
ActionEvent) instead of low-level events
Event Listeners
To react to a particular event, you need an event
listener (interface)
As there are many types of event, each should have
their own listener interface
Components have specific addXXXListener methods to
attach event listeners to them
Multiple event listeners may be registered to the same
components
The same event listener may be registered to multiple
components
Events and Event Listeners
ActionEvent
ComponentEvent
ContainerEvent
FocusEvent
InputEvent (Key/Mouse)
InputMethodEvent
InvocationEvent (run method)
ItemEvent
KeyEvent
MouseEvent
MouseWheelEvent
PaintEvent
TextEvent
WindowEvent
ActionListener
ComponentListener
ContainerListener
FocusListener
InputMethodListener
ItemListener
KeyListener
MouseListener
MouseMotionListener
MouseWheelListener
TextListener
WindowFocusListener
WindowListener
WindowStateListener
Event Information
To grab more information from an event to be
handled, all event listener methods have a
parameter giving the information regarding the
specific event
–
public void actionPerformed (ActionEvent e) {…}
The event object can provide information like
–
–
Event source
Event type
Extending HelloWorldSwing
Example
Add a class MyActionListener
–
public class MyActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(…);
}
}
Remember to register your button the action listener
–
MyActionListener myListener = new MyActionListener();
Button.addActionListener(myListener);
Event Adapters
As Listeners are interfaces, you are required to
implement all listener methods even you are not using
one of them.
–
Empty methods can be used for those listener methods you
are not required in the program
Java provides Adapter classes for every Listener, with
all methods empty
–
–
E.g., MouseListener has five methods: mousePressed,
mouseReleased, mouseEntered, mouseExited and
mouseClicked
User can use MouseAdapter and override only the method(s)
they are care about.
Listener/Adapter Methods
Component Listener/Adapter
–
Container Listener/Adapter
–
componentAdded, componentRemoved
Focus Listener/Adapter
–
componentHidden, componentMoved, componentResized,
componentShown
focusGained, focusLost
Key Listener/Adapter
–
keyPressed, keyReleased, keyTyped
Listener/Adapter Methods (cont’d)
Mouse Listener/Adapter
–
Mouse Motion Listener/Adapter
–
mouseDragged, moseMoved
Mouse Input Listener/Adapter
–
mouseClicked, mouseEntered, mouseExited, mousePressed,
mouseReleased
mouse listener + mouse motion listener
Window Listener/Adapter
–
windowActivted, windowClosed, windowClosing,
windowDeactivated, windowDeiconified, windowIconified,
windowOpened
Writing Event Listeners
Many methods to write a event listener
–
–
Create a new ActionListener class (like the original example)
Not good because creating a new class is rather heavyhanded
Making the HelloWorldSwing class implements ActionListener
and put the method inside the HelloWorldSwing class
Most casual programmers do so, but work in simple cases only.
When the program becomes complex, we do not know which
method is for the Listener and which is for the application
Writing Event Listeners (cont’d)
–
–
–
Use inner class: define the listener class inside the
application program
Encapsulate the listener inside the class
Use anonymous class: we do not even need to have
a class – the listener is only for the button we are
handling
Inner class and anonymous class may make
elegant and efficient code, but at the same time,
may also make the code incomprehensible
Direct Implementing ActionListener
public class HelloWorldSwing implements
ActionListener {
:
:
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(…);
}
}
Anonymous Event Listener
button.addActionListener (
new ActionListener() {
public void actionPerformed (ActionEvent e) {
JOptionPane.showMessageDialog(…);
}
}
);
Layout
The way of arranging components on a container is
layout
–
Layout manager determine the relative position of the
components.
–
–
Overall placement and size
Java can still use absolute positioning (by setting layout
manager to null)
Layout managers are used because Java programs may
appear in different platform which may have a different font,
different screen size and etc. Flexible layouts are needed.
Most GUI use flow layout as default
–
–
Default as BorderLayout: JApplet, JFrame and Dialog
Default as FlowLayout: Panel, Applet and JPanel
Common Layout Managers
FlowLayout
–
GridLayout
–
–
arranges components from left to right
displays components in a rectangular grid
E.g., container.setLayout(new GridLayout(2,3));
means 2 rows and 3 cols, components are added from left to
right, then top to bottom.
BorderLayout
–
–
–
divides the container into regions
programmers specifies where to place their components
The regions are PAGE_START (NORTH), PAGE_END
(SOUTH), LINE_START (WEST), LINE_END (EAST) and
CENTER
Border Layout Example
import java.awt.*;
import javax.swing.*;
public class BorderLayoutDemo {
public static void main(String[] args) {
JFrame frame = new JFrame("BorderLayoutDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container pane = frame.getContentPane();
pane.add(new JButton("PAGE_START"), BorderLayout.PAGE_START);
pane.add(new JButton("LINE_START"), BorderLayout.LINE_START);
pane.add(new JButton("CENTER"), BorderLayout.CENTER);
pane.add(new JButton("LINE_END"), BorderLayout.LINE_END);
pane.add(new JButton("PAGE_END"), BorderLayout.PAGE_END);
frame.pack();
frame.setVisible(true);
}
}
Component Size
By default, each component has a natural size
–
E.g., a button is just as tall and wide enough to fit the button
label
We can override the default by setting the preferred
size
–
–
E.g., button.setPerferredSize(new Dimension(50, 200));
You may set the maximum/minimum size of the component
also, but the methods are not supported by all layout
managers
Component Size and Layout
Manager
In Border Layout
–
–
–
In Grid Layout
–
Each component occupies full width and height of its own grid
In Flow Layout
–
Components in N and S will have natural height, but extend to
full width
Components in E and W will have natural width but full height
Center is region is greedy, it occupies all area left by N, E, S,
W
All components are in natural size
Always use JPanel to group your components to make
your layout flexible
Other Layout Manager
Box Layout
–
Spring Layout
–
Good for single row / single column layout
Most suitable for form – multiple rows and columns
in varying width and height
GridBag Layout
–
Most powerful layout – grid based, but a component
can span multiple rows and/or columns
PART II
Java Graphics
Graphics
You can paint anything onto a graphical context
–
All components have a graphics context
–
E.g, A JButton knows how to draw itself, and you can even
make it to have an image on itself
Graphics g = component.getGraphics(); // not the usual way
We usually get the graphics object through the paint
method
–
–
–
void paint (Graphics g)
Paint method is called whenever the component needs repaint
Custom drawing is made by overriding the component’s paint
method
Coordinate System in Java
Upper-left corner of the GUI component (a
window or an applet) is (0, 0)
x-coordinates increases from left to right
y-coordinates increases from top to bottom
coordinates are measured in the number of
pixels
Drawing Lines and Shapes
drawLine(int x1, int y1, int x2, int y2)
–
drawRect(int x, int y, int w, int h)
–
Draws a line between the points (x1, y1) and (x2, y2) in this
graphics context's coordinate system.
Draws a rectangle with its top-left corner at (x, y), and its width
as w and its height as h
drawOval(int x, int y, int w, int h)
–
Draws a circle or an ellipse that fits within the rectangle with
top-left angle at (x, y), the width of the rectangle as w, and the
height as h.
Drawing Lines and Shapes (cont’d)
drawPolygon(int[] xPoints, int[] yPoints, int nPoints)
–
Draws a closed Polygon which vertices are specified by the
arrays of x- and y- coordinates
drawArc(int x, int y, int width, int height, int startAngle,
int arcAngle)
–
–
–
Draws the arc which:
begins at startAngle and extends for arcAngle degrees
Angles are interpreted such that 0 degrees is at the 3 o'clock
position. A positive value indicates a counter-clockwise rotation.
(x, y) is the coordinates of the top-left corner of the rectangle
embedding the arc. The size of such rectangle is specified by
the width and height arguments.
Filling Shapes
The following methods draw a filled shape (filled with
current Color)
–
–
–
–
fillRect(int x, int y, int w, int h)
fillOval(int x, int y, int w, int h)
fillPolygon(int[] xPoints, int[] yPoints, int nPoints)
fillArc(int x, int y, int width, int height, int startAngle, int
arcAngle)
There are still many other shapes Java can draw
–
draw3DRect, drawRoundRect, clearRect and etc.
Color Class
Color class contains color constants and methods
–
Color constructors:
–
public Color (int r, int g, int b)
Color components can be retrieved using methods
getRed(), getBlue() and getGreen()
Common color can be retrieved using Color constants
–
Each color is created from RGB (Red-Green-Blue) value
Examples: Color.red, Color.orange, Color.yellow, Color.green
To change the color used in a Graphics object, call
setColor method
–
Example: g.setColor(Color.red);
Sample Applet of
Drawing Lines and Shapes
import javax.swing.JApplet;
import java.awt.*;
public class DrawLineDemo
extends JApplet {
public void init() {
setBackground(
new Color(0xcc, 0xcc, 0xcc));
}
public void paint(Graphics g) {
g.setColor(Color.red);
g.drawLine(0, 0, 100, 100);
g.setColor(Color.green);
g.drawLine(250, 250, 120, 13);
g.setColor(Color.blue);
g.fillRect(100, 100, 100, 80);
g.setColor(Color.orange);
g.drawOval(30, 30, 200, 200);
int x[] = { 19, 234, 9, 192, 62};
int y[] = { 35, 135, 241, 141, 71};
g.setColor(Color.cyan);
g.fillPolygon(x, y, 5);
}
}
Output of DrawLineDemo Applet
Graphics 2D
Graphics object provides primary drawing functions
only
Graphics2D object provides more advanced features
such as
–
–
–
Solid, dotted and patterned lines of any width
Gradient paint, image filling
Shape rotating, stretching and squashing
You can safely upcast a Graphics object to Graphics2D
Sample Code of Graphics2D Applet
(Only paint method is shown here)
public void paint(Graphics g) {
// cast Graphics to Graphics2D
Graphics2D g2 = (Graphics2D) g;
Dimension d = getSize();
// fill Ellipse2D.Double
g2.setPaint(new
GradientPaint(0, 0, Color.red, d.width, d.height, Color.white));
g2.fill(new Ellipse2D.Double(0, 0, d.width, d.height));
}
Output of Graphics2D Applet
Draw a String
Method drawString(String s, int x, int y) can
display a string s with the current font at the
position of (x, y) (baseline of the first character)
Current font can be set and retrieved using the
methods
–
–
void setFont(Font f)
String getFont()
Using a Font
Font class contains constants and methods for
manipulating fonts
Font Constructor:
–
public Font(String name, int style, int size)
name = name of the font
style = font style
use font style constants: Font.PLAIN, Font.BOLD and
Font.ITALIC
(Font.BOLD | Font.ITALIC to apply both bold and italic)
size are measured in points (1 point = 1/72 inch)
Java 2D graphics has anti-aliasing capability to make
text look smoother
Font Information
A list of available fonts can be retrieved through
method getFontList in the AWT Toolkit class:
–
String fontList[] =
ToolKit.getDefaultToolKit().getFontList();
FontMetrics class defines methods to obtain font
metrics such as height, ascent, descent and etc.
–
–
FontMetrics object can be retrieved from a Font object using
getFontMetrics()
Using getStringBounds method in FontMetrics can know the
exact length of a string shown in the screen
Drawing String Example
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.blue);
g2.setFont(new Font("Arial", Font.BOLD | Font.ITALIC, 18));
g2.drawString("Changing your font is FUNNY.", 50, 50);
}
Drawing an Image
To display image file, you use drawImage
–
–
To get image from the file
–
boolean drawImage (Image img, int x, int y, ImageObserver o)
draws image at x, y without scaling
boolean drawImage (Image img, int x, int y, int width, int height,
ImageObserver o) draws image at x, y to a specific width and
height
Image img = Toolkit.getDefaultToolkit().getImage(<file>);
ImageObserver is the object which will be repainted
when the image needs refresh (this)
Image Drawing Sample Code
import javax.swing.JApplet;
import java.awt.*;
public class DrawImageDemo extends JApplet {
Image img;
public void init() {
img = getImage(getDocumentBase(), "images/demo.gif");
setBackground(Color.white);
}
public void paint(Graphics g) {
g.drawImage(img, 0, 0, getWidth(), getHeight(), this);
}
}
Pluggable Look and Feel
UIManager.setLookAndFeel(
"com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
Other Advanced Features
Drag and Drop
–
Java’s Data Transfer package (in Swing) supports
Drag and Drop of GUI components and other
objects
Design Pattern
–
–
MVC
Observer/Observable pattern