Вы находитесь на странице: 1из 271

Topics of this chapter

0 Evolution of the Java GUI 0 Swing Vs. AWT 0 Swing 0 Buttons, events, and other swing 0 Basics ,containers and layout managers 0 Menus and buttons, text fields and text areas 0 Window listeners, icons and scroll bars 0 Color and font ,Loading 0 Playing Audio Clips , Playing Video
Chap-3 Adv Prog 2

Evolution of Java GUI


0 Java 1.0 AWT built in 30 days, and it shows Java 1.1 AWT

significantly improved, but GUI not finished yet 0 Java 2 Swing: very different, vastly improved

Chap-3 Adv Prog

JDK 1.0 (circa 1996)


0 JDK 1.0 went a long way to implementing platform-

independent GUI library

0 Bruce Eckel: it "produced a GUI that looks equally mediocre

on all systems." 0 Just 4 fonts 0 Couldnt access GUI of native OS 0 Didnt separate model and UI code cleanly

Chap-3 Adv Prog

JDK 1.1 (circa 1998)


0 JDK 1.1 makes AWT more robust and extensible 0 Delegation-based event model separates user interface from problem domain 0 Other enhancements: button tool tips, cut/paste to

the clipboard, popup menus, printing, etc.


0 Adds supports for JavaBeans

Chap-3 Adv Prog

JDK 1.2 (Swing)


0 JDK 1.2 adds Java Foundation Classes

0 Swing is the GUI library for JDK 1.2


0 Much richer class library plus better integration with look

and feel of GUI of OS

Chap-3 Adv Prog

Java Foundation Class


0 JFC(Java Foundation Class) has two parts: 0 Abstract Window Toolkit (AWT) 0 Original user interface toolkit 0 Refers to the set of classes provided by Java that enables the

creation of a graphical user interface and provide a mechanism to handle user input through the mouse and keyboard. 0 Swing 0 Introduced in Java 1.2 0 Swing is the codename of the project that developed the first JFC components (JFC 1.1) which is initially released as an extension to JDK 1.1.
Chap-3 Adv Prog 7

Swing Vs. AWT


0 AWT is Javas original set of classes for building GUIs 0 Uses peer components of the OS; heavyweight components 0 Not truly portable: looks different and lays out inconsistently on

different OSs 0 Due to OSs underlying display management system 0 Swing is designed to solve AWTs problems 0 99% java; lightweight components 0 Drawing of components is done in java 0 Uses AWTs components like Window, frame, dialog 0 Lays out consistently on all OSs 0 Uses AWT event handling 0 Swing provides several advanced components such as tabbed panel, scroll panes, trees, tables and lists. 0 Unlike AWT components, Swing components are not implemented by platform-specific code. Instead they are written entirely in Java and therefore are platform-independent. The term "lightweight" is used to describe such an element.
Chap-3 Adv Prog 8

Swing Vs. AWT


0 Swing provides replacements for most of the AWT components, althoght

many AWT non-component classes remain in use. Upward compatibility is assured in almost all cases; an AWT continues to work in Java. 0 Mixing both Swing andAWT components in the same interface can produce errors, so one has to make a decision about which to use. Despite the advantages of Swing, there actually are arguments for using AWT. 0 Swing advantages
Swing is faster. Swing is more complete. Swing is being actively improved.

0 AWT advantages
AWT is supported on older, as well as newer, browsers so Applets written in AWT will run on more browsers.

The Java Micro-Edition, which is used for phones, TV settop boxes, PDAs, etc, uses AWT, not Swing.

Chap-3 Adv Prog

Peer classes at run-time


