13: More GUI Topics

What We Will Cover


Continuations

Questions from last class?

What to take next?

  • Schedule of Classes
  • After completing CS-12J you are qualified to take either CS-19 or cs-20J
    • CS-19: C++ programming and software design methodologies
    • CS-20J: Java programming and software design methodologies
  • Each course has a initial review section such that you could learn the syntax with a little effort
  • Other computer-related courses on which you can use your programming skills
    • CIS 130: UNIX/Linux Shell Programming
    • CIS-160GP: Game Programming in Java
    • CIS-165PH: Introduction to Programming Database-Driven Web Sites with PHP

13.1: Using Labels and Text Fields

Objectives

At the end of the lesson the student will be able to:

  • Use JLabels to display text
  • Use text fields for entering data

13.1.1: Using Labels

  • A JLabel is typically used to display text in a GUI
  • These labels often display text for other components
  • For instance, you may want a label for a text field

Code to Add Labels

  • Following code adds a label to a panel
  • JLabel label = new JLabel("Label text");
    JPanel panel = new JPanel();
    panel.add(label);
    
  • Other constructors of a JLabel allow Icons as well

Some Commonly-Used Constructors and Methods from JLabel

Constructor/Method Description
JLabel() Creates a blank label.
JLabel(Icon) Creates a label with the specified image.
JLabel(String) Creates a label with the specified text.
setIcon(Icon) Sets the icon for a label.
setHorizontalAlignment(int) Sets the alignment along the 10 axis, Usually JLabel.LEFT, JLabel.CENTER,or JLabel.RIGHT.
setText(String) Sets the text for a label.

For Example

  • In the following, we use this image for an icon: A pretty but meaningless splat (From the Java Tutorial)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class LabelApp extends JFrame {
    public final static int X_LOC = 100, Y_LOC = 100,
                            WIDTH = 150, HEIGHT = 125;

    public static void main(String[] args) {
        new LabelApp();
    }

    public LabelApp() {
        super("Label Application");
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        ImageIcon icon = new ImageIcon("icon.gif",
            "A pretty but meaningless icon");
        JLabel label1 = new JLabel("Text-only label");
        JLabel label2 =
            new JLabel("Image and text label");
        label2.setIcon(icon);
        label2.setHorizontalAlignment(JLabel.CENTER);
        JLabel label3 = new JLabel(icon);

        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());
        panel.add(label1, BorderLayout.NORTH);
        panel.add(label2, BorderLayout.CENTER);
        panel.add(label3, BorderLayout.SOUTH);
        add(panel);

        setBounds(X_LOC, Y_LOC, WIDTH, HEIGHT);
        setVisible(true);
    }
}

Further Information

13.1.2: Displaying Images on JLabels

  • An easy way to display images is to use an ImageIcon object with a JLabel
  • ImageIcons can be created from either files or URLs
  • ImageIcon myImage = new ImageIcon("image.jpg");
    
  • Note that Java only supports GIF, JPEG and PNG images
    • If you have images in other formats, you will need to convert them
  • We use the ImageIcon to instantiate a JLabel
  • JLabel label = new JLabel(myImage);
    
  • We then add the JLabel to the application in the usual way

Example: Displaying an Image

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.awt.*;
import javax.swing.*;

public class ImageDisplayer extends JFrame {
    public final static int X_LOC = 100, Y_LOC = 100,
                            WIDTH = 300, HEIGHT = 400;

    public static void main(String[] args) {
        new ImageDisplayer();
    }

    public ImageDisplayer() {
        super("Image Display Application");
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        ImageIcon myImage = new ImageIcon("image.jpg");
        JLabel label = new JLabel(myImage);
        add(label);

        setBounds(X_LOC, Y_LOC, WIDTH, HEIGHT);
        setVisible(true);
    }
}

We can download an image from my homepage and save it as image.jpg.

13.1.3: Using Text and Password Fields

  • JTextField: single-line area in which user can enter text
  • JPasswordField: extends JTextField and hides characters that a user enters
  • When the user presses the Enter key inside a JTextField, the component generates an ActionEvent
  • Thus, you can use an ActionListener to listen for text actions
  • Alternatively, you can add buttons to perform actions

Code for Text Fields

  • Code to declare a JTextField and a JPasswordField
  • JTextField login = new JTextField(10);
    JPasswordField password = new JPasswordField("asecret");
    
  • Code to register the handlers
  • login.addActionListener(this);
    password.addActionListener(this);
    
  • Example code that works with text and password fields
  • String data = login.getText();
    String pass = password.getPassword();
    password.setText("asecret");
    login.setEditable(false);
    

Commonly-Used Constructors and Methods from JTextField

Constructor/Method Description
JTextField(int) Creates an empty text field with the specified number of columns.
JTextField(String, int) Creates a text field that starts with the text and contains the number of columns.
getText() Returns the text contained in the text field as a String object.
setText() Sets the text field to the specified String.
setColumns(int) Sets the number of columns for the text field.
setEditable(boolean) Sets whether this text field is editable or not.

Commonly-Used Constructors and Methods from JPasswordField

Constructor/Method Description
JPasswordField(int) Creates an empty text field with the specified number of columns.
JTextField(String, int) Creates a password field that starts with the text and contains the number of columns.
getPassword() Returns the text stored in the component as a char[].

For Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class LoginDemo extends JFrame {
    public final static int X_LOC = 100, Y_LOC = 100;
    private JTextField login;
    private JPasswordField password;
    private JButton loginButton;

    public static void main(String[] args) {
        new LoginDemo();
    }

    public LoginDemo() {
        super("Login Application");
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        JLabel loginLabel = new JLabel("User name:");
        login = new JTextField(10);
        JPanel loginPanel = new JPanel();
        loginPanel.add(loginLabel);
        loginPanel.add(login);

        JLabel pwdLabel = new JLabel("Password:");
        password = new JPasswordField("asecret", 10);
        JPanel pwdPanel = new JPanel();
        pwdPanel.add(pwdLabel);
        pwdPanel.add(password);

        loginButton = new JButton("Press to Login");
        JPanel buttonPanel = new JPanel();
        buttonPanel.add(loginButton);

        add(loginPanel, BorderLayout.NORTH);
        add(pwdPanel, BorderLayout.CENTER);
        add(buttonPanel, BorderLayout.SOUTH);

        LoginListener listener = new LoginListener();
        login.addActionListener(listener);
        password.addActionListener(listener);
        loginButton.addActionListener(listener);

        setLocation(X_LOC, Y_LOC);
        pack();
        setVisible(true);
    }

    private void showMessage() {
        String message = "Login: " + login.getText()
            + "\nPassword: "
            + new String(password.getPassword());
        System.out.println(message);

    }

    class LoginListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            if (e.getSource() == login) {
                password.requestFocus();
            } else if (e.getSource() == password) {
                showMessage();
                login.requestFocus();
            } else if (e.getSource() == loginButton) {
                showMessage();
                login.requestFocus();
            }
        }
    }
}
  • Note how the loginLabel and login text field are grouped into a JPanel
  • The pwdLabel and password field are grouped similarly
  • This keeps these components grouped together during frame resizing

13.1.4: Dialogs Using JOptionPane

  • Dialogs provide a simple "popup" type of interaction with users
  • The JOptionPane class provides several static methods for constructing dialogs
  • Code for dialogs can be minimal
  • For instance, to collect text input from a dialog:
  • String inputString = JOptionPane.showInputDialog(
        "Enter your first name:");
    
  • Produces the following input dialog
  • Most dialogs are small windows with minimal options like the above

For Example

  • Lets create a simple program to ask for and display a name
  • We will use these three types of dialog boxes in sequence:
    1. showInputDialog(): ask for name
    2. showConfirmDialog(): verify entry
    3. showMessageDialog(): display results
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import javax.swing.JOptionPane;

public class NameApp {
    public static void main(String[] args) {
        String inputString = JOptionPane.showInputDialog(
            "Enter your first name: ");
        int choice = JOptionPane.showConfirmDialog(null,
            "Are you sure?");
        String message = "First name: " + inputString + "\n"
                         + "Choice: " + choice + "\n"
                         + "Press enter to exit.";
        JOptionPane.showMessageDialog(null, message);
        System.exit(0);
    }
}

Input with showInputDialog()

  • You use the showInputDialog() method of JOptionPane to get text input from users
  • In the above example, we created the first dialog like this:
  • String inputString = JOptionPane.showInputDialog(
        "Enter your first name:");
    
  • Note that this is a single code statement

Input with showConfirmDialog()

  • You use the showConfirmDialog() method of JOptionPane to ask the user a question
  • In the above example, we asked the question like this:
  • JOptionPane.showConfirmDialog(null, "Are you sure?");
    

Output with showMessageDialog()

  • You use the showMessageDialog() to show the user a message
  • From the above example:
  • String message = "First name: " + inputString + "\n\n"
                     + "Press enter to exit.";
    JOptionPane.showMessageDialog(null, message);
    
  • Since both showInputDialog() and showConfirmDialog() display a message, you can use them for output as well

Commonly-Used Methods of JOptionPane

Static Method Description
showConfirmDialog() Asks a confirming question, like yes/no/cancel.
showInputDialog() Prompts for user text input.
showMessageDialog() Tell the user about something that has happened.

13.1.5: Dialog Options

  • Most methods of JOptionPane are overloaded to allow different options
  • These options control dialog placement, messages and icons displayed, and title-bar wording
  • Both showInputDialog() and showMessageDialog() accept the arguments listed in the table below
  • showInputDialog() can accept four arguments
  • JOptionPane.showInputDialog(parentComponent, messageString,
            titleString, messageTypeInt);
    
  • To display a different dialog without an input field:
  • JOptionPane.showMessageDialog(parent, message);
    
  • If the parent component is unknown, you can use null for that argument
  • JOptionPane.showMessageDialog(null, "Hello, world!");
    
  • You will need to look up the exact usage in the JOptionPane API documentation

Commonly-Used Arguments in JOptionPane Methods

Argument Description
parentComponent An object representing the frame of the dialog box and controls its placement on the screen. If null is used, the dialog is centered on the screen.
messageString A descriptive message displayed in the dialog box.
titleString A title typically placed in the title bar above the dialog box.
messageTypeInt Indicates the type of icon to display in the dialog box. Use one of the fields of JOptionPane to choose the icon.

Icons provided by JOptionPane

