ch17 NN

Download as ppt, pdf, or txt
Download as ppt, pdf, or txt
You are on page 1of 61

Chapter 17 1

GUI Programming Basics

 GUI Overview
 Event-Driven Programming Basics
 GUI Classes and Packages
 A Simple Window Program
 JFrame Class
 Java Components
 JLabel Component
 JTextField Component
 Component Listeners
 Interfaces
 Inner Classes
 Anonymous Inner Classes
 JButton Component
 JOptionPane Dialog Box
 Distinguishing Between Multiple Events
 Using getActionCommand to Distinguish Between Multiple Events
(optional)
 Color
Chapter 17 2
GUI Programming Basics

 Mouse Listeners
 MouseListener Interface
 MouseMotionListener Interface
 Mouse Adapter Classes
 DragSmiley Program
 Displaying an Image
3
GUI Overview
 GUI stands for Graphical User Interface.
 Graphical = picture objects (windows, buttons, menus, etc.)
 User = the person who uses the program.
 Interface = the manner in which the user interacts with the
program.
 Although companies still write text-based programs
for internal use, most companies write GUI-based
programs for programs that are to be used externally.
4
Event-Driven Programming Basics
 GUI programs usually use event-driven programming
techniques.
 Basic idea behind event-driven programming:
 The program waits for events to occur and then it responds.
 An event is a message that tells the program that
something has happened. For example, if the user
clicks a button, then an event is generated, and it
tells the program that a particular button was clicked.
 More formally, when the user clicks a button, we say
that the button object fires an event.
5
Event-Driven Programming Basics
 Note these additional event examples:

User Action What Happens


Pressing the enter key The text box object fires an
while the cursor is inside a event, and it tells the
text box. program that enter was
pressed within the text
box.
Clicking a menu item. The menu item object fires
an event, and it tells the
program that the menu
item was selected.
Closing a window (clicking The window object fires an
on the window's top-right event, and it tells the
corner "X" button). program that the window's
close button was clicked.
6
Event-Driven Programming Basics
 If an event is fired, and you want your program to handle the
fired event, then you need to create a listener for the event.
 For example, if you want your program to do something when the
user clicks a particular button, you need to create a listener for
the button.
 If an event is fired and there's no listener listening to it, then the
fired event is never "heard" and there's no response to it.
 On the other hand, if there is a listener listening to a fired event,
then the listener "hears" the event and the program then
responds to the fired event.
 The way the program responds is by executing a chunk of code
known as an event handler.
7
Event-Driven Programming Basics
 What happens when a button is pressed:

user fired event


listener handler
action event

------------------
OK -----------------
-------------------
---------------
------------------
------------------
-----------------
8
GUI Classes and Packages
 In writing a GUI program, use Java's pre-built GUI classes. For
example:
 Use the pre-built JButton class when you need a button.
 Use the pre-built Color class when you need to specify a color.
 In the first Java compiler, JDK 1.0, all GUI classes were bundled
into one library known as the Abstract Windowing Toolkit (AWT).
 The AWT's component classes were less than ideal in terms of
portability, so Sun developed a set of more-portable GUI
components and put them in a new GUI library named Swing.
 The Swing library adds lots of functionality to the AWT, but it
does not replace the AWT entirely.
 Today, Java GUI application programmers use both libraries -
Swing and the AWT.
 The primary Swing package is javax.swing. The primary AWT
packages are java.awt and java.awt.event. Get used to
importing those three packages in all of your GUI programs.
9
A Simple Window Program
import javax.swing.*; // for JFrame & JLabel
import java.awt.*; // for FlowLayout
public class SimpleWindow extends JFrame
{
private static final int WIDTH = 300;
private static final int HEIGHT = 200;
public SimpleWindow()
{
setTitle("Simple Window");
setSize(WIDTH, HEIGHT);
setLayout(new FlowLayout());
setDefaultCloseOperation(EXIT_ON_CLOSE);
createContents();
setVisible(true);
} // end SimpleWindow constructor
private void createContents()
{
JLabel label = new JLabel("Hi! I'm Larry the label!");
add(label);
} // end createContents
public static void main(String[] args)
{
new SimpleWindow();
} // end main
} // end class SimpleWindow
12
JFrame Class
 The JFrame class:
 Should be used as the superclass for most of your GUI
application windows, so programmer-defined windows should
extend the JFrame class.
 Is in the javax.swing package, so import that package.