class TestPeer { TestPeer() { Frame myFrame = new Frame("my Frame"); //create window Frame Button myButton = new Button("my Button"); //create myButton myFrame.add("Center",myButton); //put Attach (add) myButton in myFrame myFrame.setVisible(true); //button appears in window on screen by // setting myFrame and myButton visible, // by creating platform-specific peer objects. //setVisible() creates peer objects for myFrame & myButton ComponentPeer buttonPeer = myButton.getPeer(); //now works } }

0 0 0 0 0 0

TestPeer first constructs a frame, then adds a button on the frame setVisible method creates peer objects on platform Last line now accesses myButtons peer object Peer classes are usually hidden from developers. In fact, in newer versions of JDK, getPeer() method is "deprecated" Peer classes strongly discouraged for code maintenance purposes
Chap-3 Adv Prog 10

Swing is Java's GUI(graphical user interface) library So far, our user interfaces have only been textual,

WHAT IS SWING?

meaning the user sees text and writes text at the command prompt. Swing is created to provide a more sophisticated set of GUI components than the Abstract Windows Toolkit (AWT) Today we will learn to make our interfaces graphical, so we can use our programs through windows, click on buttons, etc. You MUST import the following packages to use swing:
import java.awt.*; import javax.swing.*;
Chap-3 Adv Prog 11

WHAT IS SWING?
0 Swing Java consists of
Pluggable Look and feel manse each picture shows the

same program but with a different look and feel Accessibility API - Screen readers, Braille displays, ... Java 2D Drag and Drop - Between Java applications and native applications

Chap-3 Adv Prog

12

WHAT IS SWING?
0 Swing is a Java package, javax.swing, provided in J2SDK (Java

2 Software Development Kit). It provides many enhancements to the existing graphics package, AWT (Abstract Windows Toolkit) package, java.awt. 0 javax.swing and java.awt together offer a complete API (Application Programming Interface) for Java applications to operate graphical devices and create GUI (Graphical User Interfaces). 0 The Swing components are implemented entirely in the Java programming language.

Chap-3 Adv Prog

13

WHAT IS SWING?
The Swing package in JDK 1.6 and recent versions contains following sub packages:
0 javax.swing - Provides a set of "lightweight" (written in Java with no native 0 0 0 0 0 0 0 0

code) components that, to the maximum degree possible, work the same on all platforms. javax.swing.border - Provides classes and interfaces for drawing specialized borders around a Swing component. javax.swing.colorchooser - Contains classes and interfaces used by the JColorChooser component. javax.swing.event - Provides support for events fired by Swing components. javax.swing.filechooser - Contains classes and interfaces used by the JFileChooser component. javax.swing.plaf - Provides one interface and many abstract classes that Swing uses to provide its pluggable look and feel capabilities. javax.swing.plaf.basic - Provides user interface objects built according to the Basic look and feel. javax.swing.plaf.metal - Provides user interface objects built according to the Java look and feel (once codenamed Metal), which is the default look and feel. javax.swing.plaf.multi - Provides user interface objects that combine two or more look and feels. Chap-3 Adv Prog 14

WHAT IS SWING?
0 javax.swing.plaf.synth - Provides user interface objects for a skinnable 0 0 0

0
0

0
0

look and feel in which all painting is delegated. javax.swing.table - Provides classes and interfaces for dealing with JTable. javax.swing.text - Provides classes and interfaces that deal with editable and non-editable text components. javax.swing.text.html - Provides the class HTMLEditorKit and supporting classes for creating HTML text editors. javax.swing.text.html.parser - Provides the default HTML parser, along with support classes. javax.swing.text.rtf - Provides a class (RTFEditorKit) for creating Rich Text Format text editors. javax.swing.tree - Provides classes and interfaces for dealing with JTree. javax.swing.undo - Allows developers to provide support for undo/redo in applications such as text editors.
Chap-3 Adv Prog 15

What are Components?


0 A component is an object having a graphical representation

that can be displayed on the screen. like checkboxes, menus, windows, buttons, text fields, applets, and more. 0 A container is a special component that can hold other components.
0 Example of containers in typical GUI applications include:

panels, windows, applets, frames

Functionality of most GUI components derive from the

Component and Container classes.

Chap-3 Adv Prog

16

Components

Chap-3 Adv Prog

17

Swing Containment Hierarchy


0 Top-level container: 0 place for other Swing components to paint themselves 0 e.g., JFrame, JDialog, Japplet

Chap-3 Adv Prog

18

Swing Containment Hierarchy


0 Intermediate container: 0 simplify positioning of atomic components 0 e.g., JPanel, JSplitPane, JTabbedPane

Chap-3 Adv Prog

19

Swing Containment Hierarchy


0 Atomic components: 0 self-sufficient components that present information to and get input from the user 0 e.g., JButton, JLabel, JComboBox, JTextField, JTable

Chap-3 Adv Prog

20

Implementing a Swing GUI


0 Import javax.swing.*, java.io.*, java.awt.* 0 Make a specific class to do GUI functions 0 Specify all the GUI functions/components in the classs

constructor (or methods / classes called by the constructor) 0 Run the GUI by instantiating the class in the classs main method

Chap-3 Adv Prog

21

import javax.swing.*; public class HelloWorldSwing { public static void main(String[] args) { // lets create a frame object and give some title JFrame frame = new JFrame("HelloWorldSwing"); // lets have a label JLabel label = new JLabel("Hello World"); //lets add the label to the frame we have created above frame.getContentPane().add(label); //this is the operation to do when the window is closed. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //pack() causes a window to be sized to fit the preferred //size and layouts of its sub-components frame.pack(); // lets make the frame to be visible frame.setVisible(true); } } Chap-3 Adv Prog 22

My First Swing Program

Example 2
import javax.swing.*;
public class HelloWorldFrame extends JFrame { public HelloWorldFrame() { super(HelloWorldSwing); final JLabel label = new JLabel("Hello World"); getContentPane().add(label); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); pack(); setVisible(true); } public static void main(String[] args) { HelloWorldFrame frame = new HelloWorldFrame(); } }

In this example a custom frame is created

Components
0 Components (also known as "widgets") are the basic user

interface elements the user interacts with: labels, buttons, text fields, ... 0 Components are placed in a container (eg, JPanel). The visual arrangement of the components depends on the container's layout. When the user does something to a component, the component's listener is sent an event.

Chap-3 Adv Prog

24

Components
0 The most important components to learn for simple programs are: 0 Input Components
Buttons ( JButton, Radio Buttons, JCheckBox) Text (JTextField, JTextArea) Menus (JMenuBar, JMenu, JMenuItem) Sliders (JSlider) JComboBox (uneditable) (JComboBox)

0 Information Display Components JLabel Progress bars (JProgressBar) Tool tips (using JComponent's setToolTipText(s) method) 0 Choosers File chooser (JFileChooser) Color chooser (JColorChooser) 0 More complex displays Tables (JTable) Trees (JTree) Formatted Text
Chap-3 Adv Prog 25

Top-level Container: javax.swing.JFrame


JFrame - window, typically subclassed w =new JFrame(); Constructor w =new JFrame(t); Constructor. Sets titlebar to t.

w.setTitle(t);

Sets titlebar text to t

w.setDefaultCloseOperation(opt); JFrame.EXIT_ON_CLOSE terminates program when close box clicked. w.setVisible(true/false); Make visible (and start GUI thread) or hide.
w.pack(); w.setContentPane(cont); Calculates layout on all inner containers and sets size of JFrame. Sets the content pane - common to pass a JPanel here. Returns the window's content pane. Adds a JMenuBar. Prevent user from resizing window. Positions window's top left corner at screen coordinates (x, y). Sets window size, but use layouts and pack() instead. 26 Deprecated. Use w.setVisible(true). Deprecated. Use w.setVisible(false).

cont =w.getContentPane();
w.setJMenuBar(mb); w.setResizable(false); w.setLocation(x, y); w.setSize(w, h); w.show(); w.hide();

Anatomy of a JFrame
title bar

minimize maximize close

The contentPane holds your content; created automatically when a JFrame is created
Chap-3 Adv Prog 27

JFrame
0 JFrame is the application window class 0 It draws the window and interacts with the operating system 0 When a JFrame is created, an inner container called the

contentPane is automatically created 0 We don't draw graphics directly on JFrame; we draw on the contentPane 0 Frames are the basis of any Java GUI 0 Frame is the actual window that encompasses your GUI objects; a GUI can have multiple frames 0 The J prefix is at the beginning of any Swing components name (to distinguish them from AWT components) 0 JFrame is a wrapper around AWTs Frame
Chap-3 Adv Prog 28

JFrame
0 The javax.swing.JFrame class is used to create a "window". This

window has a few characteristics of its own (title bar, etc), but most of the controls are placed in one of two subareas: content pane or menu bar. 0 You can create a frame like this: JFrame w = new JFrame("your title"); // but it's better to use subclassing as below. 0 Subclass JFrame, build in constructor. Another better way is to define a class, eg MyWindow that extends JFrame, put the code which builds the GUI in the class's constructor, and create an instance of the window from the main program. See example below.
Chap-3 Adv Prog 29

Jframe(cont)
0 Content pane - Two styles - Get it or Set it

There are two common ways to use a JFrame's content pane. Both are commonly used. In both cases, the easiest style is to assign the working version of the content pane to 0 Get the predefined content pane and change it. Every JFrame comes with a default content pane. It doesn't have anything on it, although it does have a default layout, probably not the one you want to use though! The getContentPane() method returns a Container object, which interestingly is actually a Jpanel. 0 Create a JPanel and make it the content pane. This requires a call to setContentPane(...).
Chap-3 Adv Prog 30

Jframe(cont)
Using the content pane. c = w.getContentPane(); w.setContentPane(c); Returns window's content pane. Use either get or set, but not both. Sets window's content pane to c (or subclass JPanel). This adds a window listener that simply executes System.exit(). It's the short, appropriate, solution for most small programs. Use this to call your own window closing listener.

Handling the window's close box. w.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

w.addWindowListener(listen);

Executing the layout.


w.pack(); Finalize layout after everything is added to window and content pane. Don't use validate() with layout managers.
31

Jframe(cont)
Displaying the window. w.setVisible(true); Makes the window visible, and starts the Event Dispatch Thread (EDT) which manages the GUI. This is usually called by the main program after calling the constructor. show() should no longer be used.

Miscellaneous.

w.setTitle(title);
w.setResizable(false);

xxx
Set to false if you don't want the user to resize your window.

w.setJMenuBar(mbar);

This is how to add a menubar to the window.

w.setLocationRelativeTo(null); Centers the window. If you even bother with position, this is the most common choice. Less common positioning and sizing. w.setSize(w, h); Sets window to pixel width (w) and height (h). The only reasons to use this are to fill the screen or restore a window size from a previous run.

w.setLocation(x, y); Sets the upper left corner of the window to this screen pixel 32 coordinate.

Jframe(cont)
0 There is typically be a very short main method something

like this.

public static void main(String[] args { JFrame windo = new MyExample(); windo.setVisible(true); }

0 And a class which defines the window.


public class MyExample extends JFrame { //..Declare components, something to hold the model.. public MyExample() { // constructor builds GUI //... Build the content pane. Container content = this.getContentPane(); content.add(...) // Add components to the content . . . this.setTitle("My new window"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.pack(); // does layout of components. }//end constructor }
Chap-3 Adv Prog 33

Jframe(cont) Window Size and Position


0 First pack your window to do the layout : The optimum size of

a window depends on the size and layout of the components. After adding all the components to a window (JFrame), call pack() to perform the layout. 0 Centering a Window : The following code positions a window (JFrame) f in the center of the screen. Use this when you create a window, after calling pack() has been called, as follows.
setLocationRelativeTo(null);

// Implicit "this" if inside JFrame

constructor.

f.setLocationRelativeTo(null);

// Explicit JFrame if outside JFrame constructor.


Chap-3 Adv Prog 34

Jframe(cont) Window Size and Position


0 You can use the older, more explicit, way of centering a

window

Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); Dimension windowSize = window.getSize(); int windowX =Math.max(0,(screenSize.width-windowSize.width )/2); int windowY =Math.max(0,(screenSize.height-windowSize.height)/2);
f.setLocation(windowX, windowY);

// Don't use "f." inside

constructor. 0 The Math.max call makes sure the window origin is not negative.

Chap-3 Adv Prog

35

Jframe(cont) Window Size and Position


0 Expanding a window to fit the screen

The first example leaves a 40 pixel border around the window. The second example passes the Dimension object directly to setSize(). You don't need the explicit "f." if this code is in the constructor.
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); f.setSize(screenSize.width - 40, screenSize.height - 40); f.validate(); // Make sure layout is ok

0 Completely full screen.


f.setSize(Toolkit.getDefaultToolkit().getScreenSize()); f.validate(); // Make sure layout

is ok

Chap-3 Adv Prog

36

Jframe(cont) Window Size and Position


0 Fixed Window Size using setSize() and validate() -

Probably a mistake 0 You can set the size of a window, but it's almost always a mistake unless you're simply expanding the window to fill the screen. The default window size should depend on the size and layout of the components as determined by pack(). If you must create a fixed size window (JFrame), call setSize(width, height) or setSize(dimension), then call validate() to finalize the component layout before making the window visible.

Chap-3 Adv Prog

37

Jframe(cont) Content Panes


0 Before Java 2 each top-level container had only one layer. Java 2

top-level containers (JFrame, JApplet, ...) have several layers (panes): root, content, layered, and glass. Programs normally reference only the content pane. There are two programming idioms for using the content pane: (1) using the preassigned pane (recommended), or (2) building your own pane.

0 Naming convention 0 It is common to name the content pane content or contentPane.

Chap-3 Adv Prog

38

0 Idiom 1: Use the existing content pane

Jframe(cont) Content Panes

0 Each container has a pre constructed content pane of class

Container. You can get this pane and add the components to it. For example,

class MyWindow extends JFrame { . . . MyWindow() {


// constructor Container content = getContentPane(); // Use the default content pane. content.add(...); content.add(...); . . . }
Chap-3 Adv Prog

39

0 All JFrames already have a content pane, so there's no need to

Jframe(cont) Content Panes

create a new one, just get the existing pane. And if you're wondering about the Container type, it's a superclass of JPanel. In fact, if you look at the actual type of the object that's currently returned by getContentPane(), it really is a JPanel, although you can't count on this in the future, of course. 0 Sometimes programmers don't bother to copy the content pane reference into a new variable, resulting in code like this. Since there are typically a large number of references to the content pane, this seems awkward.
class MyWindow extends JFrame { . . . MyWindow() { // constructor getContentPane().add(...); getContentPane().add(...); . . .

Chap-3 Adv Prog

40

0 Idiom 2: Create your own content pane

Jframe(cont) Content Panes

It's common to create a new panel for the content pane and tell the window to use this new panel for it's content pane. For example,
class MyWindow extends JFrame { . . . MyWindow() { // constructor JPanel content = new JPanel(); // Create a new content pane. content.add(...); content.add(...); . . . setContentPane(content); } }

Chap-3 Adv Prog

41

0 Components are typically declared in one of several places: 0 Field variables : Some components should be declared as field

Where to declare components

variables (instance variables, member variables). This is the appropriate place to declare components which must be referenced after the interface is constructed. Typically these are text fields or text areas, check boxes, etc. Those components whose values must be gotten or set. 0 Local variables : Local variables should be used for components which are never referenced after the interface is constructed. Typically these are panels for holding components, buttons (whose interaction is thru their listeners), ... Local variables disappear when the method they are in returns, but the component will continue to exist if it has been added to the interface. 0 Anonymous : Anonymous creation is typical with labels, which can be created and added in one step and never assigned to a variable. Of course, if the appearance (font, alignment, ...) must be changed, then they should be put in a local variable. Some programs use labels for output (not a good idea), and in this case they should be field variables. Example content.add(new JLabel("Look at this"));
Chap-3 Adv Prog 42

Java: Text
If you work with text, you need to know about the following user interface text components. Component
JLabel JTextField

Lines

Style

Use

1 plain, HTML plain or For displaying a fixed line of text. Can be "page", and/or HTML HTML an icon 1 plain For entering or displaying one line of plain text. Added in SDK 1.4, JFormattedTextField is a subclass of JTextField for which the type of entry may be specified. For example, a field can be constructed to only accept integer values. For entering one line of plain text that displays a symbol instead of the characters, ie, for entering passwords. Subclass of JTextField. For entering or displaying multiple lines of plain text. Put it into a JScrollPane to add scrolling.

JFormattedTextField 1

plain

JPasswordField

plain

JTextArea

many

plain

JLabel
0 Labels display fixed text or images on a GUI as information to

the user, for example, as a label in front of a a JTextField, etc. You can have text (including HTML), an image, or both on a JLabel. A JLabel has a transparent background, so it will always match the container it is in. 0 JLabel Constructors Assume the following declarations. String text; Icon image; int alignment; // JLabel.LEFT, JLabel.Center, or JLabel.RIGHT.
JLabel JLabel JLabel JLabel JLabel yourLabel yourLabel yourLabel yourLabel yourLabel = = = = = new new new new new JLabel(text); JLabel(text, alignment); JLabel(image); JLabel(image, alignment); JLabel(text, image, alignment);

44

Jlabel(cont)
0 Java Idiom

Because there is usually no need to refer to a JLabel after it has been added to a container, it is common to combine creation and adding the JLabel in one statement. For example.
... p.add(new JLabel("Enter your ID:", JLabel.RIGHT)); is the same as JLabel idLabel = new JLabel("Enter ID:", JLabel.RIGHT); . . .

p.add(idLabel);

45

Jlabel(cont)
HTML in JLabels
0 You may put HTML text in a JLabel. In this case the text should

begin with <html> and end with </html>. 0 JLabel font and color The most user-friendly interfaces are usually obtained by using the default appearance (font, color, background), but there are cases where you want to change these. 0 Appearance: setting the font The font of a JLabel can be changed like this.
JLabel title = new JLabel(Enter Name :", JLabel.CENTER); title.setFont(new Font("Serif", Font.BOLD, 48));
46

Jlabel(cont)
0 Appearance: setting the text color

HTML in JLabels

Use the setForeground method to set the text color.


JLabel title = new JLabel(Name :", JLabel.CENTER); title.setForeground(Color.white);

0 Appearance: setting the background color

Because a JLabel's background is transparent, there is no effect from using the setBackground method. To make a new background, you need to create a JPanel with the appropriate color and put the label on that. For example
JLabel title = new JLabel(Enter your name"); title.setForeground(Color.white); JPanel titlePanel = new JPanel(); titlePanel.setBackground(Color.blue); titlePanel.add(title);

// adds to center of panel's default BorderLayout.

47

Jlabel(cont)
0 Why using JLabel for output is usually bad

JLabel for output

It's possible to change the text of a JLabel, although this is not generally a good idea after the user interface is already displayed. For output JTextField is often a better choice. The use of JLabel for output is mentioned because some textbooks display output this way. Here are some reasons not to use it. 0 Can't copy to clipboard. The user can not copy text from a JLabel, but can from a JTextField. 0 Can't set background. Changing the background of individual components probably isn't a good idea, so this restriction on JLabels is not serious. You can change the background of a JTextField, for better or worse. 0 Text length. This is where there are some serious issues. You can always see the entire text in a JTextField, altho you might have to scroll it it's long. There are several possibilities with a JLabel. You may either not see all of the long text in a JLabel, or putting long text into a JLabel may cause the layout to be recomputed, resulting in a truly weird user experience.
48

Jlabel(cont)
0 Changing the text of a JLabel

Most JLabels are never changed, except for internationalization, and that is done before the user interface is shown. To change the text, use yourLabel.setText(String newText);

49

JTextField
0 javax.swing.JTextField has two uses. Input. The user can enter one line of text (a String) Output. To display one line of text.

0 If you need a component that displays or allows entry of

more than one line, use a JTextArea. 0 Overview of methods JTextField

JTextField(width) setText(text)

String

getText()
addActionListener(listener) setEditable(true/false) setFont(font) setHorizontalAlignment(align)

Chap-3 Adv ProgrequestFocus(align)

50

JTextField(cont)
To use a JTextField for Input 1. Declare a JTextField as an instance variable. Reason: If it's an instance variable, it can be seen in all methods in the class. 2. Assign an initial value to this variable by calling the JTextField constructor. Specify the approximate field width in the constructor. Example:
JTextField yourInpuField = new JTextField(16);

3. Add the text field to a container. content.add(yourInputField);

or to add it to a JPanel p
p.add(yourInputField);

4. Input is done by calling the getText().


Get the string in the text field by calling yourTextField.getText() method whenever you need it. This is probably the most common way. String x = yourInputField.getText(); 2. Attach an action listener to the text field. It is called whenever the user types Enter in that field. The listener can then get the text and process it.
1.
Chap-3 Adv Prog 51

JTextField(cont)
To use a JTextField for Output 0 Using a JTextField for output is almost the same as for input, but . . . 1. Set the text field with yourTextField.setText(someString) 2. If it's only for output, call .setEditable(false) so the user can't change the field. 0 Here is the sequence. 1. Declare and initialize a JTextField as a field variable (instance variable). Example:
JTextField myOutput = new JTextField(16);

You can also set the initial value in the field


JTextField myOutput = new JTextField("someInitialValue", 20);

2. Add the text field to a container. For example, to add it to JPanel p.


p.add(myOutput);

3. Setting the value of the text field. Whenever you want put a string value in the text field, call myOutput.setText("Some text").
myOutput.setText("some text");
Chap-3 Adv Prog 52

JTextField(cont)
0 Constructors

JTextField tf = new JTextField(int columns); The number of columns is approximate because the width of text depends on the font and width of individual characters.

JTextField tf = new JTextField(String initial); This puts the initial String in the JTextField. The size of the JTextField is set from this String. JTextField tf = new JTextField(String initial, int columns); This creates a JTextField columns wide with value initial.

Chap-3 Adv Prog

53

JTextField(cont)

Common methods 0 Here are some of the most common methods use with text fields: Assume these declarations JTextField tf; ActionListener listener; String s, text; Font f; //--- When used for input. s = tf.getText(); // gets the text from the JTextField tf.addActionListener(listener);// Optional listener intialization. //--- When used for output. tf.setText(text); // Sets text in the JTextField. tf.setEditable(false); // Initialization to disallow user changes. //--- To change the appearance. tf.setHorizontalAlignment(align);//See below for possible values. tf.setFont(f); // sets the font for the text 54
Chap-3 Adv Prog

JTextField(cont)

Appearance of a JTextField - font, alignment 0 yourField.setFont(Font f); sets the font for the text. Often numbers are aligned to the right (eg, in the display of a calculator), and text is aligned to the left. 0 yourField.setHorizontalAlignment(align); sets the alignment of the text in the field, where align is one of these values: JTextField.LEFT (the default), JTextField.CENTER, or JTextField.RIGHT. 0 Example JTextField userID; // declare a field . . . userID = new JTextField(8); // create field approx 8 columns wide. p.add(userID); // add it to a JPanel userID.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { ... // THIS CODE IS EXECUTED WHEN RETURN IS TYPED } } 55 Chap-3 Adv Prog );

JTextField(cont)
Use JPasswordField for passwords 0 Use a JPasswordField component for a field where the characters the person enters are replaced by some other character. JPasswordField is a subclass of JTextField. Use JFormattedTextField to restrict input format 0 The JPasswordField subclass of JTextField can be used to restrict the input to particular values. Focus 0 To select a JTextField so that user typing occurs in that field, you must give the JTextField focus. For example, the nameField JTextField can be given focus with: nameField.requestFocus(); 56 Chap-3 Adv Prog

0 A javax.swing.JTextArea is a multi-line text component to display

JTextArea

text or allow the user to enter text. 0 Using a JTextArea for output -- Setting the text 0 Assume: JTextArea ta; int i, w, pos, start, end, line; String s; boolean b; Font f; Reader reader; Writer writer;
Result Constructors ta = ta = Method new JTextArea(rows, cols);

Description

Creates text area. cols is approx char width. new JTextArea(s, rows, cols); As above, but also containing initial Chap-3 Adv Prog 57 string s.

JTextArea(cont)
Result Setting text Method ta.setText(s); ta.append(s); Description Replaces all text with s. Appends s to the end.

ta.insert(s, pos); Getting text s = ta.getText();


i = ta.getLineCount();

Inserts s at position pos.

ta.replaceRange(s, start, end); Replace start to end with s.

Returns all text. Use methods below to get individual lines. Returns number of lines in the text area.

i = ta.getLineStartOffset(line); Returns character index of beginning of line line. May throw javax.swing.text.BadLocationException. i = ta.getLineEndOffset(line); Returns character index of end of line line. May throw javax.swing.text.BadLocationException. Chap-3 Adv Prog 58

JTextArea(cont)
Result Method Description Text is tight against edge. See example below to add space. Lines wrapped if true. Default false. If wrapping on (see above), wraps at words (true) or chars (false). Default false. Number of max width chars in a tab. Displays using Font f. Set false to disable user editing. Set caret position. If content is scrolled, setCaretPosition(0) will move to top. Changing the appearance/function ta.setBorder(brdr); ta.setLineWrap(b); ta.setWrapStyleWord(b); ta.setTabSize(w); ta.setFont(f); ta.setEditable(b); ta.setCaretPosition(i);

Reading and writing to/from a JTextArea ta.read(reader, null); Reads text from reader into text area. May throw IOException. ta.write(writer); Writes text from text area to writer. May throw IOException. Chap-3 Adv Prog 59

JTextArea(cont)
Scrolling 0 JTextArea doesn't support scrolling itself but you can easily add the JTextArea to a JScrollPane. JScrollPane creates scrollbars as needed. For example, //... Create scrolling text area.
resultTA = new JTextArea("This is a test", 10, 80); JScrollPane scrollingResult = new JScrollPane(resultTA); content.add(scrollingResult);

Chap-3 Adv Prog

60

JTextArea(cont)
Scrollbar policy 0 There are three policies that you can specify for the scrollbars. Below is how you set if for the horizontal scrollbar, but change "horizontal" to "vertical" as needed. 0 ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED - Default value. 0 ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER 0 ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS
Result Method
scrollPane.setVerticalScrollBarPolicy(policy);

Description
Where policy is described above.

scrollPane.setHorizontalScrollBarPolicy(policy); Where policy is described above.

0 It's Unncessary to have horizontal scrolling when wrapping is turned on.

Wrapping takes precedence over horizontal scrolling. Positioning the scrolling view to the top - moving the caret 0 If more lines are added than can be displayed and the scrollbars appear, the position that shows can be controlled with setCaretPosition(pos), where pos is a character position between 0 and the length of the text. To move to the top, use position 0. Chap-3 Adv Prog 61

JTextArea(cont)
Space between text and edge improves appearance 0 JTextArea leaves no space between the edge andtext that it holds. This can be fixed by adding an empty border to it.
outArea.setBorder(BorderFactory.createEmptyBorder(4,4,4,4));

0 Example: Common JTextArea+JScrollPane usage

Setting up a text area can be slightly tedious. Here is an example.


JTextArea outputTA = new JTextArea(12, 40); . . . outputTA.setLineWrap(true); outputTA.setWrapStyleWord(true); outputTA.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); JScrollPane scroller = new JScrollPane(outputTA); scroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_ SCROLLBAR_ALWAYS); . . . content.add(scroller, ...);
Chap-3 Adv Prog 62

JTextArea(cont)
0 Example: Getting and setting all lines sequentially 0 The following code shows how to sequentially get and set each line in a

JTextArea. Assume inputArea has the input and outputArea will receive the output. Of course, this is a ridiculous way to copy from one text area to another; it would be better to just write outputArea.setText(inputArea.getText());, but it wouldn't illustrate working with individual lines. JTextArea inputArea = new JTextArea(40, 20); JTextArea outputArea = new JTextArea(40, 20); ... outputArea.setText(""); // Empties the textarea String text = inputArea.getText(); int totalLines = inputArea.getLineCount(); for (int i=0; i < totalLines; i++) { int start = inputArea.getLineStartOffset(i); int end = inputArea.getLineEndOffset(i); String line = text.substring(start, end); outputArea.append(line + "\n"); }
Chap-3 Adv Prog 63

JTextArea(cont)
public class TextAreaDemoB extends JFrame { JTextArea _resultArea = new JTextArea(6, 20); public TextAreaDemoB() { //... Set textarea's initial text, scrolling, and border. _resultArea.setText("Enter more text to see scrollbars"); JScrollPane scrollingArea = new JScrollPane(_resultArea); //... Get the content pane, set layout, add to center JPanel content = new JPanel(); content.setLayout(new BorderLayout()); content.add(scrollingArea, BorderLayout.CENTER); //... Set window characteristics. this.setContentPane(content); this.setTitle("TextAreaDemo B"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.pack(); } //============================================================= public main public static void main(String[] args) { JFrame win = new TextAreaDemoB(); win.setVisible(true); Chap-3 Adv Prog 64 } }

Java: Buttons
There are many kinds of buttons, all derived from theAbstractButton class. Components JButton Description This is a standard button which can have text, icon, or both. Listener: addActionListener(...)

JCheckBox JRadioButton, ButtonGroup

The box next to the text can be toggled on or off. Radio buttons are a group of buttons that can have at most one button toggled on. When you click one button, that button is toggled on, and all others are set to off.
Menu items are a kind of button. Changes between two states: on and off. Stays on/off until the next click.
Chap-3 Adv Prog 65

JMenuItem JToggleButton

0 There are a few steps in using a button: declaring it, creating it,

JButton

adding it to a container (the content pane or a JPanel), and adding a listener that has code to execute when the user clicks on the button. Images can be used on buttons, including automatic rollover effects. 0 Constructors 0 Assume these declarations. String text; Icon image; JButton btn = new JButton(text); JButton btn = new JButton(text, image); JButton btn = new JButton(image); Common methods 0 Assume these declarations: JButton btn; ActionListener listener; boolean b; //--- Buttons always have action listeners. btn.addActionListener(listener); btn.setEnabled(b); Chap-3 Adv Prog 66

for all of the button's listeners. It is passed an ActionEvent, which is generally ignored, but can be used to identify which component generated the event if several share the same listener. The example below shows the creation of a button, attaching a listener, and adding the button to a container. 0 Example 0 Typically a button is assigned to a local variable (not an instance variable) and an anonymous action listener is added to it. The listener often calls another method to do everything because separating the code to build the user interface and do the "semantics" makes a program clearer and easier to modify.
JButton mybtn = new JButton("Do Something"); mybtn.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { doMyAction(); // code to execute when button is pressed } } ); . . . content.add(mybtn); // add the button to a JPanel (eg, content).

Jbutton(cont) Events : When a button is clicked, the actionPerformed() method is called

67

Jbutton(cont)
JButton Appearance
0 Dynamically changing a button 0 You can change the text or icon (image) that appears on a

button with: btn.setText("someText"); btn.setIcon(anIcon);

0 WARNING: If you change the size of the button by one of these

changes, this may have consequences in the layout of the components. This may require a call to validate() or revalidate() which then computes a new layout based on the change in the button size. This is not a quick operation. Replacing an icon with another of the same size should not cause any problems.

68

Jbutton(cont)
Buttons with Icons
0 You can create buttons that show text, icons (images), or both.

Different images can be associated with different button states and user interactions with the button (disabled, rollover, ...). The two supported image formats are GIF and JPEG, although support for more image types is being worked on.

0 To create a button with an icon


JButton next = new JButton(new ImageIcon("right.gif")); or JButton next = new JButton("Next", rightArrow);

69

Jbutton(cont)
Methods to change the icon on a JButton 0 It is common to show different icons when the button is disabled, the mouse is over it (rollover), etc. Java recognizes seven (7) different states for a button, and you can set a different image for each state. 0 Java computes two button images automatically: the disabled image is computed from the normal image, and the selected, disabled image is computed from the selected image if one is supplied. 0 Rollover image changes are not automatic -- first you must call b.setRolloverEnabled(true);. JButton b = new JButton(Icon x); // Create button with normal icon
b.setIcon(Icon x); b.setDisabledIcon(Icon x); b.setPressedIcon(Icon x); b.setSelectedIcon(Icon x); b.setDisabledSelectedIcon(Icon x);

Buttons with Icons

b.setRolloverEnabled(boolean b); // turn on before rollovers work b.setRolloverIcon(Icon x); 70 b.setRolloverSelectedIcon(Icon x);

Making Choices 0 There are several ways to select one of many fixed choices: radio buttons, a menu, a list, or a (uneditable) combo box. A combo box (JComboBox) is a popup menu and is often the best component to use because it uses less space than radio buttons or a list, and it shows as part of a "form" so the user realizes it's there, unlike a menu. You can also use an editable combo box, and in this case the user can either choose from the pop-up menu or type in a value. Constructor 0 An easy way to build a combo box is to initialize an array (or Vector, but not yet the new Collections types) of strings and pass it to the constructor. Objects other than strings can be used, but this is the most common. The list also be built by successive calls to the add method.
String[] dias = {"lunes", "martes", "miercoles"}; JComboBox dayChoice = new JComboBox(dias);
Chap-3 Adv Prog 71

JComboBox (uneditable)

JComboBox (uneditable)
Common methods
0 In these prototypes, assume the following. int index;

String item; String obj; // obj can be any object type, but is commonly String JComboBox cb = new JComboBox(. . .); Result Call
cb.addActionListener(...); Modifying a JComboBox cb.setSelectedIndex(index); cb.setSelectedItem(obj); cb.add(item); Set default, visible, choice. Set default, visible, choice. Add additional item to the list

Description
Add listener -- same as for button.

cb.insert(item, index);
cb.remove(item); cb.remove(index); Testing a JComboBox index = cb.getSelectedIndex();

Add additional item after index.


Remove item from the list Remove item as position index Return index of selected item.

obj = cb.getSelectedItem();

selected item. Chap-3Return Adv Prog

72

Events 0 A JComboBox generates both ActionEvents (like buttons, text fields, etc), or ItemEvents. Because it is easier to work with ActionEvents, we'll ignore the ItemEvents. When the user chooses an item from a combo box, an ActionEvent is generated, and the listener's actionPerformed method is called. Use either getSelectedIndex to get the integer index of the item that was selected, or getSelectedItem to get the value (eg, a String) that was selected.
0 Example 0 This example creates a JComboBox, and adds a listener to it. The getSelectedItem

JComboBox (uneditable)

method returns an Object type, so it's necessary to downcast it back to a

String.String[] fnt = {"Serif", "SansSerif", "Monospaced"}; JComboBox fontChoice = new JComboBox(fnt); fontChoice.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { JComboBox combo = (JComboBox)e.getSource(); currentFont = (String)combo.getSelectedItem(); } } );
Chap-3 Adv Prog

73

JCheckBox
0 A javax.swing.JCheckBox shows a small box that is either

marked or unmarked. When you click on it, it changes from checked to unchecked or vice versa automatically. You don't have to do any programming for the checkbox to change. 0 There are two ways to use a checkbox: 1. Active. Use addActionListeneror addItemListener() so that a method will be called whenever the checkbox is changed. 2. Passive. Use isSelected() to test if a checkbox is checked.

Chap-3 Adv Prog

74

0 Common constructors and methods 0 Assume

JCheckBox(cont)

JCheckBox cb; // A checkbox. String text; // Label on text box. boolean state; // True/false state of checkbox.
Constructors cb =new JCheckBox(text); Methods state =cb.isSelected(); cb.setSelected(state); cb.addActionListener(actionlistener); cb.addItemListener(itemlistener); Creates check box, initially unchecked.

cb =new JCheckBox(text, state); Creates check box, checked or not depending on state.
Returns true if the check box is checked. Checks (true) or unchecks check box. Adds an action listener to the radio button. The action listener will be called if button is selected. Add an item listener to a radio button. The item listener will be called if the button is selected or Chap-3 Adv Prog 75 deselected.

0 Example using an ActionListener 0 An ActionListener should probably be preferred to an ItemListener, and this needs

JCheckBox

to have a little more explanation. 0 Example with anonymous inner class ItemListener 0 This example creates a checkbox (ignoreCase) that is already checked, and adds it to the JPanel (content). It sets the boolean variable (ignore) whenever the box state is changed by the user. boolean ignore = true; // true if should ignore case . . . JCheckBox ignoreCase = new JCheckBox("Ignore Case", true); ignoreCase.addItemListener( new ItemListener() { public void itemStateChanged(ItemEvent e) { // Set "ignore" whenever box is checked or unchecked. ignore = (e.getStateChange() == ItemEvent.SELECTED); } } ); content.add(ignoreCase);
76

0 Example checking state

JCheckBox

0 This example is similar to the above, but gets the state of the

checkbox when the value is needed.

JCheckBox ignoreCase; . . . //... inside window constructor JCheckBox ignoreCase = new JCheckBox("Ignore Case", true); content.add(ignoreCase); . . . //... Inside processing method, eg in button listener. if (ignoreCase.isSelected()) { . . .

77

Radio Buttons(cont)
0 Radio buttons (javax.swing.JRadioButton) are used in groups

(java.awt.ButtonGroup) where at most one can be selected. The example below produced this image. A radio button group starts with all buttons deselected, but after one is selected the only way to have them appear all off is to have an invisible button that is selected by the program.

Chap-3 Adv Prog

78

0 Source code for above example 0 This example creates a group of three radio buttons, puts them in a

Radio Buttons(cont)

grid layout on a panel, and puts a titled, etched border around them.

JRadioButton yesButton = new JRadioButton("Yes" , true); JRadioButton noButton = new JRadioButton("No" , false); JRadioButton maybeButton = new JRadioButton("Maybe", false); ButtonGroup bgroup = new ButtonGroup(); bgroup.add(yesButton); bgroup.add(noButton); bgroup.add(maybeButton);
JPanel radioPanel = new JPanel(); radioPanel.setLayout(new GridLayout(3, 1)); radioPanel.add(yesButton); radioPanel.add(noButton); radioPanel.add(maybeButton); radioPanel.setBorder(BorderFactory.createTitledBorder( BorderFactory.createEtchedBorder(), "Married?"));

Radio Buttons(cont)
Testing the status of radio buttons 0 There are several ways to find out about radio button states:
During execution, test the radio button with isSelected().
In the setup phase, add an action listener with

addActionListener(...). ActionListeners are called when a radio button is selected. In the setup phase, add an item listener with addItemListener. ItemListeners are called both when the radio button is selected and (automatically) deselected.

Chap-3 Adv Prog

80

Radio Buttons(cont)
0 JRadioButton methods

boolean b; JRadioButton rb = new JRadioButton("Sample", false); 0 Common JRadioButton methods


b =rb.isSelected(); Returns true if that button is selected. rb.setSelected(b); Sets selected status of a radio button to b (true/false). rb.addActionListener(an-action-listener); Adds an action listener to the radio button. The action listener will be called if button is selected. rb.addItemListener(an-item-listener); Add an item listener to a radio button. The item listener will be called if the button is selected or deselected.
Chap-3 Adv Prog 81

Radio Buttons(cont)
0 ButtonGroup methods 0 The most common method used for a button group is add(), but

it's also possible to get or set the selected button. Assume:

JRadioButton rb = new JRadioButton("Sample", false); ButtonGroup bgroup = new ButtonGroup();

0 Common ButtonGroup methods


bgroup.add(rb); rb =bgroup.getSelectedJRadioButton(); bgroup.setSelectedJRadioButton(rb); bgroup.add(rb); Adds a button to a radio button group. Returns the radio button which is currently selected. Sets the status of a particular radio button (unsetting others). Adds a button to a radio button group.
82

Chap-3 Adv Prog

0 A slider (JSlider class) lets the user easily select from a range of

Sliders

integer values. Use sliders for integer input whenever you can. They are easier for the user than text fields, and there is no possibility of illegal input values, so your programming is simpler.Constructors 0 The usual constructor is JSlider s = new JSlider(orientation, min, max, initial);orientation: JSlider.HORIZONTAL or JSlider.VERTICAL min: The minimum value. max: The maximum value. initial: The initial value. 0 Example:JSlider sl = new JSlider(JSlider.HORIZONTAL, 0, 20, 10);
Chap-3 Adv Prog 83

Sliders(cont)
Tick Marks 0 You can add both major and minor tick marks. You must call setPaintTicks(true) to make the tick marks appear. 0 Here is an example that sets major tick marks every 10 values and minor tick marks every 1 value: sl.setMajorTickSpacing(10); // sets numbers for biggest tick marks sl.setMinorTickSpacing(1); // smaller tick marks sl.setPaintTicks(true); // display the ticksLabels 0 To display the values next to the major tick marks: sl.setPaintLabels(true);

Chap-3 Adv Prog

84

Sliders(cont)
Listeners and getting the slider value 0 We will see how to do something when the slider is changed in the next lessons. Advanced Appearance 0 In addition to tick marks, you can specify text or icon labels at any values that you specify using setLabelTable(...). You can also specify which end of the slider should have the high or low values using setInverted(true/false).

Chap-3 Adv Prog

85

Menus
Types of menus 0 A menu is a way to arrange buttons. There are several types.
0 Traditional dropdown menus are positioned across the top of a

window in a menu bar, and display below the menu name. 0 Popup menus appear when the user clicks, eg with the right mouse button, on a component that can handle a popup request.

Menus and Menu Items are Buttons! 0 It is easy to see how menu items are buttons that appear when a menu appears. But the menu names in the menu bar are also buttons. When you press on these "buttons", they create a popup menu that you see as a dropdown menu.
Chap-3 Adv Prog 86

Menus(cont)
Dropdown menus: JMenuBar, JMenu, and JMenuItem 0 A menu bar can be added to the top of a top-level container, eg, JFrame, JApplet, or JDialog. Note that a menu bar can not be added to JPanel. 0 Dropdown menus have three parts: 1. JMenuBar is positioned across the top of a container (eg a JFrame, JPanel, or JApplet). It's placed above the content pane, so does not use the container's layout. Add menus to the menubar. 2. JMenu has a name and contains a number of menu items which are displayed is a vertical list of menu items. 3. JMenuItems and Separators are added to each menu. Menu items are usually text "buttons", but can also have icons, checkboxes, radio buttons, or be hierarchical submenus.
Chap-3 Adv Prog 87

Menus(cont)
Dropdown menus: JMenuBar, JMenu, and JMenuItem 0 A menu bar can be added to the top of a top-level container, eg, JFrame, JApplet, or JDialog. Note that a menu bar can not be added to JPanel. 0 Dropdown menus have three parts: 1. JMenuBar is positioned across the top of a container (eg a JFrame, JPanel, or JApplet). It's placed above the content pane, so does not use the container's layout. Add menus to the menubar. 2. JMenu has a name and contains a number of menu items which are displayed is a vertical list of menu items. 3. JMenuItems and Separators are added to each menu. Menu items are usually text "buttons", but can also have icons, checkboxes, radio buttons, or be hierarchical submenus.
Chap-3 Adv Prog 88

Menus(cont)
Keyboard Mnemonics and Accelerators 0 You can associated characters with menus and menu items so that the user can invoke them from the keyboard: 0 Menu mnemonics can be used to open a menu by typing a single character associated with a menu along with an operating system defined key for this action. For example, on MS Windows, The ALT key with F will typically open the File menu. You can then select the relevant menu item with either the mnemonic key for that item, or with the arrow keys and Enter. The corresponding letter (char) in the menu will be underlined. For example fileMenu.setMnemonic('F');
Chap-3 Adv Prog 89

Menus(cont)
0 Menu item mnemonics are used to select a menu item when its

menu is already open. Typically the character corresponds to the first, or a significant, letter in the menu item name. That letter in the menu item will be underlined. openItem.setMnemonic('O'); 0 Accelerator key combinations are used to directly invoke a menu item without opening the menu, for example the common CTRL-C (Copy) execute the copy menu action. Accelerator key options are displayed to the right of the menu item name. Adding accelerator key requires using KeyStroke codes. There are several ways to get these codes, but the model below shows one of the easiest. openItem.setAccelerator(KeyStroke.getKeyStroke("control O"));
Chap-3 Adv Prog 90

Jframe frame = new Jframe(); frame.setTitle(Menu Sample"); frame.setBounds(100, 100, 500, 500); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //menu items, then munu and finaly menubar //menu itemes JMenuItem mi1 = new JMenuItem("item 1..."); mi1.setMnemonic('I'); mi1.setAccelerator(KeyStroke.getKeyStroke("control I")); JMenuItem mi2 = new JMenuItem("item 2"); mi2.setMnemonic('T'); mi2.setAccelerator(KeyStroke.getKeyStroke("alt T")); JMenuItem mi3 = new JMenuItem("item 3"); mi3.setAccelerator(KeyStroke.getKeyStroke("control 3")); JMenuItem mi4 = new JMenuItem("item 4"); mi4.setAccelerator(KeyStroke.getKeyStroke("alt 4"));

Menus(cont)

91

//menu JMenu m1 = new JMenu("Menu 1"); m1.add(mi1); m1.add(mi2); JMenu m2 = new JMenu("Menu 2"); m2.add(mi3); m2.add(mi4); //menubar JMenuBar mbar = new JMenuBar(); mbar.add(m1); mbar.add(m2); frame.setJMenuBar(mbar); frame.setLocationRelativeTo(null); frame.setVisible(true);

Menus(cont)

92

Dialogs
0 There are several ways to build dialog boxes: 0 JOptionPane - Simple Dialogs This is a very easy way (one

statement) to build simple dialogs. Usually this, JFileChooser, and maybe JColorChooser are the only dialog classes that you need. 0 JFileChooser This will create and control a standard file chooser dialog.
javax.swing.JColorChooser You can call one static method

(Color.showDialog(. . .)) to display a dialog that lets the user choose a color, or you can add listeners to make a more complicated dialog interaction, or you can use this class to create a color chooser pane. javax.swing.Jdialog This can be used for building dialogs that are too complicated for JOptionPane.
Chap-3 Adv Prog 93

Dialogs(cont)
Dialogs are attached to window (frame) 0 Every dialog is attached to a window (frame). When the window in iconified, the dialog will automatically disappear, and it will automatically reappear when the window is deiconified. When the window is destroyed, the dialog will disappear.

Dialogs are usually modal 0 When a dialog in active, input to other parts of the graphical user interface will be blocked. This kind of dialog is called a modal dialog. If you want a dialog which is modeless (allows interaction with other windows), you must use the JDialog class.

Chap-3 Adv Prog

94

0 Here are two useful static methods from

JOptionPane

javax.swing.JOptionPane that allow you to easily create dialog boxes for input and output. The Java API documentation has many more JOptionPane options, but these are sufficient for many uses. In the code below userInput and text are Strings.
Value Method call userInput = JOptionPane.showInputDialog(component, text);

JOptionPane.showMessageDialog(component, text);

Use null for the component parameter if you don't have a window 0 The dialog box will be centered over the component given in the first parameter. Typically you would give the window over which it should be centered. If your program doesn't have a window, you may simply write null, in which case the dialog box 95 will be centered on the screen.

JOptionPane(cont)
JOptionPane.showMessageDialog(null, "Hello guys!");

Chap-3 Adv Prog

96

0 This program produces the dialog boxes below.

JOptionPane(eg 1)

import javax.swing.JOptionPane; public class JOptionPaneTest1 { public static void main(String[] args) { String ans; ans = JOptionPane.showInputDialog(null, "Speed in miles/ hour?"); double mph = Double.parseDouble(ans); double kph = 1.621 * mph; JOptionPane.showMessageDialog(null, "KPH = " + kph); System.exit(0); } }
97

JOptionPane(eg 1)
This line displays a String, an input text field (JTextField), and OK and CANCEL buttons. If the user presses the OK button, the string in the text field is returned. If the user didn't type anything, the string "" is returned. If the user presses the CANCEL button, null is returned. Because this call returns a String, it's necessary in the next line to convert it into a double to do the arithmetic calculation.

This line displays a String and an OK button. In this call the String formed by concatenating a String literal with a number. When a String is concatenated with anything, that other operand is converted to a String by Java, then the two are put together into a new String.
98

0 This program produces the dialog boxes below.

JOptionPane(eg 2)

import javax.swing.JOptionPane; public class JOptionPaneTest1 { public static void main(String[] args) { String[] choices = {"Democratic", "Republican", "None of your business", "Quit"}; int response = JOptionPane.showOptionDialog( null // Center in window. , "How did you vote?" // Message , "Party Poll" // Title in titlebar , JOptionPane.YES_NO_OPTION // Option type , JOptionPane.PLAIN_MESSAGE // messageType , null // Icon (none) , choices // Button text as above. , "None of your business" // Default button's label ); System.exit(0); } 99 }

JDialog (cont)
JFrame frame = new JFrame(); Object[] options = {"Yes!", "No!", "Cancel"}; int n = JOptionPane.showOptionDialog( frame, "Here goes the description", "This is the title ", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, //do not use a custom Icon options, //the titles of buttons options[2] //default button title );

Example

Chap-3 Adv Prog

100

JDialog (cont)
Example
Icon description question information warning error Java look and feel Windows look and feel

Chap-3 Adv Prog

101

0 Use javax.swing.JFileChooser to create a file chooser for

JFileChooser

selecting a file or directory to open or save. To display a file chooser 0 Use one of three methods to display the dialog after it has been created. r = fc.showOpenDialog(owner); // button labeled "Open" r = fc.showSaveDialog(owner); // button labeled "Save" r = fc.showDialog(owner, title); 0 The owner parameter is the component (eg, JFrame, JPanel, ...) over which the dialog should be centered. You can use null for the owner, which will put the dialog in the center of the screen. The title parameter is a string that is used as the dialog's title and accept button text.
102

JFileChooser(cont)
Checking the return value 0 The user may either select a file or directory, or click CANCEL or close the file chooser window. If the user selected a file or directory, the value returned will be JFileChooser.APPROVE_OPTION. Always check this value. 0 For example, JFileChooser fc = new JFileChooser(); int retval = fc.showOpenDialog(null); if (retval == JFileChooser.APPROVE_OPTION) { ... // The user did select a file.;
103

JFileChooser(cont)
Getting the selected file or directory 0 After checking for JFileChooser.APPROVE_OPTION, the File value of the selection is returned from a call on getSelectedFile. int retval = fc.showOpenDialog(null); if (retval == JFileChooser.APPROVE_OPTION) { File myFile = fc.getSelectedFile(); // DO YOUR PROCESSING HERE. OPEN FILE OR ... }

104

Files, directories, or both 0 By default a file chooser allows the user to select only files. To allow selection of either files or directories, or only directories, use one of the following calls. fc.setFileSelectionMode(JFileChooser.FILES_ONLY); // default fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);

JFileChooser(cont)

Filtering files 0 You can specify the kinds of files that should be shown (eg, with a specific extension, ...), by supplying a JFileFilter. myChooser.setFileFilter(FileFilter filter); Eg to select only picture files JFileChooser myChooser = new JFileChooser(); FileNameExtensionFilter filter = new FileNameExtensionFilter(".txt and .java files", "txt", "java"); myChooser.setFileFilter(filter);

JFileChooser(cont)

Filtering files(cont) Eg to select only picture files JFileChooser myChooser = new JFileChooser(); String[] okFileExt = {"jpg", "png", "gif"}; @Override public boolean accept(File file) { for(String extension : okFileExt){ if(file.getName().toLowerCase().endsWith(extension)){ return true; } return false; } return false; } };

JFileChooser(cont)

JFileChooser(cont)
Specify a start directory in the constructor 0 The file chooser will start the file dialog at some default directory, for example, "C:\My Documents". To start the dialog at a different directory (called the current directory), specify the directory path as a String or File value in the JFileChooser constructor. JFileChooser m_fileChooser = new JFileChooser("C:\home"); The current directory is ".".
0 Portability warning: If you put system specific file paths in your code, the

program will not be portable to other systems. Note that the above call is therefore not portable.

0 Description.

JTabbedPane

The JTabbedPane container allows many panels to occupy the same area of the interface, and the user may select which to show by clicking on a tab. A tab may also be selected by the program. 0 Constructor JTabbedPane tp = new JTabbedPane(); // Defaults to tabs along the top edge. JTabbedPane tp = new JTabbedPane(edge); Where edge specifies which edge the tabs are on JTabbedPane.TOP (default) JTabbedPane.RIGHT JTabbedPane.BOTTOM JTabbedPane.LEFT

Adding tabs to the JTabbedPane 0 Add tabs to a tabbed pane by calling addTab and passing it a String title and a component (eg a JPanel) to display in that tab. For example, JTabbedPane display = new JTabbedPane(); display.addTab("Diagram View", diagramPanel); display.addTab("SQL View" , sqlPanel); display.addTab("Instructions", instructionPanel); Selecting the tab to display 0 A tab can be selected by the program using setSelectedIndex(). display.setSelectedIndex(1); // Display SQL View tab Listening for a tab change 0 When the user selects a tab, a ChangeEvent is fired. Add a ChangeListener to receive notification of the tab change. ______.addChangeListener(ChangeListener cl);

JTabbedPane (cont)

JFrame f = new JFrame(); f.setTitle("Tab demo"); f.setSize(500,100); JPanel p = new JPanel(); p.setLayout(new FlowLayout()); JPanel diagramPanel = new JPanel(); JPanel sqlPanel = new JPanel(); JPanel instructionPanel = new JPanel(); JTabbedPane display = new JTabbedPane(); display.addTab("Diagram View", diagramPanel); display.addTab("SQL View" , sqlPanel); display.addTab("Instructions", instructionPanel); display.setSelectedIndex(1); f.add(display); f.setVisible(true);

JTabbedPane (cont)

Anatomy of an Application GUI


GUI Internal structure

JFrame
JPanel containers

JFrame

JPanel
JButton

JButton
JLabel

JLabel

Chap-3 Adv Prog

112

Using a GUI Component 2


1. 2. 3. 4. 5.

Create it Configure it Add children (if container) Add to parent (if not JFrame) Listen to it

order important

Chap-3 Adv Prog

113

Build from bottom up


Listener

0 Create:
0 Frame

0 Panel
0 Components 0 Listeners

JLabel

JButton

0 Add: (bottom up)


0 listeners into components 0 components into panel 0 panel into frame

JPanel

JFrame
Chap-3 Adv Prog 114

What Is Layout?
0 A layout is a set of rules that defines how graphical components

should be positioned in a container. 0 Layouts tell Java where to put components in containers (JPanel, content pane, etc). Every panel (and other container) has a default layout, but it's better to set the layout explicitly for clarity. 0 Create a new layout object (using one of its constructors) and use the container's setLayout method to set the layout. Each layout has its own way to resize components to fit the layout, and you must become familiar with these.

115

What Is Layout?(cont)
0 There two ways to position a component is a container: 1. Using a predefined layout and allowing the layout to decide

where to position the component. This is a soft way of positioning a component. If the container changes its size, the component's position will be adjusted. But you may not able to get precisely where you want to component to be. 2. Specifying the position of the component using the container's coordinates. This is a hard way of positioning a component. You can get precisely where you want the component to be. But if the container changes its size, the component's position will not be adjusted.

Chap-3 Adv Prog

116

AWT offers a number of predefined layouts for you to use: 0 java.awt.BorderLayout - Divides the container into five regions: east, south, west, north, and center and assigns one component for each region. 0 java.awt.FlowLayout - Takes unlimited number of components and let them flow naturally horizontally first, then vertically. 0 java.awt.BoxLayout - Takes unlimited number of components and let them flow horizontally or vertically in one direction. 0 java.awt.GridLayout - Divides the container into rows and columns and assigns one component for each cell. 0 java.awt.GridBagLayout - Divides the container into rows and columns and assigns one component for each cell with cell sizes not equal.
Chap-3 Adv Prog 117

What Is Layout?(cont)

BorderLayout
0 It is a very simple layout that: 0 Divides the container into five regions: east, south, west, north,

and center. 0 Takes maximum 5 components only, one per region. 0 Resizes each component to match the size of its region. 0 Acts as the default layout in a container. 0 Resizes each region when the container is resized.
North West Center
Chap-3 Adv Prog

East
118

South

BorderLayout(cont)
0 Expand to fill region. Components start at their preferred size, but are 0

expanded as needed to fill the region they are in. Use subpanel for more than one component in a region. You can add at most one component to each region of a BorderLayout. To put more than one component in a section, put them in a JPanel (with its own layout), then add that panel to the border layout. Where extra space goes? The size of a region is adjusted depending on what is in it. If there is nothing in an region, its size will be reduced to zero. Components in the North and South cells are stretched horizontally, and those in East and West are stretched vertically to fill all the space. The center is stretched vertically and horizontally as needed, so it is a good place to put graphics or text areas that you want to expand. Specifying the region. When you add components to a container which uses BorderLayout, specify the target region as the second parameter as, for example, BorderLayout.NORTH. Not all regions are required If nothing has been added to a region, the neighboring regions expand to fill that space. 119
Chap-3 Adv Prog

Constructors 0 If you don't need any space between regions, use the default constructor. You can also specify the number of pixels between regions. p.setLayout(new BorderLayout()); // Default is no gaps p.setLayout(new BorderLayout(hgap, vgap); Where hgap and vgap are the distances in pixels between the regions.

BorderLayout(cont)

Chap-3 Adv Prog

120

public static void main(String[] a) { JFrame myFrame = new JFrame("FlowLayout Test"); myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Container myPane = myFrame.getContentPane(); myPane.setLayout(new BorderLayout()); myPane.add(new JButton("North"), BorderLayout.NORTH); myPane.add(new JButton("South"), BorderLayout.SOUTH); myPane.add(new JButton("East"), BorderLayout.EAST); myPane.add(new JButton("West"), BorderLayout.WEST); myPane.add(new JButton(new ImageIcon("java.gif")), BorderLayout.CENTER); myFrame.pack(); myFrame.setVisible(true); }

BorderLayout(cont)

Chap-3 Adv Prog

121

FlowLayout is a very simple layout that: 0 Takes unlimited number of components. 0 Uses the default size of each component. 0 Positions each component next to each other in a row. If there is not enough room in the current row, the component will be positioned at the beginning of the next row. 0 Re-arranges the flow when the container is resized. 0 Lets see how flowlayout and othe layouts re-arranges the flow when the container is resized. We wanted the window to look like this:
- Details ----------- -----------------| Name: Text | | System: Radio button | | Language: Check box | | Year: Dropdown | -------------------------- --------OK Cancel
Chap-3 Adv Prog 122

FlowLayout

Constructors 0 Typically the constructor is called in the call to the container's setLayout method (see example code). The parameterless FlowLayout() constructor is probably most common, but there are some good places to use the alignment. new FlowLayout() // default is centered with 5 pixel gaps new FlowLayout(int align) new FlowLayout(int align, int hgap, int vgap) Alignment 0 align is one of FlowLayout.LEFT, FlowLayout.CENTER (the default), or FlowLayout.RIGHT. You might want to use the RIGHT aligment when building a dialog that puts the OK and Cancel buttons at the lower right. Spacing 0 The default spacing is good for most purposes and is rarely changed. hgap is the size in pixels of the horizontal gap (distance) between components, and vgap is the vertical gap.
Chap-3 Adv Prog 123

FlowLayout(cont)

Typical uses 0 Quick implementation. This is the most common use of FlowLayout. You can get something working quickly, and change it, if necessary, in a later iteration. 0 Space around component in a BorderLayout. As a subpanel to keep components from expanding. For example, you might want to add a button to the SOUTH part of a BorderLayout, but don't want it to expand to the edges of the SOUTH region. Just put the button in a FlowLayout JPanel and add that to the SOUTH. 0 Multiple components in a BorderLayout region. When you want to add several components to a BorderLayout region, drop them into a FlowLayout panel and put that in the BorderLayout. Problem 0 FlowLayout makes components as small as possible, and does not use their preferred size. This can show up when you define a JPanel for drawing. Typically you will set a preferred size, but the panel may "disappear" in a FlowLayout because it was set to its minimum size (0). 124
Chap-3 Adv Prog

FlowLayout(cont)

JPanel content = new JPanel(); content.setLayout(new FlowLayout()); content.add(new JButton("Button 1")); content.add(new JButton("2")); content.add(new JButton("This is button three")); content.add(new JButton("four"));

FlowLayout(cont)

0 The window to the left is the default size after packing the FlowLayout. The window on the right shows the same window after it has been resized by dragging the lowerright corner, resulting in components flowing down onto other lines.

Chap-3 Adv Prog

125

import java.awt.*; Lets do our exercise - Details ----------- -------------import javax.swing.*; | Name: Text | | System: Radio button | public class FlowLayoutTest { | Language: Check box | | Year: Dropdown | public static void main(String[] a) { -------------------------- --------OK Cancel JFrame myFrame = new JFrame("FlowLayout Test"); myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Container myPane = myFrame.getContentPane(); myPane.setLayout(new FlowLayout(FlowLayout.CENTER)); //flowlayout myPane.add(getFieldPanel()); // calling getFieldPanel & add it to myPane myPane.add(getButtonPanel()); // calling getButtonPanel & add it to myPane myFrame.pack(); myFrame.setVisible(true); }

FlowLayout(cont)

Cont.
Chap-3 Adv Prog 126

private static JPanel getFieldPanel() { JPanel p = new JPanel(new FlowLayout()); p.setBorder(BorderFactory.createTitledBorder("Details")); p.add(new JLabel("Name:")); p.add(new JTextField(16)); p.add(new JLabel("System:")); p.add(getSystemPanel()); //calling the panel which has the radiobuttons p.add(new JLabel("Language:")); p.add(getLanguagePanel()); //calling the panel which has the checkboxes p.add(new JLabel("Year:")); p.add(new JComboBox(new String[] {"2001","2002","2003"})); return p; } Cont.
Chap-3 Adv Prog 127

FlowLayout(cont)

private static JPanel getButtonPanel() { JPanel p = new JPanel(new FlowLayout()); p.add(new JButton("OK")); p.add(new JButton("Cancel")); return p; } private static JPanel getLanguagePanel() { JPanel p = new JPanel(new FlowLayout()); p.add(new JCheckBox("Java",true)); p.add(new JCheckBox("C++",true)); p.add(new JCheckBox("Perl",false)); return p; } Cont.
Chap-3 Adv Prog

FlowLayout(cont)

128

private static JPanel getSystemPanel() { JRadioButton unixButton = new JRadioButton("Unix",true); JRadioButton winButton = new JRadioButton("Window",false); ButtonGroup systemGroup = new ButtonGroup(); systemGroup.add(unixButton); systemGroup.add(winButton); JPanel p = new JPanel(new FlowLayout()); p.add(unixButton); p.add(winButton); return p; } }//end of the class

FlowLayout(cont)

Chap-3 Adv Prog

129

0 Initially all components are positioned in a single row. If you

FlowLayout(cont)

narrow the window, "OK" and "Cancel" buttons will be wrapped to the next row. If you narrow it further, no change will happen on positions. Because the top container, the window, really contains only two components: the field panel and the button panel. 0 So, FlowLayout is not good for our example.

Chap-3 Adv Prog

130

BoxLayout
0 BoxLayout is a layout that:

0 Takes unlimited number of components.


0 Positions each component next to each other only in one

direction, horizontal or vertical. 0 Resizes components that are resizable to fill entire container. 0 Resizes components that are resizable when the container is resized.

Chap-3 Adv Prog

131

0 BoxLayout arranges components either horizontally or vertically in a

BoxLayout(cont)

panel. You can control alignment and spacing of the components. Complicated layouts can be made by combining many panels, some with horizontal layout and some with vertical layouts.

To Create a JPanel with BoxLayout 0 Choose either a horizontal layout (BoxLayout.X_AXIS) or vertical layout (BoxLayout.Y_AXIS) for a JPanel. JPanel p = new JPanel(); p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS)); p.add(some_component); 0 Unlike other layouts, the panel/container must be passed to the BoxLayout constructor.

Chap-3 Adv Prog

132

Example content.setLayout(new BoxLayout(content, BoxLayout.X_AXIS)); content.add(new JButton("Button 1")); content.add(new JButton("2")); content.add(new JButton("This is button three")); 0 The output is like this X_AXIS(Horizontal)

BoxLayout(cont)

0 If the axis was in the Y_AXIS(Vertical), then the output will be

content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));

Chap-3 Adv Prog

133

The Box class 0 The Box class was designed to be a simple, and slightly more efficient, substitute for a JPanel with a BoxLayout. Because it doesn't support everything that JPanel does (eg, borders), I recommend using a JPanel with a BoxLayout rather than Box. However, the Box class has a number of necessary methods for working with BoxLayouts. 0 Because Box is a Container with BoxLayout, all discussions of spacing and alignment apply equally well to both JPanels with BoxLayouts and Boxes. Creating Boxes 0 You can create the two kinds of boxes with: import javax.swing.*; ... Box vb = Box.createVerticalBox(); Box hb = Box.createHorizontalBox(); No Borders on Boxes 0 Boxes are lighter weight (ie, more efficient) than JPanel, but they don't support Borders. If you need borders, either use a JPanel with BoxLayout, or put the Box into a JPanel with a border. 134
Chap-3 Adv Prog

BoxLayout(cont)

BoxLayout(cont)
BoxLayout spacing
Fillers - rigid areas, glue, struts, and custom Fillers 0 Invisible components can be added to a layout to produce empty space between components. The most useful are rigid areas (or struts).Glue may be insert expandable empty space in a layout. 0 Rigid areas have a fixed horizontal and vertical size. 0 Struts are fixed either vertically or horizontally. Generally use rigid areas instead of struts. 0 Glue is an expandable component. Used if you want spacing to increase when a window is resized. 0 Box.Filler is a more general spacing component with specified minimum, preferred, and maximum sizes.

Chap-3 Adv Prog

135

BoxLayout(cont)
BoxLayout spacing(cont)
Rigid Area 0 A rigid area is very is a fixed size filler with vertical and horizontal dimensions. It can be used in either horizontal or vertical layouts. Create a rigid area by specifying its width and height in pixels in a Dimension object, which has two parameters, an x distance and a y distance. Typically the dimension you are not interested in is set to zero.

p.add(Box.createRigidArea(new Dimension(10, 0)));


This creates a rigid area component 10 pixels wide and 0 pixels high and adds it to a panel.

Chap-3 Adv Prog

136

BoxLayout(cont)
BoxLayout spacing(cont)
Glue p.add(Box.createVerticalGlue()); // expandable vertical space. p.add(Box.createHorizontalGlue()); // expandable horizontal space.
0 Glue is an invisible component that can expand. It's more like a spring or

sponge than glue. Put a glue component where extra space should appear (disappear from) when a window is resized. Use vertical glue in a vertical BoxLayout and horizontal glue in a horizontal layout. For example, this will allow extra vertical space between two buttons. JPanel p = new JPanel(); p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS)); p.add(button1); p.add(Box.createVerticalGlue()); // This will expand/contract as needed. p.add(button2); 0 Use Box.createHorizontalGlue() for horizontal expansion.
Chap-3 Adv Prog 137

BoxLayout(cont)
BoxLayout spacing(cont)
Struts p.add(Box.createVerticalStrut(n)); // n pixels of vertical space. p.add(Box.createHorizontalStrut(n)); // n pixels of horizontal space. Create a strut by specifying its size in pixels, and adding it to the panel at the point you want the space between other components.
0 Important: Use horizontal struts only in horizontal layouts and vertical

struts only in vertical layouts, otherwise there will be problems. To avoid problems from nested panels, you are generally better off using a rigid area. p.add(Box.createHorizontalStrut(10)); This creates a strut component 10 pixels wide and adds it to a panel.

Chap-3 Adv Prog

138

BoxLayout(cont)
BoxLayout spacing(cont)
Box.Filler 0 You can create your own filler by using the Box.Filler constructor and specifying the minimum, preferred, and maximum size. Each size must be in a Dimension object, which has width and height. Box.Filler myFiller = new Box.Filler(min, pref, max); For example, to create a new horizontal filler that can get no smaller that 4 pixels, that prefers to be 16 pixels wide, and that will expand to no more than 32 pixels, you could do this: Box.Filler hFill = new Box.Filler(new Dimension(4,0), new Dimension(16, 0), new Dimension(32, 0));

Chap-3 Adv Prog

139

BoxLayout alignment 0 Component alignment 0 Alignment is a property of the component, not the layout. but box layout will respect that . Generally you want all components in a box to have the same alignment (eg, left/top, center, or right/bottom). Set the X alignment for components in a vertical box and the Y alignment for components in a horizontal box. myComponent.setAlignmentX(align); // For vertical layouts myComponent.setAlignmentY(align); // For horizontal layouts Where align is one of the following constants from the java.awt.Component class.
0 Component.LEFT_ALIGNMENT 0 Component.CENTER_ALIGNMENT - for both horizontal or vertical layouts. 0 Component.RIGHT_ALIGNMENT 0 Component.TOP_ALIGNMENT 0 Component.BOTTOM_ALIGNMENT
Chap-3 Adv Prog 140

BoxLayout(cont)

import java.awt.*; Lets do our exercise - Details ----------- -------------| Name: Text | import javax.swing.*; | System: Radio button | | Language: Check box | public class BoxLayoutTest { | Year: Dropdown | -------------------------- --------public static void main(String[] a) { OK Cancel JFrame myFrame = new JFrame("BoxLayout Test"); myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Container myPane = myFrame.getContentPane(); myPane.setLayout(new BoxLayout(myPane,BoxLayout.Y_AXIS)); myPane.add(getFieldPanel()); myPane.add(getButtonPanel()); myFrame.pack(); myFrame.setVisible(true); } Cont
Chap-3 Adv Prog 141

BoxLayout(cont)

private static JPanel getFieldPanel() { JPanel p = new JPanel(); p.setLayout(new BoxLayout(p,BoxLayout.X_AXIS)); p.setBorder(BorderFactory.createTitledBorder("Details")); p.add(getLabelPanel()); p.add(getValuePanel()); return p; } private static JPanel getButtonPanel() { JPanel p = new JPanel(); p.setLayout(new BoxLayout(p,BoxLayout.X_AXIS)); p.add(new JButton("OK")); p.add(new JButton("Cancel")); return p; }

BoxLayout(cont)

Cont

Chap-3 Adv Prog

142

private static JPanel getLabelPanel() { JPanel p = new JPanel(); p.setLayout(new BoxLayout(p,BoxLayout.Y_AXIS)); JLabel l = new JLabel("Name:"); l.setAlignmentX(Component.RIGHT_ALIGNMENT); p.add(l); l = new JLabel("System:"); l.setAlignmentX(Component.RIGHT_ALIGNMENT); p.add(l); l = new JLabel("Language:"); l.setAlignmentX(Component.RIGHT_ALIGNMENT); p.add(l); l = new JLabel("Year:"); l.setAlignmentX(Component.RIGHT_ALIGNMENT); p.add(l); return p; } Chap-3 Adv Prog Cont

BoxLayout(cont)

143

BoxLayout(cont) private static JPanel getValuePanel() {


JPanel p = new JPanel(); p.setLayout(new BoxLayout(p,BoxLayout.Y_AXIS)); JComponent c = new JTextField(16); c.setAlignmentX(Component.LEFT_ALIGNMENT); p.add(c); JPanel s = getSystemPanel(); s.setAlignmentX(Component.LEFT_ALIGNMENT); p.add(s); s = getLanguagePanel(); s.setAlignmentX(Component.LEFT_ALIGNMENT); p.add(s); JComboBox b = new JComboBox( new String[] {"2001","2002","2003"}); b.setAlignmentX(Component.LEFT_ALIGNMENT); p.add(b); return p; Chap-3 Adv Prog 144 Cont

private static JPanel getSystemPanel() { JRadioButton unixButton = new JRadioButton("Unix",true); JRadioButton winButton = new JRadioButton("Window",false); ButtonGroup systemGroup = new ButtonGroup(); systemGroup.add(unixButton); systemGroup.add(winButton); JPanel p = new JPanel(); p.setLayout(new BoxLayout(p,BoxLayout.X_AXIS)); p.add(unixButton); p.add(winButton); return p; }
Cont

BoxLayout(cont)

Chap-3 Adv Prog

145

private static JPanel getLanguagePanel() { JPanel p = new JPanel(); p.setLayout(new BoxLayout(p,BoxLayout.X_AXIS)); p.add(new JCheckBox("Java",true)); p.add(new JCheckBox("C++",true)); p.add(new JCheckBox("Perl",false)); return p; } } end of the class

BoxLayout(cont)

Chap-3 Adv Prog

146

BoxLayout(cont)
0 But if you look closely, value components are not aligned to the

corresponding label components. It is almost impossible to align them, because they are in two different panels. 0 So, BoxLayout is still not good for our example. 0 Another question about BoxLayout is why the constructor needs to take the container as input. Constructors of other layouts do not need containers. This makes the statement looks very strange: p.setLayout(new BoxLayout(p,...)).

Chap-3 Adv Prog

147

GridLayout
0 GridLayout is a layout that:

0 Divides the container into rows and columns. The number of

rows and the number of columns are configurable. Rows and columns are equally divided. 0 Places components into the specified cells. 0 Resizes each component to match the size of its cell. 0 Resizes all components when the container is resized.

Chap-3 Adv Prog

148

GridLayout(cont)
0 GridLayout lays out components in a rectangular grid, where all

cells are equal size. 0 GridLayout forces components to have the same size. 0 Example JPanel content = new JPanel(new GridLayout(2,2));//2rows &2cols content.add(new JButton("Button 1")); content.add(new JButton("2")); content.add(new JLabel("")); // for empty cell content.add(new JButton("This is button three"));

Chap-3 Adv Prog

149

To Create a GridLayout 0 There are three constructors: p.setLayout(new GridLayout()); // One row. Columns expand. p.setLayout(new GridLayout(rows, cols)); p.setLayout(new GridLayout(rows, cols, hgap, vgap)); with the following int parameters: rows is number of rows, cols is number of columns, hgap is horizontal space between components (in pixels), and vgap is vertical space between components (in pixels). 0 For example, this creates a panel with a grid layout of 4 rows and 3 columns. There are 5 pixels of horizontal space between components and 10 pixels of space between vertical components. JPanel p = new JPanel(); p.setLayout(new GridLayout(4, 3, 5, 10)); p.add(. . .);
150

GridLayout(cont)

To add Components to a GridLayout 0 Use the .add(. . .) method to add components to a container with a GridLayout. You do not (can not) use the row and column to tell where to add the components -- add them in starting at the top left and going across the row first.
Empty Cells 0 There is no way to leave a cell empty in a grid layout. Although it often works ok to leave the final cells empty, there are reports of problems, so you should fill out the last cells in the final row too. The easiest way to do this is to put an empty label in any cell you want to skip. Eg. p.add(new JLabel(""));
151

GridLayout(cont)

GridLayout(cont)
import java.awt.*; Lets do our exercise - Details ----------- -------------import javax.swing.*; | Name: Text | | System: Radio button | | Language: Check box | public class GridLayoutTest { | Year: Dropdown | -------------------------- --------public static void main(String[] a) { OK Cancel JFrame myFrame = new JFrame("Layout Test 1"); myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Container myPane = myFrame.getContentPane(); myPane.setLayout(new GridLayout(2,1)); myPane.add(getFieldPanel()); myPane.add(getButtonPanel()); myFrame.pack(); myFrame.setVisible(true); } Chap-3 Adv Prog 152 Cont

GridLayout(cont)
private static JPanel getFieldPanel() { JPanel p = new JPanel(new GridLayout(4,2)); p.setBorder(BorderFactory.createTitledBorder("Details")); p.add(new JLabel("Name:",SwingConstants.RIGHT)); p.add(new JTextField(16)); p.add(new JLabel("System:",SwingConstants.RIGHT)); p.add(getSystemPanel()); p.add(new JLabel("Language:",SwingConstants.RIGHT)); p.add(getLanguagePanel()); p.add(new JLabel("Year:",SwingConstants.RIGHT)); p.add(new JComboBox(new String[] {"2001","2002","2003"})); return p; } Cont
Chap-3 Adv Prog 153

GridLayout(cont)
private static JPanel getButtonPanel() { JPanel p = new JPanel(new GridLayout(1,2)); p.add(new JButton("OK")); p.add(new JButton("Cancel")); return p; } private static JPanel getLanguagePanel() { JPanel p = new JPanel(new GridLayout(1,3)); p.add(new JCheckBox("Java",true)); p.add(new JCheckBox("C++",true)); p.add(new JCheckBox("Perl",false)); return p; }

Cont
Chap-3 Adv Prog 154

GridLayout(cont) private static JPanel getSystemPanel() {


JRadioButton unixButton = new JRadioButton("Unix",true); JRadioButton winButton = new JRadioButton("Window",false); ButtonGroup systemGroup = new ButtonGroup(); systemGroup.add(unixButton); systemGroup.add(winButton); JPanel p = new JPanel(new GridLayout(1,2)); p.add(unixButton); p.add(winButton); return p; }

}//end of the class


0 All components are aligned correctly

in both directions now. But all components are having wrong sizes. 0 So, GridLayout is still not good for our eg.
155

GridBagLayout
0 GridBagLayout is one of the most flexible and complex layout managers the Java platform provides. And it :

and the number of columns are unlimited. Rows and columns are not equally divided. 0 Places components into the specified cells. 0 Uses the default size of each component. 0 Keeps component sizes unchanged when the container is resized. 0 Provides individual layout constraints for each component to control its layout behavior. 0 GridBagLayout lays out components based on a grid with rows and columns that need not all be the same size. If you're familiar with HTML tables, you'll feel comfortable with the idea. Unfortunately, GridBagLayout is awkward and error-prone to use.
156

0 Divides the container into rows and columns. The number of rows

GridBagLayout(cont)
Abandon hope, all who use GridBagLayout
0 Although GridBagLayout can produce acceptable results, it's not a happy

0 0 0

story. It is very difficult to work with because eleven constraint values are used for each component! These constraint values are bundled in a java.awt.GridBagConstraints object. Fortunately, most of them have reasonable defaults. The layout doesn't have features which specifically help to use Sun's (or anyone else's) Human Interface Guidelines, for example in handling gaps. Spacing is specified in pixels, which provides no flexibility for screen resolution and font changes. Quote from Otaku, Cedric's blog: "GridBagLayout is an absolute disaster and the perfect example of something that is completely flawed and violates with a stunning regularity the principle of least surprise." Some prefer to call it "GridBugLayout".
157

GridBagLayout(cont)
0 Subpanels for unrelated components. An entire window may

require use of nested panels -- don't try to force everything into one giant GridBagLayout. If some groups of components (eg, radio buttons, groups of buttons, checkboxes) are unrelated to alignment with other components, put them in their own panel and use an appropriate layout (often GridLayout). Unequal rows and columns 0 The underlying idea is rows and columns, similar to HTML tables. 0 Rows and columns don't all have to be same size. The size of each row and column is adjusted depending on maximum component size in the row/column and their constraints. 0 A component display area may span several rows and/or columns. Describe this area by giving the row, column, width (in columns), and height (in rows). 0 A components doesn't have to fill its display area; constraints describe how to align it within its area.
158

GridBagLayout(cont)
Three categories of constraint parameters 0 GridBagLayout performs three functions using values from the GridBagConstraints parameter in the add() method. The names are the following. 1. Grid position, width and height describe the display area.. gridx, gridy, gridwidth, and gridheight. 2. Position within the display area. fill, anchor, insets, ipadx, and ipady. 3. Identifying rows and columns which receive extra space on expansion. weightx, and weighty. Constructor JPanel p = new JPanel(new GridBagLayout()); or JPanel p = new JPanel(); p.setLayout(new GridBagLayout()); Do not give the number of rows and columns when you create a new GridBagLayout. They are computed by the layout manager as a consequence of what you add. 159

GridBagLayout(cont)
Adding a component 0 Components are added to JPanel p like this: p.add(component, constraintObj); Constraint parameters are instance fields in a GridBagConstraints object. The add() method clones (copies) the constraint object, so typically the same GridBagConstraints object is reused to pass constraints for the next component. It is common to use only one GridBagConstraints object to add all components, changing fields as necessary between adds, but this practice also leads to many errors and code which is difficult to change.

160

GridBagLayout(cont)
GridBagConstraints fields 0 The fields can divided into three groups: 1. Necessary - row and column coordinates, width and height in terms of rows and columns. Describe the location and size (in rows and columns) of the component using gridx, gridy, gridwidth, and gridheight. 2. Common - expandability and alignment. If a column or row can use extra space when a window is expanded, set weightx and weighty to 1.0; you will rarely want to use other values.
Use fill depending on what the type of component is. For example, a JTextField can usually grow horizontally, so you would use gbc.fill = GridBagConstraints.HORIZONTAL; to allow it to stretch. Use anchor to tell which edges of the display area a component should be attached to.

3.

Less common - surrounding spacing. You can also control the space around a component with ipadx and ipady. To control the amount of unused space around a component, use insets.
161

GridBagLayout(cont)
GridBagConstraints
0 gridx, gridy : Specify the row and column at the upper left of the

component. The leftmost column has address gridx=0 and the top row has address gridy=0. Use GridBagConstraints.RELATIVE (the default value) to specify that the component be placed just to the right of (for gridx) or just below (for gridy) the component that was added to the container just before this component was added. We recommend specifying the gridx and gridy values for each component rather than just using GridBagConstraints.RELATIVE; this tends to result in more predictable layouts. 0 fill : Used when the component's display area is larger than the component's requested size to determine whether and how to resize the component. Valid values (defined as GridBagConstraints constants) include NONE (the default), HORIZONTAL (make the component wide enough to fill its display area horizontally, but do not change its height), VERTICAL (make the component tall enough to fill its display area vertically, but do not change its width), and BOTH (make the component fill its display area entirely).
162

GridBagLayout(cont)
GridBagConstraints(cont)
0 gridwidth, gridheight : Specify the number of columns (for gridwidth) or

rows (for gridheight) in the component's display area. These constraints specify the number of cells the component uses, not the number of pixels it uses. The default value is 1. Use GridBagConstraints.REMAINDER to specify that the component be the last one in its row (for gridwidth) or column (for gridheight). Use GridBagConstraints.RELATIVE to specify that the component be the next to last one in its row (for gridwidth) or column (for gridheight). We recommend specifying the gridwidth and gridheight values for each component rather than just using GridBagConstraints.RELATIVE and GridBagConstraints.REMAINDER; this tends to result in more predictable layouts. Note: GridBagLayout does not allow components to span multiple rows unless the component is in the leftmost column or you have specified positive gridx and gridy values for the component.
163

GridBagLayout(cont)
GridBagConstraints(cont)
0 ipadx, ipady Specifies the internal padding: how much to add to the size of

the component. The default value is zero. The width of the component will be at least its minimum width plus ipadx*2 pixels, since the padding applies to both sides of the component. Similarly, the height of the component will be at least its minimum height plus ipady*2 pixels.

0 insets Specifies the external padding of the component -- the minimum

amount of space between the component and the edges of its display area. The value is specified as an Insets object. By default, each component has no external padding.

164

GridBagConstraints(cont)

GridBagLayout(cont)

0 anchor Used when the component is smaller than its display area to

determine where (within the area) to place the component. Valid values (defined as GridBagConstraints constants) are CENTER (the default), PAGE_START, PAGE_END, LINE_START, LINE_END, FIRST_LINE_START, FIRST_LINE_END, LAST_LINE_END, and LAST_LINE_START. Here is a picture of how these values are interpreted in a container that has the default, leftto-right component orientation.
FIRST_LINE_START LINE_START LAST_LINE_START PAGE_START CENTER PAGE_END FIRST_LINE_END LINE_END LAST_LINE_END

Version note: The PAGE_* and *LINE_* constants were introduced in 1.4.

Previous releases require values named after points of the compass. For example, NORTHEAST indicates the top-right part of the display area. We recommend that you use the new constants, instead, since they enable 165 easier localization.

GridBagConstraints(cont)

GridBagLayout(cont)

0 weightx, weighty : Specifying weights is an art that can have a significant

impact on the appearance of the components a GridBagLayout controls. Weights are used to determine how to distribute space among columns (weightx) and among rows (weighty); this is important for specifying resizing behavior. Unless you specify at least one non-zero value for weightx or weighty, all the components clump together in the center of their container. This is because when the weight is 0.0 (the default), the GridBagLayout puts any extra space between its grid of cells and the edges of the container. Generally weights are specified with 0.0 and 1.0 as the extremes: the numbers in between are used as necessary. Larger numbers indicate that the component's row or column should get more space. For each column, the weight is related to the highest weightx specified for a component within that column, with each multicolumn component's weight being split somehow between the columns the component is in. Similarly, each row's weight is related to the highest weighty specified for a component within that row. Extra space tends to go toward the rightmost column and bottom 166 row.

GridBagLayout(cont)
gridx gridy The int column (gridx) and row (gridy) of the component. If requires more than one cell (gridwidth or gridheight > 1), this is the coordinate of the topleft cell. The row and columns start at zero. The value GridBagConstraints.RELATIVE places the component in the next position. Number of columns or rows the component occupies. GridBagConstraints.REMAINDER indicates that this component should fill out all rows or columns to the end. Default 1. These double variables (default value 0) are used in calculating where space is allocated in rows and columns when a window is resized. extra space should be allocated in a column horizontally (weightx) and row vertically (weighty). A column width is originally calculated as the maximum width of the preferred sizes of the components in that column. If a component is narrower than the column width, the value of the fill attribute is used in deciding how to use that extra space (see below). Extra horizontal space is allocated to a column in proportion to the maximum weightx value for that column. If weightx is zero, no extra space is allocated. Because these weights are relative, you can assign any arbitrary positive double value to produce the desired layout, although it is common to work in the range 0-1. The analogous procedure is performed for the row heights using weighty. 167 gridwidth gridheight weightx weighty

GridBagLayout(cont)
fill Fill specifies how the component should expand within its display area if the area width/height is larger than its preferred size. GridBagConstraints.NONE // Can't expand (Default) GridBagConstraints.VERTICAL // Expand vertically GridBagConstraints.HORIZONTAL // Expand horizontally GridBagConstraints.BOTH // Expand vertically and horizontallyFor example, a text field typically expands horizontally (GridBagConstraints.HORIZONTAL), a text area expands vertically and horizontally (GridBagConstraints.BOTH), and a button might not expand at all (GridBagConstraints.NONE). If a component isn't expanded to fill the space, the anchor attribute (see below) is used to specify where it goes within that cell. Default value GridBagConstraints.NONE. If the component doesn't occupy its entire display area, anchor specifies where it should be placed. The location is usually given as a compass direction. (A relative system which works for both right-to-left and left-toright languages is also available). GridBagConstraints.CENTER (the default), GridBagConstraints.NORTH GridBagConstraints.SOUTH GridBagConstraints.NORTHEAST GridBagConstraints.SOUTHWEST GridBagConstraints.EAST GridBagConstraints.WEST GridBagConstraints.SOUTHEAST GridBagConstraints.NORTHWEST 168

anchor

GridBagLayout(cont)
insets A java.awt.Insets object adds padding space to the component. Insets should be rarely used because they often produce bad results, with the exception of JPanels and JLabels. The constructor parameters (in pixels) specify the top, left, bottom, right. For example, gbc.insets = new Insets(10, 5, 10, 4); Default value: Insets(0,0,0,0). These int fields specify an increase or decrease in the horizontal and/or vertical preferred size of the component. Default value 0. Negative values can be used to tighten the spacing. These values are rarely useful, although they can be used for fine-tuning spacing. ipadx ipady

169

Java Idiom 0 It's common to write a utility method which sets the fields of a GridBagConstraints object. For example, GridBagConstraints gbc = new GridBagConstraints(); ... private void set_gbc(int row, int column, int width, int height, int fill) { gbc.gridy = row; gbc.gridx = column; gbc.gridwidth = width; gbc.gridheight = height; gbc.fill = fill; // GridBagConstraints.NONE .HORIZONTAL .VERTICAL .BOTH // leave other fields (eg, anchor) unchanged. } ... set_gbc(3, 2, 2, 1, GridBagConstraints.HORIZONTAL); gbc.insets = new Insets(3,3,3,3); // put spacing around this field. p.add(myTextField, gbc);
170

GridBagLayout(cont)

GridBagLayout(cont)
Adding a component 0 To add myField to the third row (2) and first column (0), where the button will be one grid cell wide and one high, and it will be able to expand horizontally, do this: set_gbc(2, 0, 1, 1, GridBagConstraints.HORIZONTAL); gridbag.setConstraints(myField, gbc); panel.add(myField); Opinion 0 GridBagLayout is not a nice piece of software. The GridBagConstraints object is awkward to use. It allows you to make careless mistakes in the layout without warnings or error messages.

171

GridBagLayout(cont)
import javax.swing.*; public class DemoGridBag { public static void main(String[] a){ JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setVisible(true); JPanel pane = new JPanel(); pane.setLayout(new GridBagLayout()); JButton button; GridBagConstraints c = new GridBagConstraints(); button = new JButton("Button 1"); c.weightx = 0.5; c.fill = GridBagConstraints.HORIZONTAL; c.gridx = 0; c.gridy = 0; pane.add(button, c);
172

GridBagLayout(cont)
button = new JButton("Button 2"); c.fill = GridBagConstraints.HORIZONTAL; c.weightx = 0.5; c.gridx = 1; c.gridy = 0; pane.add(button, c);
button = new JButton("Button 3"); c.fill = GridBagConstraints.HORIZONTAL; c.weightx = 0.5; c.gridx = 2; c.gridy = 0; pane.add(button, c); button = new JButton("Long-Named Button 4"); c.fill = GridBagConstraints.HORIZONTAL; c.ipady = 40; //make this component tall c.weightx = 0.0; c.gridwidth = 3; c.gridx = 0; c.gridy = 1; pane.add(button, c); button = new JButton("5"); c.fill = GridBagConstraints.HORIZONTAL; c.ipady = 0; //reset to default c.weighty = 1.0; //request any extra vertical space c.anchor = GridBagConstraints.PAGE_END; //bottom of space c.insets = new Insets(10,0,0,0); //top padding c.gridx = 1; //aligned with button 2 c.gridwidth = 2; //2 columns wide c.gridy = 2; //third row pane.add(button, c); f.add(pane); f.pack(); }//end of main }//end of the class

173

GridBagLayout(cont) import java.awt.*;

Lets do our exercise

- Details ----------- -------------import javax.swing.*; | Name: Text | | System: Radio button | public class GridBagLayoutTest { | Language: Check box | | Year: Dropdown | public static void main(String[] a) { -------------------------- --------OK Cancel JFrame myFrame = new JFrame("GridBagLayout Test"); myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Container myPane = myFrame.getContentPane(); myPane.setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); setMyConstraints(c,0,0,GridBagConstraints.CENTER); //(gridbagconstraint, // gridx, gridy, anchor) myPane.add(getFieldPanel(),c); setMyConstraints(c,0,1,GridBagConstraints.CENTER); myPane.add(getButtonPanel(),c); myFrame.pack(); myFrame.setVisible(true); } 174 Cont

GridBagLayout(cont)
private static JPanel getFieldPanel() { JPanel p = new JPanel(new GridBagLayout()); p.setBorder(BorderFactory.createTitledBorder("Details")); GridBagConstraints c = new GridBagConstraints(); setMyConstraints(c,0,0,GridBagConstraints.EAST); p.add(new JLabel("Name:"),c); setMyConstraints(c,1,0,GridBagConstraints.WEST); p.add(new JTextField(16),c); setMyConstraints(c,0,1,GridBagConstraints.EAST);p.add(new JLabel("System:"),c); setMyConstraints(c,1,1,GridBagConstraints.WEST); p.add(getSystemPanel(),c); setMyConstraints(c,0,2,GridBagConstraints.EAST); p.add(new JLabel("Language:"),c); setMyConstraints(c,1,2,GridBagConstraints.WEST); p.add(getLanguagePanel(),c); setMyConstraints(c,0,3,GridBagConstraints.EAST); p.add(new JLabel("Year:"),c); setMyConstraints(c,1,3,GridBagConstraints.WEST); p.add(new JComboBox(new String[] {"2001","2002","2003"}),c); return p; } 175 Cont

GridBagLayout(cont)
private static JPanel getButtonPanel() { JPanel p = new JPanel(new GridBagLayout()); p.add(new JButton("OK")); p.add(new JButton("Cancel")); return p; } private static JPanel getSystemPanel() { JRadioButton unixButton = new JRadioButton("Unix",true); JRadioButton winButton = new JRadioButton("Window",false); ButtonGroup systemGroup = new ButtonGroup(); systemGroup.add(unixButton); systemGroup.add(winButton); JPanel p = new JPanel(new GridBagLayout()); p.add(unixButton); p.add(winButton); return p; } Cont

176

GridBagLayout(cont)
private static JPanel getLanguagePanel() { JPanel p = new JPanel(new GridBagLayout()); p.add(new JCheckBox("Java",true)); p.add(new JCheckBox("C++",true)); p.add(new JCheckBox("Perl",false)); return p; } private static void setMyConstraints(GridBagConstraints c, int gridx, int gridy, int anchor) { c.gridx = gridx; c.gridy = gridy; c.anchor = anchor; } }//end of the class 0 All components are aligned correctly in both directions now. And all components are properly sized. 0 GridBagLayout seems to be good enough for our example.
177

Layout(cont)
General advice 0 Initial Iterations. To quickly get the first iterations of a program running, use FlowLayout. The result is often ugly, but if there are only a few components, it's quick. FlowLayout is rarely the correct layout to use in a finished program. 0 Simple programs. BorderLayout is often a good layout for simple programs. More complicated layouts can often be nesting BorderLayouts within other BorderLayouts. This and FlowLayout are the most important layouts for beginners. 0 Grids of equal sized elements (eg, a calculator keypad), can be created with GridLayout. 0 Single Rows or columns of components are sometimes best done with BoxLayout. 0 More complicated layouts may require GridBagLayout. Getting a GridBagLayout to work correctly can be time-consuming, but it produces excellent results.
178

Null Layout
0 You can set the layout manager to null(cont.setLayout(null);), but this is generally

bad practice. 0 Eg

import javax.swing.*; import java.awt.*; public class NullLayoutTest { public static void main(String[] a){ JFrame f = new JFrame(); f.setTitle("Null layout demo"); f.setSize(500,100); JTextField m_milesTf = new JTextField(10); JTextField m_kilometersTf = new JTextField(10); JButton m_convertBtn = new JButton("Convert"); JLabel kmLabel = new JLabel("Kilometers"); JLabel miLabel = new JLabel("Miles");

179

Null Layout (cont)


//... Set the positions of components. kmLabel.setBounds(5, 10, 62, 16); //x, y, width, height m_kilometersTf.setBounds(72, 8, 114, 20); m_convertBtn.setBounds(191, 5, 78, 26); miLabel.setBounds(274, 10, 30, 16); m_milesTf.setBounds(309, 8, 114, 20); //... Content panel, layout, add components JPanel content = new JPanel(); content.setLayout(null); content.add(kmLabel); content.add(m_kilometersTf); content.add(m_convertBtn); content.add(miLabel); content.add(m_milesTf); f.add(content); f.setVisible(true); } }
180

Problems with null layout that regular layouts don't have 0 Difficult to change, therefore hard (expensive) to maintain Moving, adding, removing, etc require a lot of recalculation. Relatively little work is required with regular layouts. 0 Hard to get right in the first place Exactly how do you get these coordinates? 0 System dependent The components have different sizes in different systems. I once wrote a Java program that I proudly showed to an important colleague, who unfortunately was using a different system. The layout looked really, really bad - gaps, overlaps. What happened? Null layout! It was one of my early programs and the last null layout I ever wrote. 0 Java version dependent A little know fact is that between Java versions the rendering of components something changes slightly. It's not big, but if you have things carefully aligned in null layouts, they may not be in the next version of Java. 0 User setting dependent Another little used feature is that the user can actually change Java's default settings for fonts etc. I once decided I wanted larger fonts on the high resolution screen I had. Of course, this completely breaks any null layouts altho regular layouts will adjust properly. 0 Not resizeable It's not uncommon to have text fields/areas that the use might want to make larger by dragging 181 the lower right corner of the window. Impossible with null layouts, automatic with regular layouts.

Null Layout (cont)

Reading on Layout
0 Read the following layout types: CardLayout GroupLayout SpringLayout

182

Events -- Introduction
0 Events come from User Controls When you define a user interface, you will usually have some way to

get user input. For example, buttons, menus, sliders, mouse clicks, ... all generate events when the user does something with them. User interface event objects are passed from an event source, such as a button or mouse click, to an event listener, a user method which will process them. 0 Every Input Control (JButton, JSlider, ...) Needs an Event Listener If you want a control to do something when the user alters the control, you must have a listener. 0 import Statements: To use events, you must import : import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*;

Types of Events
There are several kinds of events. The most common are: User Control JButton JTextField JMenuItem JSlider JCheckBox addXXXListener addActionListener() addChangeListener() addItemListener() method in listener actionPerformed(ActionEvent e) stateChanged(ChangeEvent e) itemstateChanged() keyPressed(), keyReleased(), keyTyped() mouseClicked(), mouseEntered(), mouseExited(), mousePressed(), mouseReleased() mouseMoved(), mouseDragged() windowClosing(WindowEvent e), ...

key on component

addKeyListener()

mouse on component

addMouseListener()

mouse on component JFrame

addMouseMotionListener() addWindowListener()

Listener API Table


Listener Interface Adapter Class Listener Methods

ActionListener
AncestorListener

None
None

actionPerformed(ActionEvent)
ancestorAdded(AncestorEvent) ancestorMoved(AncestorEvent) ancestorRemoved(AncestorEvent)

CaretListener
CellEditorListener

None
None

caretUpdate(CaretEvent)
editingStopped(ChangeEvent) editingCanceled(ChangeEvent)

ChangeListener

none

stateChanged(ChangeEvent)
componentHidden(ComponentEvent) componentMoved(ComponentEvent) componentResized(ComponentEvent) componentShown(ComponentEvent) componentAdded(ContainerEvent) componentRemoved(ContainerEvent)

ComponentListener ComponentAdapter

ContainerListener

ContainerAdapter

Listener API Table


Listener Interface DocumentListener ExceptionListener FocusListener Adapter Class none none FocusAdapter Listener Methods changedUpdate(DocumentEvent) insertUpdate(DocumentEvent) removeUpdate(DocumentEvent) exceptionThrown(Exception) focusGained(FocusEvent) focusLost(FocusEvent)

HierarchyBoundsList HierarchyBoundsAdapter ener


HierarchyListener none

ancestorMoved(HierarchyEvent) ancestorResized(HierarchyEvent)
hierarchyChanged(HierarchyEvent)

HyperlinkListener

none

hyperlinkUpdate(HyperlinkEvent)
caretPositionChanged(InputMethod Event) inputMethodTextChanged(InputMet hodEvent)

InputMethodListener none

Listener API Table


Listener Interface Adapter Class Listener Methods internalFrameActivated(InternalFrameEvent) internalFrameClosed(InternalFrameEvent) internalFrameClosing(InternalFrameEvent) internalFrameDeactivated(InternalFrameEvent) internalFrameDeiconified(InternalFrameEvent) internalFrameIconified(InternalFrameEvent) internalFrameOpened(InternalFrameEvent) InternalFrameListener InternalFrameAdapter

ItemListener
KeyListener

none
KeyAdapter

itemStateChanged(ItemEvent)
keyPressed(KeyEvent) keyReleased(KeyEvent) keyTyped(KeyEvent) contentsChanged(ListDataEvent) intervalAdded(ListDataEvent) intervalRemoved(ListDataEvent)

ListDataListener ListSelectionListener

none none

valueChanged(ListSelectionEvent)

Listener API Table


Listener Interface MenuDragMouseListener Adapter Class none Listener Methods menuDragMouseDragged(MenuDragMouseEvent) menuDragMouseEntered(MenuDragMouseEvent) menuDragMouseExited(MenuDragMouseEvent) menuDragMouseReleased(MenuDragMouseEvent) menuKeyPressed(MenuKeyEvent) menuKeyReleased(MenuKeyEvent) menuKeyTyped(MenuKeyEvent) menuCanceled(MenuEvent) menuDeselected(MenuEvent) menuSelected(MenuEvent)

MenuKeyListener

none

MenuListener

none

MouseInputListener ( extends MouseListener and MouseMotionListener

MouseInputAda pter MouseAdapter

mouseClicked(MouseEvent) mouseEntered(MouseEvent) mouseExited(MouseEvent) mousePressed(MouseEvent) mouseReleased(MouseEvent) mouseDragged(MouseEvent) mouseMoved(MouseEvent) MouseAdapter(MouseEvent)

Listener API Table


Listener Interface Adapter Class Listener Methods

MouseListener

MouseAdapter, MouseInputAdapter

mouseClicked(MouseEvent) mouseEntered(MouseEvent) mouseExited(MouseEvent) mousePressed(MouseEvent) mouseReleased(MouseEvent)

MouseMotionListener MouseWheelListener

MouseMotionAdapter, mouseDragged(MouseEvent) MouseInputAdapter mouseMoved(MouseEvent) MouseAdapter mouseWheelMoved(MouseWheelEvent) MouseAdapter<MouseEvent> popupMenuCanceled(PopupMenuEvent) popupMenuWillBecomeInvisible(Popup MenuEvent) popupMenuWillBecomeVisible(PopupMe nuEvent)

PopupMenuListener

none

Listener API Table


Listener Interface Adapter Class Listener Methods

PropertyChangeListener

none

propertyChange(PropertyChangeEvent) columnAdded(TableColumnModelEvent) columnMoved(TableColumnModelEvent) columnRemoved(TableColumnModelEvent) columnMarginChanged(ChangeEvent) columnSelectionChanged(ListSelectionEvent) tableChanged(TableModelEvent) treeCollapsed(TreeExpansionEvent) treeExpanded(TreeExpansionEvent) treeNodesChanged(TreeModelEvent) treeNodesInserted(TreeModelEvent) treeNodesRemoved(TreeModelEvent) treeStructureChanged(TreeModelEvent) valueChanged(TreeSelectionEvent)

TableColumnModelListener

none

TableModelListener TreeExpansionListener

none none

TreeModelListener

none

TreeSelectionListener

none

Listener API Table


Listener Interface Adapter Class Listener Methods

TreeWillExpandListener
UndoableEditListener VetoableChangeListener WindowFocusListener

none
none none Window Adapter

treeWillCollapse(TreeExpansionEvent) treeWillExpand(TreeExpansionEvent) undoableEditHappened(UndoableEditEvent) vetoableChange(PropertyChangeEvent) windowGainedFocus(WindowEvent) windowLostFocus(WindowEvent) windowActivated(WindowEvent) windowClosed(WindowEvent) windowClosing(WindowEvent) windowDeactivated(WindowEvent) windowDeiconified(WindowEvent) windowIconified(WindowEvent) windowOpened(WindowEvent) windowStateChanged(WindowEvent)

WindowListener

Window Adapter

WindowStateListener

Window Adapter

Listeners
0 A listener is called when the user does something to the user

interface that causes an event. Although these events usually come from the user interface, they can have other sources (eg, a Timer).

Button listener example 0 After a button is created, you will add a listener to it. Eg, b.addActionListener(listener_object); When the button is clicked, a call is made to the actionPerformed() method defined in the class of the listener object. An ActionEvent object is passed as a parameter to it actionPerformed().

Listeners
The listener method must be called actionPerformed 0 There is (unfortunately) no way to use any given method as a listener -- the listener must be called actionPerformed. 0 One per class. Because there can only be one actionPerformed method in a class, a new class is needed for every separate listener, or you have to share an actionPerformed method and use the ugly technique of figuring out who caused the call. 0 Incidental note. To address this awkward situation C# has delegates, which allow any method to be a listener, provided it has the correct return type and parameters. This doesn't provide any additional functionality, but it is more convenient. 0 You need to create an instance of the class which defines the actionPerformed method for the button, and it is this instance that becomes the button listener.

Listeners(cont)
Common Listener Strategies - Here are common ways to write listeners: 0 Named Inner Class Listeners are one of the most common ways to write small programs. They are convenient to write and be shared with several components. 0 Anonymous Inner Class Listeners are sometimes used to associate a different listener with each button or other control. This is a little quicker to write, but lacks some of the flexibility of inner class listeners. 0 Top-level Listeners (this) are commonly used where there is only one source of an event. For example, if you are defining a subclass of JPanel to use for drawing with a mouse, an instance of this new class will typically also be the mouse event listener. Similarly with a JPanel used for animation -- the panel itself may serve as the ActionListener for the Timer. Do not use "this" as a listener for buttons, menus, etc. because all controls must then share that one action listener.

Listeners(cont)
Common Listener Strategies(cont) 0 Action and AbstractAction objects are action listeners. In some ways they are more powerful than other action listener strategies in that they can easily be used to enable or disable multiple controls. An action object can be shared with many controls; eg, the same action is sometimes accomplished with a menu item and a button or toolbar tool. They encapsulate the name, description, enabled status, listener, and icon information. This is a good choice for large interfaces, and quite compatible with the MVC pattern (see below). 0 External Listeners - To implement the Model-View-Controller pattern, all listeners will effectively be in the Controller module. There are a number of ways to split the controller actions from the View part of the interface. 0 Subclassing a component and overriding processActionEvent(). This peculiar scheme certainly isn't general, and I've never seen it done in a serious program. Do not do this.

Inner-class Listeners(cont)
0 Defining an inner class listener to handle events is a very popular

style. Access. Use an inner class rather than an outer class to access instance variables of the enclosing class. In the example below, the myGreetingField can be referenced by the listener class. Because simple program listeners typically get or set values of other widgets in the interface, it is very convenient to use an inner class. Reuse. Unlike anonymous inner class listeners, it's easy to reuse the same listener for more than one control, eg, the click of a button might perform the same action as the equivalent menu item, and might be the same as hitting the enter key in a text field. Organization. It's easier to group all the listeners together with inner classes than with anonymous inner class listeners.

0 Examples: Partial source code to share one inner class listener

Inner-class Listeners(cont)

import javax.swing.*; import java.awt.event.*; class SomePanel extends JPanel { private JButton myGreetingButton = new JButton("Hello"); private JTextField myGreetingField = new JTextField(20); public SomePanel() { //=== Constructor ActionListener doGreeting = new GreetingListener(); myGreetingButton.addActionListener(doGreeting); myGreetingField.addActionListener(doGreeting); // . . . Layout the panel. } /////////////////////////// Define inner class as listener. private class GreetingListener implements ActionListener { public void actionPerformed(ActionEvent e) { myGreetingField.setText("Guten Tag"); } } }

Inner-class Listeners(cont)
JTextField inField = new JTextField(10); ... // Create an action listener that adds the key name to a field ActionListener keyIn = new ActionListener() { public void actionPerformed(ActionEvent e) { // Get the name of the button String keyNum = e.getActionCommand(); // "1", "2", ... inField.setText(inField.getText() + keyNum); } }; // Create many buttons with the same listener JButton key1 = new JButton("1"); key1.addActionListener(keyIn); JButton key2 = new JButton("2"); key2.addActionListener(keyIn); JButton key3 = new JButton("3"); key3.addActionListener(keyIn); ...

Inner-class Listeners(cont)
public class InnerDemo extends JFrame { JButton but = new JButton("click here"); //constructor public InnerDemo(){ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); ActionListener actLis = new NewActLis(); but.addActionListener(actLis); add(but); pack(); setVisible(true); } public static void main(String[] a){ InnerDemo inner = new InnerDemo(); } public class NewActLis implements ActionListener{ public void actionPerformed(ActionEvent a){ JOptionPane.showMessageDialog(null, "You clicked!"); } } }

When clicked :-

Inner-class Listeners(cont)
public class Trials { static JButton b = new JButton("Click me"); public static void main(String[] a){ JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Trials t = new Trials(); b.addActionListener(t.new MyListener()); f.add(b); f.pack(); f.setVisible(true); } public class MyListener implements ActionListener{ public void actionPerformed(ActionEvent e){ JOptionPane.showMessageDialog(null, You clicked "); } }

When clicked :-

Anonymous Listeners
A common idiom 0 There is no need to define a named class simply to add a listener object to a button. Java has a somewhat obscure syntax for creating an anonymous innner class listener that implements an interface. For example, class myPanel extends JPanel { ... public MyPanel() { ... //in the constructor JButton b1 = new JButton("Hello"); b1.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { // do something for button b1 } } );

Anonymous Listeners
Eg: public class AnnoDemo { public static void main(String[] a){ JButton but = new JButton("Press Me"); but.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ev) { JOptionPane.showMessageDialog(null, "You pressed me"); System.out.println(Button's clicked dude!"); } }); JFrame f = new JFrame(); When clicked :f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.getContentPane().add(but); f.pack(); f.setVisible(true); } Consol Output } Buttons clicked

Eg: static JTextField tf = new JTextField(12); static int count = 0; public static void main(String[] args) { JButton but = new JButton("Press Me"); but.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ev) { count++; tf.setText("clicked " + count); } }); JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel p = new JPanel(); p.setLayout(new FlowLayout()); p.add(but); p.add(tf); f.add(p); f.pack(); f.setVisible(true); } //end of main

Anonymous Listeners

Top-level Listeners
Using this as a listener
0 A common way to write simple applets is to use the applet itself as a

listener (referred to as this). For example 0 This doesn't seem to be a problem for small programs, but what happens if there is more than one button? There can be only one actionPerformed() method in a class.

public class TopLevelDemo extends JFrame implements ActionListener { JButton but = new JButton("click here"); //constructor public TopLevelDemo (){ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); but.addActionListener(this); // add(but); pack(); setVisible(true); } When clicked :public void actionPerformed(ActionEvent a){ JOptionPane.showMessageDialog(null, "You clicked!"); } public static void main(String[] a){ TopLevelDemo n = new TopLevelDemo (); } }

Top-level Listeners(cont)

Problem: One listener for many components 0 Inside the listener method, it's possible to check the parameter to find out which component caused the event. For example, JButton b1, b2; public void actionPerformed(ActionEvent e) { Object obj = e.getSource(); // get the control that ... //caused the event public MyClass() { if (obj instanceof JButton) {// make sure it's a button. // constructor JButton b = (JButton)obj; // downcast to a button ... if (b == b1) { // UGLY, DON'T DO THIS b1.addActionListener(this); // do something for button b1 ... } else if (b == b2) { b2.addActionListener(this); // do something for button b2 // SAME listener! } ... } else if (o instanceof JTextField) { }//end constructor
... ...

Top-level Listeners(cont)

public class NewClass extends JFrame implements ActionListener { JButton but1 = new JButton("click here 1"); JButton but2 = new JButton("click here 2"); //constructor public NewClass(){ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel p = new JPanel(); but1.addActionListener(this); p.add(but1); but2.addActionListener(this); p.add(but2); add(p); pack(); setVisible(true); } Cont

Top-level Listeners(cont)

public void actionPerformed(ActionEvent a){ String whichButton = a.getActionCommand(); JOptionPane.showMessageDialog(null, "You clicked! & the button is :" + whichButton); } public static void main(String[] a){ NewClass n = new NewClass(); } }//end of class

Top-level Listeners(cont)

public class NewClass extends JFrame implements ActionListener { JButton but1 = new JButton("click here 1"); JButton but2 = new JButton("click here 2"); //constructor public NewClass(){ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel p = new JPanel(); but1.addActionListener(this); p.add(but1); but2.addActionListener(this); p.add(but2); add(p); pack(); setVisible(true); } Cont

Top-level Listeners(cont)

public void actionPerformed(ActionEvent a){ Object obj = a.getSource(); if(obj instanceof JButton){ JButton bChecker = (JButton)obj; if(bChecker == but1){ JOptionPane.showMessageDialog(null, "You clicked But 1" ); //do what you want when but 1 is clicked } else{ JOptionPane.showMessageDialog(null, "You clicked But 2" ); //do what you want when but 2 is clicked } } } public static void main(String[] a){ NewClass n = new NewClass(); } }//end of class

Top-level Listeners(cont)

Top-level Listeners(cont)

Top-level Listeners(cont)
0 Using one listener makes the response slower, and forces all events to

be handled in the same place. This uses the event model which was introduced in Java 1.1, but it has all the problems of the old Java 1.0 event model. Although you will see this style used in some Java books, don't use it. It doesn't scale up from one control to many. Buttons, menu items, toolbar items, etc use action listeners; imagine what this method would look like for Microsoft Word! 0 Grouping all separate action listeners together in the source code is a good idea to make the code more comprehensible, but don't try to put all processing in one method!

Action, AbstractAction
0 The javax.swing.Action interface, and the corresponding

class, javax.swing.AbstractAction, provide a useful mechanism to implement action listeners that can be shared and coordinated. Actions can be used with most buttons, including toobox buttons and menu items, text fields, etc. They can be shared with all controls which do the same thing. Actions can be dis-/enabled, and they will then dis-/enable all corresponding controls. They can specify text, icons, tooltip text, accelerator, and mnemonic keys. 0 Subclassing. You must subclass AbstractAction (the hint is the word "abstract" in the class name). The minimum you need to do is override actionPerformed(...) to specify what you want the Action to do. See examples below.

Action, AbstractAction(cont)
Constructors for abstract classes? 0 At first it seems impossible that there should be a constructor for an abstract class because it's not possible to actually create an object of an abstract class type. The Java syntax for anonymous classes allows an abstract class's constructor to be called if it is followed by the body for the anonymous class. See Example - Simple anonymous class below.

AbstractAction constructors, methods, and fields


Constructors act = new AbstractAction(String name) {...}

Action, AbstractAction(cont)
Specifies name for button, etc. Must defineactionPerformed(...) in body.

act = new AbstractAction(String name, Icon smallIcon) Specifies name and an icon (eg, that {...}; will appear on a toolbar buttons). Must define actionPerformed(...) in body.
Some Methods b = act.isEnabled() act.setEnabled(boolean enabled) act.putValue(String key, Objectvalue) obj = act.getValue(String key) Returns true if this Action is enabled. Sets the status of this Action. Sets the value of property key to value. Gets the value of property key.

Some Property Fields (use putValue() to explicitly set these fields)

ACCELERATOR_KEY
MNEMONIC_KEY NAME SHORT_DESCRIPTION SMALL_ICON

Accelerator key.
Mnemonic key. Name for buttons and menu items. Used as tooltip text. Used for toolbars.

Action, AbstractAction(cont) Usage


0 Actions can be used directly in the add() method of some containers (eg, menus

and toolbars), or in constructors for buttons and menu items. fileMenu.add(exitAction); // Add directly to menu. Uses Action's text, icon. 0 If you don't want all the functionality of an Action, create the desired component from the Action, then modify it. JMenuItem exitItem = new JMenuItem(exitAction); // Use to create component. exitItem.setIcon(null); // Modify to suppress the icon. fileMenu.add(exitItem); Example - Simple anonymous class Action openAction = new AbstractAction("Open...") { public void actionPerformed(ActionEvent e) { openFile(); // Do what you want here. } }; ... fileMenu.add(openAction); // Add action to menu

Eg public class ActionDemo extends JFrame{ private Action _openAction = new OpenActionClass(); //ActionDemo constructor public ActionDemo(){ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JMenuBar _menuBar = new JMenuBar(); JMenu _menuFile = new JMenu("File"); _menuFile.setMnemonic('F'); _menuFile.add(_openAction); // Note use of actions, not text. //you can add another menu items here _menuBar.add(_menuFile); setJMenuBar(_menuBar); pack(); setVisible(true); } cont.

Action, AbstractAction(cont)

Eg //..cont public static void main(String[] a){ ActionDemo actionDemo = new ActionDemo(); } public class OpenActionClass extends AbstractAction{ //constructor public OpenActionClass(){ super("Open..."); putValue(MNEMONIC_KEY, new Integer('O')); } //actionPerformed public void actionPerformed(ActionEvent a){ JOptionPane.showMessageDialog(null, "Here you can do something!"); } } }

Action, AbstractAction(cont)

Action, AbstractAction(cont)
Output :

When clicked :-

public class JRadioButtonAction implements ActionListener { ButtonGroup myGroup = null; JLabel myLebal = null;

getSelection() method of ButtonGroup class.

public void createFrame() { JFrame f = new JFrame("My Radio Buttons"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Container c = f.getContentPane(); c.setLayout(new BoxLayout(c,BoxLayout.Y_AXIS)); myGroup = new ButtonGroup(); JPanel p = new JPanel(); p.setLayout(new GridLayout(3,1)); addOption(p,myGroup,"Red"); addOption(p,myGroup,"Green"); addOption(p,myGroup,"Blue"); c.add(p); JButton b = new JButton("Select"); b.addActionListener(this); c.add(b); myLebal = new JLabel("Please select", SwingConstants.CENTER); c.add(myLebal); f.pack(); f.setVisible(true); } ///cont..

getSelection() method of ButtonGroup class.


//..cont public void addOption(JPanel p, ButtonGroup g, String t) { JRadioButton b = new JRadioButton(t); b.setActionCommand(t); p.add(b); g.add(b); } public void actionPerformed(ActionEvent e) { ButtonModel b = myGroup.getSelection(); String t = "Not selected"; if (b!=null) t = b.getActionCommand(); myLebal.setText(t); } public static void main(String[] a) { JRadioButtonAction myTest = new JRadioButtonAction(); myTest.createFrame(); } }

Click after selecting one of the radio buttons.

ActionListener, ChangeListener and ItemListener public class JRadioButtonTest {


public static void main(String[] a) { JFrame f = new JFrame("My Radio Buttons"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); ButtonGroup g = new ButtonGroup(); MyRadioButton b1 = new MyRadioButton("On"); g.add(b1); f.getContentPane().add(b1,BorderLayout.NORTH); MyRadioButton b2 = new MyRadioButton("Off"); g.add(b2); f.getContentPane().add(b2,BorderLayout.SOUTH); f.pack(); f.setVisible(true); } private static class MyRadioButton extends JRadioButton implements ActionListener, ChangeListener, ItemListener { static int count = 0; String text = null; public MyRadioButton(String t) { super(t); text = t; addActionListener(this); addChangeListener(this); addItemListener(this); } //cont..

ActionListener, ChangeListener and ItemListener //cont


public void actionPerformed(ActionEvent e) { count++; System.out.println(count+": Action performed - "+text); } public void stateChanged(ChangeEvent e) { count++; System.out.println(count+": State changed on - "+text); } public void itemStateChanged(ItemEvent e) { count++; System.out.println(count+": Item state changed - "+text); } } } If you press the "On" button and hold it, you will see 2 messages showing in command window. If you release the "On" button, you will see 5 more messages. If you continue to press the "Off" button and hold it, you will see 2 more messages. If you release the "Off" button, you will see 7 more messages. Here is the list of all the messages:

ActionListener, ChangeListener and ItemListener 1: State changed on - On


2: State changed on - On - "On" pressed 3: State changed on - On 4: Item state changed - On 5: State changed on - On 6: Action performed - On 7: State changed on - On - "On" released 8: State changed on - Off 9: State changed on - Off - "Off" pressed 10: State changed on - On 11: Item state changed - On 12: State changed on - Off 13: Item state changed - Off 14: State changed on - Off 15: Action performed - Off 16: State changed on - Off - "Off" released

0 Action event raised only once when you release a button. 0 Change event (stateChanged method call) is raised 2 times when you press a button; and

raised 2 time again when you release a button. This tells us that a button has more than 2 states: selected and deselected. 0 Item event (itemStateChanged method call) is raised only once when you release a button. 0 In a button group, if one button is selected, other selected buttons will be deselected. Events #10 and #11 show that when "Off" is selected, "On" is deselected.

Button Action Handler at the Component Level


public class JButtonAction1 { public static void main(String[] a) { JFrame f = new JFrame("My Switch Button"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JButton b = new MyButton(); f.getContentPane().add(b); f.pack(); f.setVisible(true); } private static class MyButton extends JButton implements ActionListener { String text = "On"; public MyButton() { super(); setText(text); addActionListener(this); } public void actionPerformed(ActionEvent e) { if (text.equals("On")) text = "Off"; else The button works well. If you click text = "On"; the button, the button label text setText(text); will change from "On" to "Off"; and } } from "Off" to "On", if you click it } again.

public class JButtonAction2 implements ActionListener { JButton myButton = null; JLabel myLebal = null; String text = null; public void createFrame() { JFrame f = new JFrame("My Switch Button"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Container c = f.getContentPane(); c.setLayout(new GridLayout(2,1)); text = "On"; myButton = new JButton(text); myButton.addActionListener(this); c.add(myButton); myLebal = new JLabel(text,SwingConstants.CENTER); c.add(myLebal); f.pack(); f.setVisible(true); The button works nicely. If you } click the button, the button label text will change from "On" to "Off", //cont. and the text of the label component will also change.

Button Action Handler at the Frame Level

Button Action Handler at the Frame Level


//.cont public static void main(String[] a) { JButtonAction2 myTest = new JButtonAction2(); myTest.createFrame(); } public void actionPerformed(ActionEvent e) { if (text.equals("On")) text = "Off"; else text = "On"; myButton.setText(text); myLebal.setText(text); } } The button works nicely. If you click the button, the button label text will change from "On" to "Off", and the text of the label component will also change.

Mouse Events
Overview 0 The mouse listeners allow you to receive events to process: Button clicks, presses, or releases by the left, middle, or right buttons. Moves and drags. Which Modifier keys (shift, control, alt) were down when the event occurred. Notification when the mouse enters or exits the component. Scroll wheel movements.

Mouse Events(cont)
Overview 0 Normally handled for you. The mouse is handled automatically by most components, so you never have to know about it. For example, if someone clicks on a button (JButton), the JButton translates that click into an ActionEvent, which is a higher level event that can be caused by a number of things. You don't need to know (and shouldn't care) whether the ActionEvent was from a mouse click on the button, or from a keyboard shortcut, or hitting enter while that button had focus, or .... 0 Sometimes used with graphics. If you are drawing your own graphics (eg, on a JComponent or JPanel) and need to know where the user clicks, then you need to know about mouse events. You can easily add a mouse listener to a JComponent or JPanel.

Mouse Events(cont)
MouseEvent A MouseEvent object is passed to all mouse listeners. The most useful information in a MouseEvent is the x and y coordinates of the mouse cursor.

MouseListener
MouseMotionListener

Interface for mouse presses, releases, clicks, enters, and exits.


Interface for mouse moves and drags.

MouseInputListener

Interface combination of MouseListener and MouseMotionListener.


Class useful for writing anonymous listener for mouse button presses, entering, ... Class useful for writing anonymous listener for mouse movement. Object passed to mouseWheelMoved. Subclass of MouseEvent. Interface to handle wheel movements. Write mouseWheelMoved(MouseWheelEvent we)

Adapter classes - You only have to override the methods you need. MouseAdapter MouseMotionAdapter Handling the mouse wheel. MouseWheelEvent MouseWheelListener

MouseListener
0 This type of mouse listener is for events which typically don't

happen very often -- a mouse button is pressed, released, or the mouse enters or leaves the area of the component with a listener. Here are the actions that a MouseListener catches.
one of the mouse buttons is pressed. one of the mouse buttons is released. a mouse button was pressed and released without moving the mouse. This is perhaps the most commonly used.

press release click enter exit

mouse cursor enters the component. Often used to change cursor.


mouse cursor exits the component. Often used to restore cursor.

0 To listen for these events you will use addMouseListener.

Event Adapters
0 Some listener interfaces contain more than one method. For

example, the MouseListener interface contains five methods: mousePressed, mouseReleased, mouseEntered, mouseExited, and mouseClicked. Even if you care only about mouse clicks, if your class directly implements MouseListener, then you must implement all five MouseListener methods. Methods for those events you do not care about can have empty bodies. Here is an example:

Event Adapters(cont)
//An example that implements a listener interface directly. public class MyClass implements MouseListener { ... someObject.addMouseListener(this); ... /* Empty method definition. */ public void mousePressed(MouseEvent e) { } /* Empty method definition. */ public void mouseReleased(MouseEvent e) { } /* Empty method definition. */ public void mouseEntered(MouseEvent e) { } /* Empty method definition. */ public void mouseExited(MouseEvent e) { } public void mouseClicked(MouseEvent e) { ...//Event listener implementation goes here... } }

Event Adapters(cont)
0 The resulting collection of empty method bodies can make code

harder to read and maintain. To help you avoid implementing empty method bodies, the API generally includes an adapter class for each listener interface with more than one method. (The Listener API Table lists all the listeners and their adapters.) For example, the MouseAdapter class implements the MouseListener interface. An adapter class implements empty versions of all its interface's methods. 0 To use an adapter, you create a subclass of it and override only the methods of interest, rather than directly implementing all methods of the listener interface. Here is an example of modifying the preceding code to extend MouseAdapter. By extending MouseAdapter, it inherits empty definitions of all five of the methods that MouseListener contains.

Event Adapters(cont)
/* * An example of extending an adapter class instead of * directly implementing a listener interface. */ public class MyClass extends MouseAdapter { ... someObject.addMouseListener(this); ... public void mouseClicked(MouseEvent e) { ...//Event listener implementation goes here... } }

public class JButtonAction3 extends MouseAdapter { JButton myButton = null; JLabel myLebal = null; String text = null; public void createFrame() { JFrame f = new JFrame("My Switch Button"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Container c = f.getContentPane(); c.setLayout(new GridLayout(2,1)); text = "On"; myButton = new JButton(text); myButton.addMouseListener(this); c.add(myButton); myLebal = new JLabel(text, SwingConstants.CENTER); c.add(myLebal); f.pack(); f.setVisible(true); The button works nicely. If you } click the button, the button label text will change from "On" to "Off", //cont and the text of the label component will also change.

Mouse Click Handler at the Frame Level

//cont public static void main(String[] a) { JButtonAction3 myTest = new JButtonAction3(); myTest.createFrame(); } public void mouseClicked(MouseEvent e) { if (text.equals("On")) text = "Off"; else text = "On"; myButton.setText(text); myLebal.setText(text); } }

Mouse Click Handler at the Frame Level

The button works nicely. If you click the button, the button label text will change from "On" to "Off", and the text of the label component will also change.

Keyboard
0 Not normally used. You don't normally need to capture the low-level

keyboard events because components (eg, JTextField) handle them for you. One of the few cases where you might want to handle them is in a subclass of JPanel that is being used for graphics where key strokes need to be interpreted, eg, to move an image, fill in a crossword cell, etc. 0 There are three types of characters, each of which is handled differently, although they all generated pressed and released events. 1. Characters (a, A, #, ...) - handled in the keyTyped() listener. 2. Virtual keys (arrow keys, function keys, etc) - handled with keyPressed() listener. 3. Modifier keys (shift, alt, control, ...) - Usually their status (up/down) is tested by calls in one of the other listeners, rather than in keyPressed(). 0 Warning: This was written for Java 1.2. In more recent versions (1.3+) javax.swing.InputMap should be used in preference to KeyListener for getting characters.

Keyboard(cont)
Listener Classes and Interfaces 0 The java.awt.event.KeyListener interface and java.awt.event.KeyEventclass are all imported by: import java.awt.event.*; KeyTyped() versus KeyPressed() and KeyReleased() Three methods must be defined in a class that implements KeyListener:
0 keyTyped(KeyEvent e)The KeyTyped() listener method is called when a

character is typed, but is not useful for virtual keys (arrow keys, function keys, etc). Modifier key (shift, control, etc) status (up/down) can be tested with method calls in the listener.

Keyboard(cont)
KeyTyped() versus KeyPressed() and KeyReleased() 0 keyPressed(KeyEvent e) and keyReleased(KeyEvent e)These methods are called whenever any key is pressed or released. Regular character keys also produce calls to these listeners, but are usually handled by the keyTyped() listener and may be ignored in this listener. Modifier keys (shift, control) also generate calls to these listeners, but are typically tested with method calls in the listener. For example, if you type an uppercase 'J', there are five events, which call these methods: 0 KeyPressed for pressing the shift key. 0 KeyPressed for pressing the j key. 0 KeyTyped for the character J. 0 KeyReleased for releasing the j key. 0 KeyReleased for releasing the shift key.

Keyboard(cont)
Focus - Which component gets KeyEvents? -- The one with Focus 0 The key listener for your JPanel is called only if the JPanel has focus. Only one component has focus at a time, not all components can get focus, and key events are directed to the component with focus. Make your panel focusable, then request focus. 0 Not all components can get focus, eg labels do not get focus. To ensure that your JPanel subclass can get focus, call setFocusable() in the constructor this.setFocusable(true); // In panel constructor. 0 After you have build the graphical user interface, give the panel p focus with: p.requestFocus() 0 ;When your window is active, all key events will be given to the listeners for your panel p.

Keyboard(cont)
Example - Key listeners in a JPanel subclass You can place a key listener in your JPanel subclass. For example
class MyPanel extends JPanel implements KeyListener { ... //=================================== constructor public MyPanel() { this.setFocusable(true); // Allow this panel to get focus. this.addKeyListener(this); // listen to our own key events. ... } //-- Define one or more of these to handle keyboard events public void keyPressed(KeyEvent e) {. . .} public void keyReleased(KeyEvent e){. . .} public void keyTyped(KeyEvent e) {. . .} }

Keyboard(cont)
Virtual Keys
0 Many keys do not generate characters, for example, the shift, arrow, or

function keys. These keys generate avirtual key code that you can check in the keyPressed() (but not keyTyped()) listener. 0 Use keyPressed(...) or keyReleased(...), not keyTyped(...) 0 There is no character for many keys, so youcan not use the KeyTyped() listener method. You must write the KeyPressed(...) or KeyReleased(...)listener methods to find out when these keys are used.

Keyboard(cont)
Virtual Keys
To get the virtual key code Use the KeyEvent.getKeyCode() method to get the virtual key code. For example,
public void keyPressed(KeyEvent ke) { switch (ke.getKeyCode()) { case KeyEvent.VK_LEFT: // move x coordinate left x -= dx; x = Math.max(x, 0); break; case KeyEvent.VK_RIGHT: // move x coordinate right x += dx; x = Math.min(x, 100); } drawing.repaint(); }

Keyboard(cont)
Virtual Key Codes 0 The KeyEvent class defines a large number of virtual key codes that correspond keys on the keyboard. This list may expand as new keyboards are supported. See the java.awt.event.KeyEvent documentation for a list of these. Below are some of the most common codes. You can probably figure out the key from the name.
0 Alphanumeric keys

0 VK_0, VK_1, ..., VK_9, VK_A, VK_B, ..., VK_Z


0 Control keys 0 VK_ENTER, VK_BACKSPACE, VK_TAB, VK_ESCAPE 0 Function keys 0 VK_F1, VK_F2, VK_F3, VK_F4 VK_F5, VK_F6, VK_F7, VK_F8, VK_F9, VK_F10, VK_F11, VK_F12, VK_SCROLL_LOCK, VK_PRINTSCREEN, VK_PAUSE, VK_DELETE, VK_INSERT, VK_PAGE_UP, VK_PAGE_DOWN, VK_HOME, VK_END

0 Arrow keys - VK_LEFT, VK_RIGHT, VK_UP, VK_DOWN

Keyboard(cont)
Testing Modifier Keys
0 Certain keys are used as modifier keys to change another action. For example,

holding the ALT key down while clicking on the mouse may alter the action you want to perform. The event object has methods which may be called to find the status (up/down) for these modifier keys. MouseEvent and KeyEvent are both subsets of java.awt.event.InputEvent, so either can use these methods for determining which modifier keys are pressed. Testing Modifier Keys from an Event Object 0 The following methods are available for KeyEvent and MouseEvent objects (e), and would normally be used inside of a mouse or key listener.

Keyboard(cont)
e.isAltDown() e.isControlDown() e.isShiftDown()

true if the ALT key was down when this event happened.
true if the CTRL key was down when this event happened. true if the SHIFT key was down when this event happened. true if the META key was down when this event happened.

e.isMetaDown()
e.isAltGraphDown() e.getModifiers()

true if the ALT-GRAPH key was down when this event happened.
This method returns an int bit mask which identifies the keys and mouse buttons which are down at the time of the event. Many constants are defined to test these. Some of the more common are: InputEvent.ALT_MASK InputEvent.CTRL_MASK InputEvent.SHIFT_MASK InputEvent.ALT_GRAPH_MASK InputEvent.META_MASK InputEvent.BUTTON1_MASK ALT key is down. CTRL key is down. SHIFT key is down. ALT-GRAPH key is down. META key is down. Mouse button 1 is down.

InputEvent.BUTTON2_MASK
InputEvent.BUTTON3_MASK

Mouse button 2 is down.


Mouse button 3 is down.

Font
0 The java.awt.Font class is used to create Font objects to set the

font for drawing text, labels, text fields, buttons, etc. Generic Font Names 0 There are three logical/generic font names. Java will select a font in the system that matches the general characteristics of the logical font.
serif sansserif monospaced This text is in a serif font. Often used for blocks of text (eg, Times). This text is in a SansSerif font. Often used for titles (eg, Arial or Helvetica). This text is in a Monospaced font, often used for computer text (eg, Courier).

0 You can also get a list of the system fonts on the host computer.

See below.

Font(cont)
Constructor
Font f = new Font(name, style, size);
String name "serif" "sansserif" "monospaced" or a system font. int style Font.PLAIN Font.BOLD Font.ITALIC Font.BOLD+Font.ITALIC int size Integer point size -- typically in range 10-48.

Example JButton b = new JButton("OK"); b.setFont(new Font("sansserif", Font.BOLD, 32));

Font(cont)
Available system fonts 0 For maximum portability, use the generic font names, but you can use any font installed in the system. It is suggested to use a font family name, and create the font from that, but you can also use the fonts directly. You can get an array of all available font family names or all fonts. // Font info is obtained from the current graphics environment.
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); //--- Get an array of font names (smaller than the number of fonts) String[] fontNames = ge.getAvailableFontFamilyNames(); //--- Get an array of fonts. It's preferable to use the names above. Font[] allFonts = ge.getAllFonts();

Font(cont)
Using Fonts for Graphics Font f; f = new Font(String name, int style, int size); // creates a new font
0 name is "Serif", "SansSerif", or "Monospaced", or a font on the system.style is

Font.PLAIN. Font.BOLD, Font.ITALIC, or Font.BOLD+Font.ITALIC.size is the point size, typically in the range 8-48.

Example Font big = new Font("SansSerif", Font.Bold, 48); ... g.setFont(big); g.drawString("Greetings Earthling");

Font(cont)
Using Fonts for Graphics Font f; f = new Font(String name, int style, int size); // creates a new font
0 name is "Serif", "SansSerif", or "Monospaced", or a font on the system.style is

Font.PLAIN. Font.BOLD, Font.ITALIC, or Font.BOLD+Font.ITALIC.size is the point size, typically in the range 8-48.

Example Font big = new Font("SansSerif", Font.Bold, 48); ... g.setFont(big); g.drawString("Greetings Earthling");

Font(cont)
Unicode fonts 0 If you're running a recent version of Windows, you probably already have a Unicode font installed, Arial Unicode MS, which is a very extensive Unicode font. If you're not running windows, you can get a the Bitstream Cyberbit font, which is quite complete (about 30,000 characters), but lacks a few of the the lesser used characters (eg, Old Cyrillic). 0 Windows installation instructions: 1. Download from ftp://ftp.netscape.com/pub/communicator/extras/fonts/windows/Cyberb it.ZIP [6.3MB Zipped]. It's also available other places on the Internet. It was originally written by Bitstream, but they no longer offer it for free download. 2. Unzip into a temporary directory. 3. Start the Fonts control panel, and add Bitstream Cyberbit font from that directory.

Look and Feel


0 Look and Feel is the term for the general appearance of GUI

components. Java allows you to change it. 0 System vs portable L&F. The default L&F is the Java portable look and feel. A popular choice is to use the current system look and feel (eg, Windows or Macintosh). 0 Non-standard. You can use independent L&Fs to give the user a particular experience. See below. 0 Start of main(). If you set the look and feel, put it as the first thing in main().

Look and Feel


Default cross-platform Look and Feel 0 Java cross-platform Look & Feel is the default, so you don't have to set it. This is the most portable.

Look and Feel


System Look and Feel 0 Some think the user experience is better when a program matches the system L&F, eg, on Windows the program has a Windows L&F (as in the example below), on the Macintosh it will use the standard Macintosh L&F. The only change to the code that produced the sample above was to set the L&F. The components have a different shape, size, and appearance.

Look and Feel


System Look and Feel 0 Here's how to use the System L&F. Be sure it's the first thing in main.
public static void main(String[] args) { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); // or // UIManager.setLookAndFeel(new MetalLookAndFeel()); //or // UIManager.setLookAndFeel(new MotifLookAndFeel()); //or // UIManager.setLookAndFeel(new NimbusLookAndFeel()); //or // UIManager.setLookAndFeel(new WindowsClassicLookAndFeel()); } catch (Exception unused) { ; // Ignore exception because we can't do anything. Will use default. } ...

Look and Feel


Where to find and how to install other Look and Feels 0 Finding. You can use Google to find L&Fs, but www.javootoo.com is a good place to start. It has samples and links to a number of free and for-pay custom L&Fs. 0 Installing other L&Fs is done by putting the .jar file (eg, napkinlaf.jar) in the CLASSPATH, and make the appropriate call as above. 0 NetBeans installation is relatively easily done by a right-click on the project, selecting Properties, click on Libraries and then Add JAR/Folder and select the L&F .jar file. Examples of other L&Fs 0 Alpha software. The Napkin L&F makes software look like it's under construction, which prevents a slick looking interface from making your customer think the program is almost finished. 0 After downloading the appropriate .jar file and making sure it's in the classpath, set it as follows.

Look and Feel


Where to find and how to install other Look and Feels
public static void main(String[] args) { try { UIManager.setLookAndFeel(new net.sourceforge.napkinlaf.NapkinLookAndFeel()); } catch (Exception unused) { ; // Ignore exception because we can't do anything. Will use default. } ...

Summary Swing Components


Basic Controls

Summary Swing Components


Basic Controls

Summary Swing Components


Interactive Displays of Highly Formatted Information
0 These components display highly formatted information that (if you

choose) can be modified by the user.

Summary Swing Components


Interactive Displays of Highly Formatted Information

Summary Swing Components


Interactive Displays of Highly Formatted Information

Summary Swing Components


Uneditable Information Displays
0 These components exist solely to give the user information.

Summary Swing Components


Top-Level Containers
0 At least one of these components must be present in any Swing

application.

Summary Swing Components


General-Purpose Containers
0 These general-purpose containers are used in most Swing applications.

Summary Swing Components


Special-Purpose Containers
0 These special-purpose containers play specific roles in the UI.

Summary Swing Components


Special-Purpose Containers
0 These special-purpose containers play specific roles in the UI.