Icon Message Type Description
ERROR_MESSAGE Displays an error icon.
INFORMATION_MESSAGE Displays an information icon.
WARNING_MESSAGE Displays an warning icon.
QUESTION_MESSAGE Displays an question icon.
  PLAIN_MESSAGE Does not display an icon.

Further Information

13.1.6: Summary

  • A JLabel is commonly used to display text or images in a GUI
  • An image is loaded into an ImageIcon
  • A JTextField provides a single line area for users to type information
  • A JPasswordField extends JTextField and hides characters that a user enters
  • Grouping labels and text fields keeps associated components together during resizing
  • Another way to get typed input is using the JOptionPane class
  • JoptionPane produces "popup" dialog boxes for simple interactions with users
  • Code for dialogs can be minimal and is usually coded using "one-liners"
  • String inputString = JOptionPane.showInputDialog(
        "Enter your first name:");
    
  • Which produces the following input dialog
  • Most methods of JOptionPane are overloaded to accept arguments
  • These options control dialog placement, messages and icons displayed, and title-bar wording
  • You will need to look up the exact usage in the Java API documentation

Check Yourself

  1. How do you set the text for a label?
  2. How are text fields added to a container?
  3. How can the text be retrieved from a text field?
  4. How can text in a text field be changed?
  5. What does the pack() method do?
  6. How many statements are typically needed to code a dialog box?

Exercise 13.1

In this exercise we create a popup window to work with text fields.

Specifications

  1. Save the following code file as LoginDemo.java.
  2. Compile and run the code to look at its various features.
  3. Change the showMessage() method to display the message in a popup.
  4. Submit your modified program as the answer for this exercise.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class LoginDemo extends JFrame {
    public final static int X_LOC = 100, Y_LOC = 100;
    private JTextField login;
    private JPasswordField password;
    private JButton loginButton;

    public static void main(String[] args) {
        new LoginDemo();
    }

    public LoginDemo() {
        super("Login Application");
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        JLabel loginLabel = new JLabel("User name:");
        login = new JTextField(10);
        JPanel loginPanel = new JPanel();
        loginPanel.add(loginLabel);
        loginPanel.add(login);

        JLabel pwdLabel = new JLabel("Password:");
        password = new JPasswordField("asecret", 10);
        JPanel pwdPanel = new JPanel();
        pwdPanel.add(pwdLabel);
        pwdPanel.add(password);

        loginButton = new JButton("Press to Login");
        JPanel buttonPanel = new JPanel();
        buttonPanel.add(loginButton);

        add(loginPanel, BorderLayout.NORTH);
        add(pwdPanel, BorderLayout.CENTER);
        add(buttonPanel, BorderLayout.SOUTH);

        LoginListener listener = new LoginListener();
        login.addActionListener(listener);
        password.addActionListener(listener);
        loginButton.addActionListener(listener);

        setLocation(X_LOC, Y_LOC);
        pack();
        setVisible(true);
    }

    private void showMessage() {
        String message = "Login: " + login.getText()
            + "\nPassword: "
            + new String(password.getPassword());
        System.out.println(message);

    }

    class LoginListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            if (e.getSource() == login) {
                password.requestFocus();
            } else if (e.getSource() == password) {
                showMessage();
                login.requestFocus();
            } else if (e.getSource() == loginButton) {
                showMessage();
                login.requestFocus();
            }
        }
    }
}

13.2: Toolkits and Other Tools

Objectives

At the end of the lesson the student will be able to:

  • Use implementations of the Toolkit class
  • Play sounds in a Swing application
  • Run Java applications as a Windows executable

13.2.1: About Toolkits

  • The Toolkit class provides some methods that query the operating system directly
  • Look below to see some of the more commonly used methods
  • To get a Toolkit object, you use the static method getDefaultToolkit() of the Toolkit class
  • Toolkit tk = Toolkit.getDefaultToolkit();
    
  • The returned Toolkit object then allows you to use Toolkit methods

Some Commonly Used Methods of the Toolkit Class

Method Description
beep() Emits an audio beep.
getDefaultToolkit() A static method that returns the default toolkit for the system.
getScreenSize() Returns the screen resolution of the current system as a Dimension object.

For Example

  • The number of pixels on a screen varies from one computer to the next
  • To determine the number of pixels on a screen, you can use a Toolkit object
  • The getScreenSize() method returns a Dimension object containing the size
  • From the Dimension object you can get the height and width
  • Using the height and width, you can center the location of a frame
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Beeper extends JFrame {
    public final static int WIDTH = 200, HEIGHT = 125;
    private JButton beepButton;

    public static void main(String[] args) {
        new Beeper();
    }

    public Beeper() {
        super("Beeper");
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        beepButton = new JButton("Play beep");
        beepButton.addActionListener(new BeepListener());
        JPanel buttonPanel = new JPanel();
        buttonPanel.add(beepButton);
        add(buttonPanel);

        // Center application window
        Toolkit tk = Toolkit.getDefaultToolkit();
        Dimension d = tk.getScreenSize();
        setBounds((d.width - WIDTH) / 2,
                  (d.height - HEIGHT) / 2,
                  WIDTH, HEIGHT);
        setVisible(true);
    }

    class BeepListener implements ActionListener {
        public void actionPerformed(ActionEvent ae) {
            Toolkit tk = Toolkit.getDefaultToolkit();
            tk.beep();
        }
    }
}