(As explained in Chapter 5, you can use an * as a wildcard to
import all the classes within a particular package.)
 Is called a container class because:
 It contains things (like labels, buttons, menus, etc).

It's derived from the Container class.
 Implements all the standard window features such as:
 a border, a title bar, a minimize button, a close-window button
(the "X"), the ability to resize the window, etc.
13
JFrame Class
 JFrame methods:
 setTitle - Displays a title in the current window.
 setSize - Sets the width and height dimensions in pixels of
the current window.
 Your monitor will be set to a certain number of pixels (e.g.,
800x600, 1024x768, etc.). The pixel setting is called the
resolution. A pixel is a monitor's smallest displayable unit.

 setLayout(new FlowLayout()) - Assigns a specified


layout manager to the current window.
 The layout manager determines the positioning of components.
 setDefaultCloseOperation(EXIT_ON_CLOSE) -
Enables the close-window button (the "X" in the top-right
corner) to work properly.
14
JFrame Class
 JFrame methods (continued):
 add - Adds a specified component to the current window.
 Once the component is added to the window, it stays with the
window for the life of the program.
 Thus, in the SimpleWindow program, even though label is
defined locally within createContents, label stays with the
window after createContents finishes.
 setVisible(true) - Displays the window. Make sure you
call setVisible at the end (after you've added all of the
window's components).
 setVisible(false) - Hides the window.
15
Java Components
 Example Java components:
 JLabel, JTextField, JButton,
 JCheckBox, JRadioButton, JComboBox, JList, JTextArea
 JMenuBar, JMenu, JMenuItem

 All of these component classes are in the javax.swing


package so import that package.
 All of these component classes are descendants of the
JComponent class. The JComponent class supports many
useful inheritable features. Along with many other methods, it
contains methods that handle a component's:
 foreground and background colors
 text font
 border appearance
 tool tips
 focus
16
JLabel Component
 JLabel component interface:
 JLabel is a read-only component; the user can read the
label's message, but cannot update it.
 JLabel is a single-line component; \n won't work.

 How to implement a label: optional


1. Instantiate a JLabel object:
<reference-variable> = new JLabel(<label-text>);

2. Add the JLabel object to the window.


add(<reference-variable>);

3. The JLabel class is in the javax.swing package so


import that package.
17
JLabel Component
 Here are API headings and descriptions for two of the
more popular JLabel methods:
 public String getText()
 Returns the label's text.
 public void setText(String text)
 Assigns the label's text.
18
JTextField Component
 JTextField component interface:
 The user can enter text into a text box.

 How to implement a text box:


1. Create a JTextField object with the JTextField
constructor: optional
<reference-variable> = new JTextField(<default-text>, <width>);

2. Add the JTextField object to the window.


add(<reference-variable>);

3. The JTextField class is in the javax.swing package so


import that package.
19
This program demonstrates text boxes and labels. When the user presses
enter in the text box, the text box's value displays in the bottom label.

import javax.swing.*; nameBox = new JTextField(15);


import java.awt.*; greeting = new JLabel();
import java.awt.event.*; add(namePrompt);
add(nameBox);
public class Greeting extends JFrame add(greeting);
{ nameBox.addActionListener(new Listener());
private static final int WIDTH = 325; } // end createContents
private static final int HEIGHT = 100;
private JTextField nameBox; // holds user's name //****************************************************
private JLabel greeting; // personalized greeting
// Inner class for event handling.
//*******************************************
private class Listener implements ActionListener
public Greeting() {
{ public void actionPerformed(ActionEvent e)
setTitle("Greeting"); {
setSize(WIDTH, HEIGHT); String message; // the personalized greeting
setLayout(new FlowLayout()); message = "Glad to meet you, " +
setDefaultCloseOperation(EXIT_ON_CLOSE); nameBox.getText() + "!";
createContents(); nameBox.setText("");
setVisible(true); greeting.setText(message);
} // end constructor } // end actionPerformed
} // end class Listener
//*******************************************
//****************************************************
// Create components and add them to window.
public static void main(String[] args)
private void createContents() {
{ new Greeting();
JLabel namePrompt = } // end main
new JLabel("What's your name?"); } // end class Greeting
20
JTextField Component
 Here are API headings and descriptions for some of
the more popular JTextField methods:
 public String getText()
 Returns the text box's contents.
 public void setText(String text)
 Assigns the text box's contents.
 public void setEditable(boolean flag)
 Makes the text box editable or non-editable.
 public void setVisible(boolean flag)
 Makes the text box visible or invisible.
 public void addActionListener(ActionListener listener)
 Adds a listener to the text box.
21
Component Listeners
 When the user interacts with a component (e.g.,
when the user clicks a button or presses enter while
in a text box), the component fires an event.
 If the component has a listener attached to it, the
fired event is "heard" by the listener and
consequently handled by the listener.
 The listener handles the event by executing the code
in its actionPerformed method.
22
Component Listeners
 How to implement a listener for a text box:
1. Define a class with an implements ActionListener clause (that
means that the class is an implementation of the ActionListener
interface).
2. Include an actionPerformed event handler method in your listener's
class:
private class Listener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
<do something>
}
}