13.2.2: Playing Sounds

  • Sometimes you want an application to play a sound
  • The Applet class provides a simple method to play recorded sound files
  • You can use this method in either applets or applications
  • Java supports many sound files including: AU, AIFF, MIDI and WAV
  • To play a sound file, you use code like this:
  • AudioClip audioClip = Applet.newAudioClip(urlObject);
    audioClip.play();
    

Applet Method Used to Instantiate an AudioClip

Method Description
Applet.getAudioClip(urlObject) Static method that returns an AudioClip that you can use to play sounds.

Three AudioClip Methods for Controlling Sounds

Method Description
loop() Starts playing this audio clip in a loop.
play() Starts playing this audio clip one time.
stop() Stops playing this audio clip.

For Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import javax.swing.*;

public class SoundDemo extends JFrame {
    public final static int X_LOC = 100, Y_LOC = 100;

    private JButton loopButton;
    private JButton playButton;
    private JButton stopButton;
    private JTextField nameField;
    private AudioClip audioClip;

    public static void main(String[] args) {
        new SoundDemo();
    }

    public SoundDemo() {
        super("Sound Application");
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        JLabel prompt = new JLabel("File name:");
        nameField = new JTextField(15);
        JPanel panel = new JPanel();
        panel.add(prompt);
        panel.add(nameField);

        loopButton = new JButton("Loop");
        playButton = new JButton("Play");
        stopButton = new JButton("Stop");
        JPanel buttonPanel = new JPanel();
        buttonPanel.add(playButton);
        buttonPanel.add(loopButton);
        buttonPanel.add(stopButton);

        Container contentPane = getContentPane();
        contentPane.add(panel, BorderLayout.NORTH);
        contentPane.add(buttonPanel);

        ButtonListener bl = new ButtonListener();
        loopButton.addActionListener(bl);
        playButton.addActionListener(bl);
        stopButton.addActionListener(bl);
        nameField.addActionListener(bl);

        setLocation(X_LOC, Y_LOC);
        pack();
        setVisible(true);
    }

    public URL getFileURL() {
        File f = new File(nameField.getText());
        URL fileUrl = null;
        try {
            fileUrl = new URL("file:" + f.getPath());
        } catch(IOException ioe) {
            System.out.println(ioe.toString());
            System.exit(1);
        }
        return fileUrl;
    }

    public void play() {
        stop();
        URL soundURL = getFileURL();
        System.out.println("Now playing: " + soundURL);
        audioClip = Applet.newAudioClip(soundURL);
        audioClip.play();
    }

    public void loop() {
        stop();
        URL soundURL = getFileURL();
        System.out.println("Now looping: " + soundURL);
        audioClip = Applet.newAudioClip(soundURL);
        audioClip.loop();
    }

    public void stop() {
        if (audioClip != null) {
            System.out.println("Stopped playing");
            audioClip.stop();
            audioClip = null;
        }
    }

    class ButtonListener implements ActionListener {
        public void actionPerformed(ActionEvent ae) {
            Object source = ae.getSource();
            if (source == playButton || source == nameField) {
                play();
            } else if (source == loopButton) {
                loop();
            } else if (source == stopButton) {
                stop();
            }
            nameField.requestFocus();
        }
    }
}
  • The SoundDemo() constructor creates the GUI
  • actionPerformed() decides which button was and calls the associated method
  • Method getFileURL() uses the nameField to construct a URL object
  • Method play() starts an AudioClip playing
  • Method loop() starts an AudioClip looping
  • Method stop() halts and destroys the current AudioClip object

More Information

13.2.3: Running Java as a Windows Executable

  • Windows users are used to double-clicking an icon to launch an application
  • Java does not support directly this type of action
  • However, you can use the Marner Java Launcher to achieve this effect
  • The Marner Java Launcher consists of two files:
    • launch.exe
    • launcher.cfg
  • launch.exe is a Windows executable that launches a Java application
  • launcher.cfg is a text file that tells launch.exe what to run

A Simple Example Using the Marner Java Launcher

  1. Install all your files into one directory including
    • launch.exe
    • launcher.cfg
    • Your .class files
  2. Rename the launch.exe file to any name you like
  3. Hello.exe
  4. Edit the launcher.cfg file like the one shown below

Example Configuration File: Hello.cfg

.
javaw.exe
HelloFrame3
  1. First line: use the current directory (.) for running or specify a path to another directory
  2. Second line: the java executable file (java.exe or javaw.exe) to run. If the JDK bin directory is not in the path, you should specify an exact path.
  3. C:\j2sdk1.5.0_04\bin\javaw.exe
  4. Third line: parameters to java.exe (or javaw.exe) such as your .class file that contains the main() method.
  5. Optionally, package the files using ZIP or JAR

Using java.exe vs. javaw.exe

  • You can use either java.exe or javaw.exe to run a Java application
  • java.exe runs with a console window
  • javaw.exe runs without a console window

Example Application: HelloFrame3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class HelloFrame3 extends JFrame {
    public final static int X_LOC = 100, Y_LOC = 100,
                            WIDTH = 300, HEIGHT = 150;
    private JButton helloButton;
    private JButton exitButton;

    public static void main(String[] args) {
        new HelloFrame3();
    }

    public HelloFrame3() {
        super("Hello Frame Application");
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        helloButton = new JButton("Hello");
        helloButton.addActionListener(new HelloListener());
        exitButton = new JButton("Exit");
        exitButton.addActionListener(new ExitListener());
        JPanel panel = new JPanel();
        panel.add(helloButton);
        panel.add(exitButton);
        add(panel);

        setBounds(X_LOC, Y_LOC, WIDTH, HEIGHT);
        setVisible(true);
    }
}

class HelloListener implements ActionListener {
    public void actionPerformed(ActionEvent ae) {
        System.out.println("Hey");
    }
}

class ExitListener implements ActionListener {
    public void actionPerformed(ActionEvent ae) {
        System.out.println("Goodbye!");
        System.exit(0);
    }
}

More Information

Exercise 13.2

In this exercise we use the Toolkit to play sounds and then run the applications as a Windows executable.

Specifications

  1. Save the following code file as Beeper.java.
  2. Compile and run the code to check its various features.
  3. Setup the Marner Java Launcher to run the application.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Beeper extends JFrame {
    public final static int WIDTH = 200, HEIGHT = 125;
    private JButton beepButton;

    public static void main(String[] args) {
        new Beeper();
    }

    public Beeper() {
        super("Beeper");
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        beepButton = new JButton("Play beep");
        beepButton.addActionListener(new BeepListener());
        JPanel buttonPanel = new JPanel();
        buttonPanel.add(beepButton);
        add(buttonPanel);

        // Center application window
        Toolkit tk = Toolkit.getDefaultToolkit();
        Dimension d = tk.getScreenSize();
        setBounds((d.width - WIDTH) / 2,
                  (d.height - HEIGHT) / 2,
                  WIDTH, HEIGHT);
        setVisible(true);
    }

    class BeepListener implements ActionListener {
        public void actionPerformed(ActionEvent ae) {
            Toolkit tk = Toolkit.getDefaultToolkit();
            tk.beep();
        }
    }
}

13.3: Introduction to Graphics

Objectives

At the end of the lesson the student will be able to:

  • Discuss video hardware and screen layout
  • Describe how various colors are created
  • Explain how images and shapes are rendered to pixels
  • Create a drawing area on a video screen
  • Draw simple shapes
  • Display text using various fonts

13.3.1: Screen Hardware and Layout

  • To create effective graphics, we need to understand how graphics are displayed
  • There are two parts to a display screen: the video card and the monitor
  • The video card stores what to display on the screen in its memory
  • In addition, the video card tells the monitor what to display and when to display it
  • The monitor just displays what the video card tells it to
  • The monitor's screen is divided into tiny little color dots called pixels
    • Every pixel is the same size
  • Every single pixel has an x-coordinate and y-coordinate
  • The x and y coordinates start from the upper-left corner of the drawing area
  • Note that coordinates are positive numbers

Video Resolution

  • How many pixels that can be displayed is known as the video resolution
  • Resolution depends on the capabilities of the video card and monitor
  • The oldest computers had a resolution of 640x480
  • Today, most computers have a resolution of at least 800x600 and commonly 1024x768
  • Newer computers have resolutions of 1280x1024 or 1600x1200
  • Older CRT monitors can display several resolutions with the same quality
  • However, newer LCD (liquid crystal display) monitors have a single native resolution that produces the best results
  • Using non-native resolutions can make the display look fuzzy or blocky
  • Because of this, you should make sure your program can run in two or three different resolutions
  • Then the player can pick the one that looks best on their system

Refresh Rate

  • Even though an image on your monitor looks solid, each pixel actually fades away after a few milliseconds
  • Because of this, the monitor has to continuously refresh the display to keep it from fading
  • The refresh rate is how frequently the monitor refreshes the display
  • Refresh rate is measure in Hertz (Hz) which means cycles per second
  • Refresh rates between 75 Hz and 85 Hz are suitable for the human eye

More Information

13.3.2: Pixels, Colors and Bit Depth

  • Most screens use a color model known as RGB (Red, Green, Blue)
    • On CRT monitors, three different color dots are excited at different intensities
    • On LCD monitors, three different transistors are used to control how much light for each color is let through
  • The number of colors that a monitor can display depends on the number of bits stored for each pixel
  • Bit depth is the number of bits assigned to each pixel
  • The most common bit depths are 8, 16, 24 and 32 bits
    • 8-bit: also known as VGA (Video Gate Array) color, only 28 = 256 colors can be displayed. However only 216 colors are "web-safe".
    • 16-bit: Red = 5, Green = 5, Blue = 6, for a total of 216 = 65,536 colors
    • 24-bit: Red = 8, Green = 8, Blue = 8, for a total of 224 = 16,777,216 colors
    • 32-bit: Same as 24 bit with 8 bits of padding for 32-bit computer word boundaries
  • Since the human can see only about 10 million colors, 24-bit color is more than enough
  • 16-bit color is a little faster but has less accuracy

Color Coding

  • Java Supports the standard RGB color model using the Color class
  • Colors are created from red, green and blue (RGB) values
  • For example:
  • Color brown = new Color(204, 102, 0);
    
  • RGB values can be specified as either type float (0.0 to 1.0) or type int (0 to 255)
  • Color(float r, float g, float b) // 0.0 - 1.0
    Color(int r, int g, int b)       // 0 - 255
    
  • The Color class has several static color constants that you can use in place of numbers
  • Color.RED