Note that if the ActionEvent event-handler parameter (e, above) isn't


used within the actionPerformed method body, you are still
required to define it. Why?

Because when a text-box-enter event occurs, the JVM looks for an


actionPerformed method with an ActionEvent parameter. If the
JVM can't find that exact method signature, then no event handling
takes place.
23
Component Listeners
 How to implement a listener for a text box
(continued):
3. Register your text box listener object. For example, in the
Greeting program, the createContents method
registers a listener for the nameBox text box like this:
nameBox.addActionListener(new Listener());

4. Import the java.awt.event package. Event handling requires


the use of the ActionListener interface and the
ActionEvent class. Those entities are in the java.awt.event
package, so that package must be imported for event handling to
work.
24
Interfaces
 An interface is a class-like thing whose methods are all empty.
 If a programmer uses an interface to implement a new class,
the compiler requires the new class to implement methods for
all of the interface's methods.
 So what's the point of having a class-like thing with all empty
methods?
 It can be used as a template/pattern when creating a class that
falls into a certain category.
 More specifically, what's the point of the ActionListener
interface?
 Since all component listeners must implement it,
 It means that all component listeners will be similar and therefore
easier to understand.
 It means that all component listeners will implement the
actionPerformed method with the proper heading (and that
ensures that component events will be received properly).
25
Inner Classes
 If a class is limited in its scope such that it is only
needed by one other class, then define the class as
an inner class (a class inside of another class).
 Since a listener is usually limited to listening to just
one class, listeners are often implemented as inner
classes.
 To further the goal of encapsulation, "hide" the
inner class by declaring it with the private access
modifier.
26
Inner Classes
 Besides furthering the goal of encapsulation, what's
another reason to use an inner class as opposed to
a top-level class? (Top-level class is the formal term
for a regular class - a class not defined inside of
another class.)
 An inner class can directly access its enclosing class's
instance variables. And listeners normally do need to access
their enclosing class's instance variables, so this is an
important benefit.
27
Greeting Program with an Anonymous Inner Class
import javax.swing.*; nameBox = new JTextField(15);
import java.awt.*; greeting = new JLabel();
import java.awt.event.*; add(namePrompt);
add(nameBox);
public class GreetingAnonymous extends JFrame add(greeting);
{ nameBox.addActionListener(
private static final int WIDTH = 300;
private static final int HEIGHT = 200; // anonymous inner class for event handling
private JTextField nameBox; // holds user's name new ActionListener()
private JLabel greeting; // personalized greeting {
public void actionPerformed(ActionEvent e)
//********************************************** {
String message; // the personalized greeting
public GreetingAnonymous() message =
{ "Glad to meet you, " + nameBox.getText();
setTitle("Greeting Anonymous"); nameBox.setText("");
setSize(WIDTH, HEIGHT); greeting.setText(message);
setLayout(new FlowLayout()); } // end actionPerformed
setDefaultCloseOperation(EXIT_ON_CLOSE); } // end anonymous inner class
createContents(); ); // end addActionListener call
setVisible(true); } // end createContents
} // end constructor
//****************************************************
//***********************************************
public static void main(String[] args)
// Create components and add them to window. {
new GreetingAnonymous();
private void createContents() } // end main
{ } // end class GreetingAnonymous
JLabel namePrompt = new JLabel("What's your
name?");
28
Anonymous Inner Classes
 The point of using an anonymous object is to avoid
cluttering up the code with a variable name when an
object only needs to be used one time.
 The point of using an anonymous inner class is to
avoid cluttering up the code with a class name when
a class only needs to be used one time.
 For example, if a particular listener class listens to
just one object, then the listener class needs to be
used only one time as part of an
addActionListener() method call. Therefore, to
unclutter your code, you may want to use an
anonymous inner class for the listener.
29
Anonymous Inner Classes
 Syntax:
The anonymous inner class
new <interface-name>()
implements the specified interface.
{
<class-body>
}

 Example:
nameBox.addActionListener(
new ActionListener()
ActionListener is an interface
{
public void actionPerformed(ActionEvent e)
{
...
30
JButton Component
 Button component interface:
 A button component acts like a real-world button - when
you press/click it, something happens.

 How to implement a button:


1. Create a button component with the JButton constructor:
JButton helloButton = new JButton("Press me");

2. Add the button component to the


button label's text,
window: OK to omit argument
add(helloButton);

3. The JButton class and the add method are both in the
javax.swing package so import that package.
31
JButton Component
 How to implement a button (continued):
4. Implement a listener class that includes an
actionPerformed event handler method:
private class Listener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
<do something>
}
}
5. Register your button-listener object:
helloButton.addActionListener(new Listener());
32
JButton Component
 Here are API headings and descriptions for some of
the more popular JButton methods :
 public String getText()
 Returns the button's label.
 public void setText(String text)
 Assigns the button's label.
 public void setVisible(boolean flag)
 Makes the button visible or invisible.
 public void addActionListener(ActionListener listener)
 Adds a listener to the button. The listener "listens" for the
button being clicked.
33
When the user 1) clicks the button or 2) presses enter in the input text box,
the entered number's factorial displays in the output text box.

import javax.swing.*; private void createContents()


import java.awt.*; {
import java.awt.event.*; JLabel xLabel = new JLabel("x:");
JLabel xfLabel = new JLabel("x!:");
public class FactorialButton
JButton btn = new JButton("Factorial");
extends JFrame
Listener listener = new Listener();
{
private static final int WIDTH = 300;
private static final int HEIGHT = 75; xBox = new JTextField(2);
xfBox = new JTextField(10);
private JTextField xBox; // user entry xfBox.setEditable(false);
private JTextField xfBox; // factorial
add(xLabel);
//************************************ add(xBox);
add(xfLabel);
public FactorialButton()
add(xfBox);
{
add(btn);
setTitle("Factorial Calculator");
setSize(WIDTH, HEIGHT);
setLayout(new FlowLayout()); xBox.addActionListener(listener);
setDefaultCloseOperation( btn.addActionListener(listener);
EXIT_ON_CLOSE); } // end createContents
createContents();
setVisible(true);
} // end FactorialButton constructor

//*******************************
34
Factorial Button Program
//*********************************** if (x < 0)
{
// Inner class for event handling. xfBox.setText("undefined");
}
private class Listener implements else
ActionListener {
{ if (x == 0 || x == 1)
public void {
actionPerformed(ActionEvent e) xf = 1;
{ }
int x; // user entered number else
int xf; // x factorial {
xf = 1;
try for (int i=2; i<=x; i++)
{ {
x = Integer.parseInt( xf *= i;
xBox.getText()); }
} } // end else
catch (NumberFormatException nfe)
{ xfBox.setText(
x = -1; // indicates invalid x Integer.toString(xf));
} } // end else
} // end actionPerformed
All GUI I/O is string-based. Use parseInt } // end class Listener
to convert string input to an integer.
35
Factorial Button Program
//**************************************

public static void main(String[] args)


{
new FactorialButton();
} // end main
} // end class FactorialButton
36
JOptionPane Dialog Box
 A dialog box is a simple window that contains a
message. For example:

 To generate a simple output dialog box, call


JOptionPane's showMessageDialog method:
JOptionPane.showMessageDialog(null, <message>);

 Example:
JOptionPane.showMessageDialog(null,
"Click factorial button to perform calculation.");
37
JOptionPane Dialog Box
 JOptionPane's showMessageDialog method is a
class method so call it using <class-name> dot
syntax.
 showMessageDialog's first argument specifies the
position of the dialog box. If the argument is null,
the dialog box appears in the center of the screen.
 The JOptionPane class is in the javax.swing
package so import that package.
38
Distinguishing Between Multiple Events

 For listeners that are registered with multiple


components, when the listener "hears" an event
firing, the listener usually needs to identify which
component was responsible for the fired event.
 To identify the component whose event was fired:
 Within the actionPerformed method, use the
actionPerformed method's ActionEvent parameter to
call getSource.
 The getSource method returns the address of the