More Information

13.3.3: Rendering to Pixels

  • Render: calculate and store pixel data
  • Graphics Context: an object that contains drawing properties and rendering methods for the drawing area
  • Every image, shape or text drawn on a screen must be rendered into pixels
  • To render pixels to a screen or other device, you use an object of:
  • You use the same rendering process whether the output device is a screen or a printer.

Graphics vs. Graphics2D

  • Note that class Graphics2D extends class Graphics to support more graphics attributes and provide new rendering methods
  • The reason for the two classes is historical
  • Class Graphics was released in the original Java libraries
    • Provided graphics suitable for most devices of that time
  • Class Graphics2D was added in Java 1.2
    • Provided more advanced capabilities
  • Using inheritance made sure that old code worked with the newer Java versions

Some Graphics Methods that Draw Shapes

drawLine(int x1, int y1, int x2, int y2)
drawRect(int x, int y, int width, int height)
drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)
drawOval(int x, int y, int width, int height)
drawArc(int x, int y, int width, int height, int startAngle, int arcAngle)

Some Graphics Methods that Fill Shapes

fillRect(int x, int y, int width, int height)
fill3DRect(int x, int y, int width, int height, boolean raised)
fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)
fillOval(int x, int y, int width, int height)
fillArc(int x, int y, int width, int height, int startAngle, int arcAngle)

Some Additional Graphics2D Methods

draw(Shape s)
fill(Shape s)

13.3.4: Creating a Drawing Area

  • In order to draw images, shapes or text, you need a drawing window on the screen
  • A javax.swing.JFrame provides a suitable window
  • JFrame frame = new JFrame();
  • However, you cannot draw on a JFrame directly
  • Instead, you usually add another Component, such as a JPanel, to the JFrame
  • Then you draw on the added component
  • To draw an image, shape or text, you need to get the graphics context
  • To get the graphics context, you can use inheritance and override the paint() method as shown in the following example
  • Alternatively, you can call the getGraphics() method of the drawing component
  • JPanel panel = new JPanel();
    ...
    Graphics g = panel.getGraphics();
    

Example Code for a Drawing Panel Using Inheritance

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import java.awt.*;
import javax.swing.*;

public class DrawingPanel extends JPanel {
    public static int HEIGHT = 300;
    public static int WIDTH = 400;
    public static int FONT_SIZE = 24;

    public static void main(String args[]) {
        // Setup JFrame
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Create a drawing component and add it to the frame
        DrawingPanel panel = new DrawingPanel();
        panel.setBackground(Color.BLUE);
        frame.add(panel);

        // Set the frame size and make it visible
        frame.setSize(WIDTH, HEIGHT);
        frame.setVisible(true);
    }

    public void paint(Graphics g) {
        super.paint(g);

        g.setColor(Color.RED);
        g.drawLine(5, 30, 350, 30);

        g.setColor(Color.WHITE);
        g.drawRect(5, 40, 90, 55);
        g.fillRect(100, 40, 90, 55);

        g.setColor(Color.CYAN);
        g.fillRoundRect(195, 40, 90, 55, 50, 50);
        g.drawRoundRect(290, 40, 90, 55, 20, 20);

        g.setColor(Color.YELLOW);
        g.draw3DRect(5, 100, 90, 55, true);
        g.fill3DRect(100, 100, 90, 55, false);

        g.setColor(Color.MAGENTA);
        g.drawOval(195, 100, 90, 55);
        g.fillOval(290, 100, 90, 55);

        g.setColor(Color.YELLOW);
        Font f = new Font("Serif", Font.BOLD | Font.ITALIC,
                          FONT_SIZE);
        g.setFont(f);
        g.drawString("Hello Graphics World!", 5, 200);
    }
}

Drawing Arcs

  • Arcs are just a portion of an oval
  • Specify the beginning angle and the degrees of the sweep
  • g.drawArc(x, y, width, height, startAngle, arcAngle);
    
  • Sweep starts at the specified starting angle
  • Sweeps through the number of degrees specified in the arc angle
  • Counterclockwise sweep is measure in positive degrees
  • Clockwise sweep is measure in negative degrees

13.3.5: A Few Words About Drawing Text

  • A font is a style of text
  • Class Font contains methods and constants for font control
  • A Font constructor takes three arguments
    • Font name: Monospaced, SansSerif, Serif, etc.
    • Font style: Font.PLAIN, Font.ITALIC and Font.BOLD
    • Font size: measured in points (1/72 of inch)
    • Note that point sizes are only approximate
  • For example:
  • int FONT_SIZE = 24;
    Font f = new Font("Serif",
                      Font.BOLD | Font.ITALIC,
                      FONT_SIZE);
    g.setFont(f);
    
  • Method setFont() in a Graphics object can be used to change the current font
  • Java guarantees that at least three fonts will be available:
    • Monospaced
    • SanSerif
    • Serif
  • Programs can use the drawString() method to display text on the screen
    • The first parameter tells which characters to display.
    • Last two parameters specify the starting location of the text
  • For example:
  • g.drawString("Hello Graphics World", 20, 50);
    