component whose event was fired, so to check which
component is returned, use == with the original
component reference variable.
Updated listener for the factorial-button program: 39

When the user presses enter in the input text box, a warning dialog box is displayed.

private class Listener implements ActionListener


{
public void actionPerformed(ActionEvent e)
{
...
if (e.getSource() == xBox)
{
JOptionPane.showMessageDialog(null,
"Click factorial button to perform calculation.");
}
else
{
try
{
x = Integer.parseInt(xBox.getText());
}
...
}
} // end actionPerformed
} // end class Listener
Using getActionCommand to Distinguish 40
Between Multiple Events (optional)

 We call getSource to identify the component whose


event was fired. That works fine most of the time,
but not all of the time. Note the following cases
where calling getSource is inadequate:
1. If the event-firing component(s) is in a different class from
the listener class.
 The listener class's getSource method can successfully
retrieve the component responsible for the fired event, but
there is no way to identify the type of the returned component
because that requires comparing the returned component with
the original components (using ==).
 If the original component is in a different class and private,
using it in the listener class generates a compilation error.
Using getActionCommand to Distinguish 41
Between Multiple Events (optional)

 Note the following cases where calling getSource is


inadequate (continued)
2. If there's a need to have a modal component.
 A modal component is a component with more than one mode.
 For example, suppose there's a button whose label toggles
between "show details" and "hide details." The two labels
correspond to two different modes of operation – in one mode
details are shown, and in another mode details are hidden.
 If a modal button is clicked, getSource can retrieve the
button, but it cannot retrieve the button's mode. So the
getSource method cannot reveal anything about the intended
action (e.g., show details vs. hide details).
Using getActionCommand to Distinguish 42
Between Multiple Events (optional)

 What's the solution?


 To identify the event that was fired, use the
actionPerformed method's ActionEvent parameter to
call getActionCommand. The getActionCommand
method returns the "action command" associated with the
component whose event was fired. Typically, the action
command is the component's label.
 For example, the default action command for a button is
the button's label and the default action command for a
menu item is the menu item's label.
 Example code:
if (e.getActionCommand().equals("Factorial"))
...
43
Color
 Most GUI components are comprised of two colors -
foreground color is the color of the text, background
color is the color of the area behind the text.
 Here's how to create a red button with white text:
JButton btn = new JButton("Click Me");
btn.setBackground(Color.RED);
btn.setForeground(Color.WHITE);
 And here's what the red-white button looks like:
44
Color Methods
 The setBackground and setForeground methods are
standard mutator methods available to most GUI components.
 Likewise, getBackground and getForeground methods are
standard accessor methods available to most GUI components.
Here are their API headings and descriptions:
 public Color getBackground()
 Returns the component's background color.
 public Color getForeground()
 Returns the component's foreground color.
 Example for a text box:
JTextField nameBox = new JTextField();
Color originalBackground = nameBox.getBackground();
Color originalForeground = nameBox.getForeground();
45
Color Named Constants
 Color's variables (all of which are named
constants):
Color.BLACK Color.GREEN Color.RED
Color.BLUE Color.LIGHT_GRAY Color.WHITE
Color.CYAN Color.MAGENTA Color.YELLOW
Color.DARK_GRAY Color.ORANGE
Color.GRAY Color.PINK

 The Color class is in the java.awt package, so


import that package.
46
Color Objects
 To obtain a color that is not in the Color class's list
of named constant colors, instantiate a Color object
with a specified mixture of red, green, and blue.
 Here's the Color constructor call syntax:
new Color(<red 0-255>, <green 0-255>, <blue 0-255>)

 Each of the three Color constructor arguments is an


int value between 0 and 255. The int value
represents the amount of color, with 0 indicating no
color and 255 indicating the maximum amount of
color.
 For example, this statement sets a button's
background color to purple:
button.setBackground(new Color(128, 0, 128));
47
JFrame Background Color
 To set the background color for a JFrame window,
you first have to get the JFrame's content pane and
then you apply the background color to the content
pane.

content pane

 To get the content pane, call the JFrame class's


getContentPane method.
 This code sets the background color to yellow:
getContentPane().setBackground(Color.YELLOW);
This program's buttons allow the user to set the window's 48

background color to light red or light green.

import javax.swing.*; //****************************