Anti-Aliasing

  • The following is a twice-sized image of the message from the drawing panel
  • Note that the edges appear jagged
  • Jagged edges are a common font problem and the solution is called anti-aliasing
  • Anti-aliasing works by blurring the edges so that the text color blends with the background color
  • This makes the edges appear sharper as shown in the following where anti-aliasing was applied
  • Java applies anti-aliasing using RenderingHints
  • Since RenderingHints are available only in Graphics2D, you must cast the Graphics object to Graphics2D
  • The following is a revised paint() method for the DrawingPanel showing how to apply anti-aliasing to text
  • public void paint(Graphics g) {
        super.paint(g);
        if (g instanceof Graphics2D) {
            Graphics2D g2 = (Graphics2D) g;
            g2.setRenderingHint(
                RenderingHints.KEY_TEXT_ANTIALIASING,
                RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        }
        g.setColor(Color.YELLOW);
        int FONT_SIZE = 24;
        Font f = new Font("Serif",
                          Font.BOLD | Font.ITALIC,
                          FONT_SIZE);
        g.setFont(f);
        g.drawString("Hello Graphics World!", 20, 50);
    }
    

More Information

13.3.6: Summary

  • Java provides many graphical capabilities
  • In this section we looked at how to draw simple shapes and use colors
  • Drawing shapes and setting colors is done with the Graphics object
    • Drawing starts in the upper left-hand corner of the screen
  • The easiest way to get access to the Graphics object is from a GUI component
  • A handy object to draw on is a JPanel:
  • public class DrawingPanel extends JPanel
  • Which we can add to a JFrame
  • JFrame frame = new JFrame();
    DrawingPanel panel = new DrawingPanel();
    frame.add(panel);
    
  • To draw, you override the paint() method
  • public void paint(Graphics g) {
        super.paint(g);
        // add code here
    }
    
  • When you override a paint() method, you should call the superclass method before adding you own code
  • The paint() method lets us access the Graphics object
  • We used the methods of the Graphics object to draw a variety of shapes
  • g.drawLine(5, 30, 350, 30);
    g.drawRect(5, 40, 90, 55);
    g.fillRect(100, 40, 90, 55);
    g.fillRoundRect(195, 40, 90, 55, 50, 50);
    g.drawRoundRect(290, 40, 90, 55, 20, 20);
    g.draw3DRect(5, 100, 90, 55, true);
    g.fill3DRect(100, 100, 90, 55, false);
    g.drawOval(195, 100, 90, 55);
    g.fillOval(290, 100, 90, 55);
    
  • Also, you use the Color object to set colors for the shapes
  • g.setColor(Color.RED);
  • In addition, you can downcast the Graphics object to a Graphics2D object
  • public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D)g;
        // do something with g2d
    }
    
  • Graphics2D provides many more capabilities than Graphics
  • For example, you can anti-alias text for a less-jagged look
  • g2.setRenderingHint(
        RenderingHints.KEY_TEXT_ANTIALIASING,
        RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    

Exercise 13.3

Take one minute to prepare an answers to the following:

  1. Where is the origin point of the graphics screen?
  2. What data types does the constructor of the Color class take?
  3. What is the size of the area affected by the following code?
  4. public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.fillRect(10, 10, 30, 30);
    }
    
    1. 19 x 19 pixels
    2. 20 x 20 pixels
    3. 21 x 21 pixels
    4. 29 x 29 pixels
    5. 30 x 30 pixels
    6. 31 x 31 pixels

13.4: Displaying Images

Objectives

At the end of the lesson the student will be able to:

  • Objective 1
  • Objective 2
  • Objective 3

13.4.1: Images and Transparency

  • Images are a common way to show complex graphics in games
  • In this section we learn how to display images on the screen
  • One of the important characteristics of images is transparency

Transparent Pixels

  • Images are always drawn in a rectangular region
  • When you work with certain images, like a game character, you want to draw the image on various backgrounds
  • Creating a different image for each background would be cumbersome
  • Instead, you make the background area of the character image transparent
  • When you combine the two images, the background show through the transparent areas

For Example

  • The following is the same image shown twice but on different backgrounds
  • The images look different because parts of the image are transparent and the background shows through

Alpha Compositing

  • Programs that support transparency use what is known as an alpha compositing
  • Images are stored in at least two separate layers
  • Layers of an image are drawn in separate passes
  • The transparent background is one of the layers
  • The rest of the image is stored in the other layers
  • To keep track of the image shapes in each layer, an alpha channel or layer is used

Translucent Pixels

  • Translucent pixels are partially transparent
  • You can use partially transparent pixels to create a ghostlike image
  • A more common use is to make the edges of an image translucent as a form of anti-aliasing

More Information

13.4.2: Image Formats

  • There are two basic types of image formats: raster and vector
  • A raster format describes images in terms of pixels just like a video screen
  • A vector format describes each shape geometrically: lines, ovals, etc
    • The advantage of vector graphics is that images can be resized without degrading their quality
    • Vector graphics are converted to a raster format before being displayed
  • Java core libraries do not support vector graphics
    • You can add vector graphics using Batik or other add-on libraries
  • Our focus is the three raster images supported by Java:
    • GIF (Graphics Interchange Format)
    • PNG (Portable Network Graphics)
    • JPEG (Joint Photographic Experts Group)
  • Java makes these types of images are easy to use

GIF (Graphics Interchange Format)

  • GIF images can be either opaque or transparent
  • Limited to 8-bit color maximum
  • Has high compression for graphics images without much color variation
  • However, PNG supercedes GIF's functionality
  • No reason to use GIF when PNG is available

PNG (Portable Network Graphics)

  • Can use up to 48-bit color
  • Supports all types of transparency: opaque, transparent or translucent
  • PNG graphics are smaller than GIF

JPEG (Joint Photographic Experts Group)

  • Only 24-bit, opaque images supported
  • High compression for photographic images, but compression is lossy
    • Image is not an exact replica of the source

More Information

13.4.3: Obtaining Images

  • Game development teams usually have graphic artists to create images
  • If you are developing games by yourself, you must come up with your own images
  • Two basic ways to come up with graphics:
    • Use media libraries
    • Create your own

Media Libraries

  • Google search for "free game graphics"
  • Sprite set by Ari Feldman: spritelib (see license)
  • NASA images: GRIN
    • Collection of NASA photos and art that are non-copyrighted (Public Domain)
    • Works created by employees of the federal government are not entitled to copyright protection.
  • Public Domain audio and graphics at www.croftsoft.com/library/media/
  • Low cost Clip Art collections from places like Cosmi
  • Open source games
  • In general, be suspicious of sources and check licensing thoroughly

Creating Images

  • Even if you are not an artist, you can create your own graphics
  • Digital cameras are easy to use
  • Can also use paint or draw programs to create images
  • Windows: Start / Programs / Accessories / Paint
  • The GIMP (Gnu Image Manipulation Program): www.gimp.org
    • Runs on Linux and Windows
    • Professional capability
    • Online documentation and tutorials
  • See FAQ: Why can't I use PhotoShop in the CTC?

More Information

13.3.4: Reading Image Files

  • Let us look at how we can display a GIF, PNG or JPEG file on the screen
  • An image file is stored in an Image object
  • The code to read an image file and save it in an Image is:
  • ImageIcon icon = new ImageIcon("image.jpg");
    Image myImage = icon.getImage();
    

Test Program to Read and Display Images

  • In the following code, we load five image files provided by the textbook
  • One image file is used as the background image
  • Other files are same image but with various types of transparency applied
  • Note that the background image is from a JPEG file and the others are from PNG files
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import java.awt.*;
import javax.swing.*;

public class ImageTest extends JPanel {
    public static final int WIDTH = 640, HEIGHT = 640;
    public static final int FONT_SIZE = 24;

    private Image bgImage;
    private Image opaqueImage;
    private Image transparentImage;
    private Image translucentImage;
    private Image antiAliasedImage;
    private boolean imagesLoaded = false;

    public static void main(String[] args) {
        // Setup JFrame
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Create a drawing component and add it to the frame
        ImageTest panel = new ImageTest();
        frame.add(panel);

        // Set the frame size and make it visible
        frame.setSize(WIDTH, HEIGHT);
        frame.setVisible(true);

        panel.loadImages();
    }

    public void loadImages() {
        bgImage = loadImage("images/background.jpg");
        opaqueImage = loadImage("images/opaque.png");
        transparentImage = loadImage("images/transparent.png");
        translucentImage = loadImage("images/translucent.png");
        antiAliasedImage = loadImage("images/antialiased.png");
        imagesLoaded = true;
        // Signal to AWT to repaint this window
        repaint();
    }

    private Image loadImage(String fileName) {
        return new ImageIcon(fileName).getImage();
    }

    public void paint(Graphics g) {
        super.paint(g);
        if (!imagesLoaded) return;
        g.setColor(Color.WHITE);
        g.setFont(new Font("Dialog", Font.PLAIN, FONT_SIZE));
        // set text anti-aliasing
        if (g instanceof Graphics2D) {
            Graphics2D g2 = (Graphics2D)g;
            g2.setRenderingHint(
                RenderingHints.KEY_TEXT_ANTIALIASING,
                RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        }
        // draw images
        g.drawImage(bgImage, 0, 0, null);
        drawImage(g, opaqueImage, 0, 0, "Opaque");
        drawImage(g, transparentImage, 320, 0, "Transparent");
        drawImage(g, translucentImage, 0, 300, "Translucent");
        drawImage(g, antiAliasedImage, 320, 300,
            "Translucent (Anti-Aliased)");
    }

    public void drawImage(Graphics g, Image image, int x, int y,
            String caption) {
        g.drawImage(image, x, y, null);
        g.drawString(caption, x + 5, y + FONT_SIZE +
            image.getHeight(null));
    }
}

13.4.5: Summary

Exercise 13.3

Take one minute to prepare an answers to the following:

  1. Where is the origin point of the graphics screen?
  2. What data types does the constructor of the Color class take?
  3. What is the size of the area affected by the following code?
  4. public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.fillRect(10, 10, 30, 30);
    }
    
    1. 19 x 19 pixels
    2. 20 x 20 pixels
    3. 21 x 21 pixels
    4. 29 x 29 pixels
    5. 30 x 30 pixels
    6. 31 x 31 pixels

Wrap Up

    Reminders

    Due Next:
    Exercise 12 (11/23/05)
    Sampler Project (12/5/05)

  • When class is over, please shut down your computer
  • There is no need to turn in this weeks exercises
  • Work on your project!

Home | WebCT | Announcements | Schedule | Expectations | Course info
Help | FAQ's | HowTo's | Links

Last Updated: November 23 2005 @09:45:59