import java.awt.*;
import java.awt.event.*; private void createContents()
{
public class ColorChooser extends JFrame
setLayout(new FlowLayout());
{
stopButton = new JButton("Stop");
private static final int WIDTH = 300;
private static final int HEIGHT = 100; stopButton.setBackground(Color.RED);
stopButton.addActionListener(
// These buttons change the window's new ButtonListener());
// background color to light red and add(stopButton);
// light green, respectively.
private JButton stopButton; goButton = new JButton("Go");
private JButton goButton; goButton.setBackground(Color.GREEN);
goButton.addActionListener(
//************************************
new ButtonListener());
add(goButton);
public ColorChooser()
{ } // end createContent
setTitle("Background Color Chooser");
setSize(WIDTH, HEIGHT);
setDefaultCloseOperation(
EXIT_ON_CLOSE);
createContents();
setVisible(true);
} // end ColorChooser constructor
49
Background Color Chooser Program
//***************************************

// Inner class for event handling.

private class ButtonListener implements ActionListener


{
public void actionPerformed(ActionEvent e)
{
Container contentPane = getContentPane();
if (e.getSource() == stopButton)
{
// Change the window background color to pink.
contentPane.setBackground(Color.PINK);
}
else
{
// Change the window background color to light green.
contentPane.setBackground(new Color(220, 255, 220));
}
} // end actionPerformed
} // end class ButtonListener

//**************************************

public static void main(String[] args)


{
new ColorChooser();
}
} // end class ColorChooser
50
Mouse Listeners
 Previously, you learned about the most common
listener – the ActionListener.
 You should use the ActionListener for events
where the user does something to a component, such
as clicking a button or pressing Enter within a text
box. For mouse dragging events, you’ll need a mouse
listener.
 In creating a mouse listener, you use the same basic
steps that you use for the ActionListener:
 Define a listener class.
 Define an event handler method(s) within the listener class.
 Register your listener class with a component.
51
MouseListener Interface
 Here are the API headings and descriptions for some
of the more popular MouseListener interface event
handlers:
public void mouseClicked(MouseEvent event)
Called when the user presses and releases the mouse button while
the mouse cursor is stationary on a MouseListener-registered
component.
public void mousePressed(MouseEvent event)
Called when the user presses the mouse button while the mouse
cursor is on a MouseListener-registered component.
public void mouseReleased(MouseEvent event)
Called when the user releases the mouse button, but only if the
prior mouse press was on a MouseListener-registered
component.
52
MouseMotionListener Interface

 Here are the API headings and descriptions for the


MouseMotionListener interface event handlers:
public void mouseDragged(MouseEvent event)
Called when the user holds the mouse button down while moving
the mouse cursor, but only if the initial mouse press was on a
MouseMotionListener-registered component.
public void mouseMoved(MouseEvent event)
Called when the user moves the mouse while the mouse cursor is
on a MouseMotionListener-registered component.
53
Mouse Listeners
 For the mouse event handlers to be called, you need to register
your mouse listeners with a Component object.
 An image is not a component, so for the DragSmiley program,
you can’t register your listeners with the smiley icon image.
Instead, register your listeners with a JPanel object (a
descendent of the Component class), and add the JPanel
object to your JFrame.

 In the DragSmiley program, note the listener class headings:


private class ClickListener extends MouseAdapter
private class DragListener extends MouseMotionAdapter
 The extends clauses indicate inheritance from the
MouseAdapter and MouseMotionAdapter classes.
54
Mouse Adapter Classes
 For each event handling interface with more than one method,
Sun provides an associated class that already implements the
interface's methods for you. Those classes are called adapter
classes.
 The MouseAdapter class implements the MouseListener
interface's methods, and the MouseMotionAdapter class
implements the MouseMotionListener interface's methods.
Adapter classes don't do much. They simply implement their
associated interface's methods as dummy methods, like this:
public void mousePressed(MouseEvent event)
{ }
 To implement a listener that detects the mouse being pressed,
you extend the MouseAdapter class and provide an overriding
mousePressed method.
55
DragSmiley Program
/*************************************************************
* DragSmiley.java
* Dean & Dean
*
* This program displays a smiley face image.
* When the user presses the mouse, the image changes to a
* scared image. The user can drag the image.
*************************************************************/

import javax.swing.*;

public class DragSmiley extends JFrame


{
private static final int WIDTH = 250;
private static final int HEIGHT = 250;
private SmileyPanel smileyPanel; // drawing panel

//**************************************
56
DragSmiley Program
public DragSmiley()
{
setTitle("Drag Smiley");
setSize(WIDTH, HEIGHT);
setDefaultCloseOperation(EXIT_ON_CLOSE);
smileyPanel = new SmileyPanel();
add(smileyPanel);
setVisible(true);
} // end DragSmiley constructor

//**************************************

public static void main(String[] args)


{
new DragSmiley();
}
} // end class DragSmiley
57
DragSmiley Program
/*************************************************************
* SmileyPanel.java
* Dean & Dean
*
* This class contains a smiley image and listeners
* that enable image dragging and image swapping.
*************************************************************/

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class SmileyPanel extends JPanel


{
private final ImageIcon SMILEY = new ImageIcon("smiley.gif");
private final ImageIcon SCARED = new ImageIcon("scared.gif");
private final int WIDTH = SMILEY.getIconWidth();
private final int HEIGHT = SMILEY.getIconHeight();

private Point imageCorner; // image's top-left corner location


private Point prevPt; // mouse location for previous event
private ImageIcon image; // toggles between smiley and scared
private boolean grabbed; // does mouse have a hold on the icon?
58
DragSmiley Program
//**************************************

public SmileyPanel()
{
image = SMILEY;
imageCorner = new Point(0, 0); // image starts at top left
ClickListener clickListener = new ClickListener();
DragListener dragListener = new DragListener();
this.addMouseListener(clickListener);
this.addMouseMotionListener(dragListener);
} // end SmileyPanel constructor

//**************************************

private class ClickListener extends MouseAdapter


{
// When mouse pressed, change to scared image.

public void mousePressed(MouseEvent e)


{
image = SCARED;
repaint();
59
DragSmiley Program
prevPt = e.getPoint(); // save current position

// Make sure mouse was pressed within the image.


if (prevPt.getX() >= imageCorner.getX() &&
prevPt.getX() <= imageCorner.getX() + WIDTH &&
prevPt.getY() >= imageCorner.getY() &&
prevPt.getY() <= imageCorner.getY() + HEIGHT)
{
grabbed = true;
}
} // end mousePressed

// When mouse released, return to smiley image.

public void mouseReleased(MouseEvent e)


{
image = SMILEY;
repaint();
grabbed = false;
} // end mouseReleased
} // end class ClickListener
60
DragSmiley Program
//**************************************

private class DragListener extends MouseMotionAdapter


{
// Enable image to be dragged by mouse.

public void mouseDragged(MouseEvent e)


{
Point currentPt = e.getPoint(); // current position

// Make sure mouse was pressed within the image.


if (grabbed)
{
imageCorner.translate(
(int) (currentPt.getX() - prevPt.getX()),
(int) (currentPt.getY() - prevPt.getY()));
prevPt = currentPt; // save current position
repaint();
}
} // end mouseDragged
} // end class DragListener
61
DragSmiley Program
//****************************************

// Draw the window, including the updated image.

public void paintComponent(Graphics g)


{
super.paintComponent(g);
image.paintIcon(this, g,
(int) imageCorner.getX(), (int) imageCorner.getY());
} // end paintComponent
} // end class SmileyPanel
62
Displaying an Image
 To display an image:
1. Instantiate an ImageIcon object that stores an image file.
Specifically, call the ImageIcon constructor like this:
private final ImageIcon SMILEY = new ImageIcon("smiley.gif");

2. Call the ImageIcon’s paintIcon method from within a


paintComponent method.
 The paintComponent method is called automatically by the JVM
when the program starts up and whenever a user does something
to alter the program's window (e.g., when the user resizes the
window, or moves another window off of the window).
 The JPanel class has a paintComponent method that's in
charge of drawing Swing components (e.g., text boxes and
buttons) within the JPanel container. But it doesn't handle
drawing lines, shapes, or images. To draw those things, you need
to provide an overriding paintComponent method with calls to
graphics methods.
63
Displaying an Image
 To display an ImageIcon object, call the paintIcon
method like this:
<ImageIcon-reference-variable>.paintIcon(<image-observer>,
<Graphics-reference-variable>, <top-left-x>, <top-left-y>);

Where:
 The <image-observer> argument refers to an object that listens
for the completion of the image being loaded.
 <top-left-x> refers to the x coordinate position of the image's
top-left corner.
 <top-left-y> refers to the y coordinate position of the image's
top-left corner.
 For example:
image.paintIcon(this, g, (int) imageCorner.getX(),
(int) imageCorner.getY());

You might also like