The AWT Components
So far I've emphasized more concepts than pragmatic programming. You've become familiar with the concepts and ideas upon which Java GUI programming, and the Swing architecture in particular, are built.
At this point, you know how to organize a GUI program and get it to display. The example GUI screens did not have much on them, however. It's now time to introduce some actual components--real widgets--that you can use to build more functional GUIs.
This chapter introduces the AWT component set. You will look at the basic visual components, how to construct them and add them to a GUI, and how to use their basic features. It is still possible to build complete GUI applications using only the original AWT components. Therefore, it is useful to examine the contents of the AWT package.
This chapter is presented to aid those who must still build Java GUI programs using only the AWT components and not Swing's new lightweight components. However, you are strongly encouraged to use the new lightweight components if you are starting fresh.
The Personal Java platform for embedded programming does not support Swing so you need to use the AWT for that environment.
The AWT Components
The AWT components are defined in the java.awt package. Table 2.2 lists the AWT components defined in the java.awt package. By now you know that this package is part of the JFC since the JDK 1.1 release. All AWT components are JFC components. However, they are implemented as heavyweight components. Each AWT component instance creates a corresponding native platform peer object.
Components appear on the GUI display, so users can interact with them. User actions such as clicking a button, scrolling a scrollbar, typing in a text field, and so on generate events. Even though events are related to components, I do not cover events or how to handle them in this chapter. I devote Chapter 9, "Events and Event Handling," to this topic.
Without further ado, let's look at the basic AWT components.
Buttons
Buttons are simple components that can be clicked. A button can be created with a text label. In Chapter 9, you'll see that clicking a button creates an event to which your program can respond.
Listing 5.1 shows the source code that displays the GUI shown in Figure 5.1. Figure 5.1 shows three buttons with different visual states that represent the different possible visual states of all AWT buttons.
Notice that this application creates its third button with no label, but sets the label with the setLabel() method. There is also a complementary getLabel() method defined in the Button class.
Listing 5.1 The Different Possible States of a Button
import java.awt.Button; import java.awt.Component; import java.awt.Font; import java.awt.Frame; import java.awt.Panel; public class Buttons extends Panel { /** No-arg constructor. Builds the entire visible GUI before it returns. */ public Buttons() { Font f18 = new Font("SansSerif", Font.PLAIN, 18); Button b1 = new Button("Enabled button"); Button b2 = new Button("Disabled button"); Button b3 = new Button(); b3.setLabel("Depressed button"); b1.setFont(f18); // The second button is initially disabled. // b2.setFont(f18); b2.setEnabled(false); b3.setFont(f18); add(b1); add(b2); add(b3); } public static void main(String [] args) { Buttons app = new Buttons(); Frame f = new Frame("Buttons"); f.add(app); f.pack(); f.setVisible(true); } }
FIGURE 5.1
Buttons are rendered differently depending on their state.
Table 5.1 lists the methods in the Button class that pertain to manipulating the button.
Table 5.1 Button Constructors and Methods
Button Methods and Constructors | Description |
Button() | No-arg constructor. Creates a button with no label. |
Button(String label) | Constructor. Creates a button with the specified label. |
String getLabel() | Gets this button's label. |
void setLabel (String label) | Sets this button's label. |
Also note that you did not have to set the visibility of your buttons so that they would appear on screen. Back in Chapter 3, you had to call setVisible(true) and pack() on your frames so that the application would appear on screen. To set a component's visibility to true means that the component should be visible when its parent is visible.
You only have to set visibility for top-level components such as frames. Other components, such as the ones I discuss in this chapter, are visible by default. They will appear on screen when their parent is made visible.
When a component is enabled, it can accept events. In Figure 5.1, the disabled button cannot accept events because it has been disabled.
Check Boxes
A check box is a component that can be either on or off, that is, either selected or not. You toggle a check box's state by clicking on it. Listing 5.2 shows how you can add some check boxes to a panel, and initialize them to be selected or not.
Listing 5.2 Standalone Check Boxes and Grouped Checkboxes
import java.awt.Checkbox; import java.awt.CheckboxGroup; import java.awt.Font; import java.awt.Frame; import java.awt.GridLayout; import java.awt.Panel; public class Checkboxes extends Panel { /** No-arg constructor. Builds the complete visible GUI before it returns. */ public Checkboxes() { setLayout(new GridLayout(2, 3)); Font f18 = new Font("SansSerif", Font.PLAIN, 18); Font f14 = new Font("SansSerif", Font.PLAIN, 14); Checkbox c1 = new Checkbox("Checkbox 1"); Checkbox c2 = new Checkbox(); c2.setLabel("Checkbox 2"); c2.setEnabled(false); Checkbox c3 = new Checkbox("Checkbox 3"); // Create a CheckboxGroup object to manage the states of // the second row of check boxes. // CheckboxGroup group = new CheckboxGroup(); Checkbox c4 = new Checkbox("Checkbox 4", group, true); Checkbox c5 = new Checkbox("Checkbox 5", group, true); Checkbox c6 = new Checkbox("Checkbox 6", group, true); // Make the text more readable. // c1.setFont(f18); c2.setFont(f18); c3.setFont(f18); c4.setFont(f18); c5.setFont(f18); c6.setFont(f18); add(c1); add(c2); add(c3); add(c4); add(c5); add(c6); } public static void main(String [] args) { Checkboxes app = new Checkboxes(); Frame f = new Frame("Checkboxes"); f.add(app); f.pack(); f.setVisible(true); } }
Figure 5.2 shows what this program's GUI looks like. The first row contains three check boxes that exist independently of each other. Any combination of them can be selected. The example shows numbers one and three selected, while number two is disabled.
The three checkboxes in the second row are part of a CheckboxGroup. You can see from Listing 5.2 that we added all of them to the group in their enabled state. CheckboxGroup objects are not visible; they serve only an organizational role. In the AWT, a group of check boxes can only have one member selected at any given time.
Also notice that the glyph for the two types of check boxes are different. The independent check boxes have square glyphs, whereas the check boxes that are part of a group have diamond shaped glyphs. This helps you determine their organization and membership.
The actual glyphs used may vary from platform to platform. It is the native peer which dictates the actual look of an AWT component. For example, Windows does not use the diamond glyph to display check boxes.
FIGURE 5.2
Check boxes can be organized in groups that allow only one to be selected at once.
Table 5.2 shows the methods in the Checkbox class.
Table 5.2 Checkbox Constructors and Methods
Checkbox Methods and Constructors | Description |
Checkbox() | No-arg constructor. Constructs a check box with no label. |
Checkbox(String label) | Constructs a check box with this label. |
Checkbox(String label, boolean state) | Constructs a check box with this label and the specified enabled/disabled state. |
Checkbox(String label, boolean state, label CheckboxGroup group) | Constructs a check box with this and the specified enabled/disabled state, and belonging to the check box group. |
Checkbox(String label, boolean state) | Constructs a check box with this label, CheckboxGroup group, and the specified enabled/disabled state, and belonging to the check box group. |
CheckboxGroup getCheckboxGroup() | Gets the group to which this check box belongs. |
String getLabel() | Gets this check box's label. |
Object [] getSelectedObjects() | Gets an array containing the label of this check box's label, or null if it's not selected. |
boolean getState() | Gets the enabled/disabled state. |
void setCheckboxGroup (ChecboxGroup g) | Sets the group to which this check box belongs. |
void setLabel(String label) | Sets the label for this check box. |
void setState(boolean state) | Sets the enabled/disabled state. |
Choices
The Choice class gives you a way to create a pop-up menu of selections. A choice component looks somewhat like a button, but has a distinctive face. Clicking on a choice component drops down a type of menu (in appearance, but not the same as a real menu). You can select one of the elements in the choice object.
Listing 5.3 shows code that builds such a choice component and Figure 5.3 shows what a choice component looks like. Figure 5.4 shows the choice element when it is expanded.
Listing 5.3 Constructing a Choice Component and Adding Elements to It
import java.awt.Choice; import java.awt.Dimension; import java.awt.Font; import java.awt.Frame; import java.awt.GridLayout; import java.awt.Panel; public class Choices extends Panel { public Choices() { Font f18 = new Font("SansSerif", Font.PLAIN, 18); Font f14 = new Font("SansSerif", Font.PLAIN, 14); // Create a choice object and add the string items to it. // Choice c = new Choice(); c.addItem(new String("Albinoni")); c.addItem(new String("Bach")); c.addItem(new String("Beethoven")); c.addItem(new String("Brahms")); c.addItem(new String("Chopin")); c.addItem(new String("Debussey")); c.addItem(new String("Gluck")); c.addItem(new String("Kachaturian")); c.addItem(new String("Mahler")); c.setFont(f18); add; } public Dimension getPreferredSize() { return new Dimension(175, 300); } public static void main(String [] args) { Choices app = new Choices(); Frame f = new Frame("Choices"); f.add(app); f.pack(); f.setVisible(true); } }
FIGURE 5.3
Choice components let you choose one of a list of choices.
FIGURE 5.4
A choice component after the user has clicked on it.
Table 5.3 shows the constructor and methods of the Choice class.
Table 5.3 Choice Class Constructors and Methods
Choice Methods and Constructors | Description |
Choice() | No-arg constructor. |
void add(String item) | Adds an item to this check box. |
void addItem(String item) | Adds an item to this check box. |
String getItem(int index) | Gets the name of the item at the specified index. |
int getItemCount() | Gets the number of items in this choice. |
int getSelectedIndex() | Gets the index of the selected item. |
int getSelectedItem() | Gets the name of the selected item. |
Object [] | Gets an array of length one that contains the selected item. |
void insert(String item, int index) | Inserts a new item with the string name indicated at the specified index. |
void select(int pos) | Selects the item in the indicated position. |
void select(String str) | Sets the selected choice item to be the one whose name matches the string. |
Dialogs
So far the components you've seen have been direct subclasses of java.awt.Component. Dialogs, however, are direct subclasses of java.awt.Window. A dialog is a window that can be displayed independently of the main window of your application. Dialogs, like frames, have a border and menu bar.
There are some differences between dialogs and frames. Each dialog must have an associated frame, which is its owner. For instance, the main frame of your application might be the owner of any dialog it pops up.
If the associated frame is made into an icon or terminated, any associated dialogs will disappear from the screen. Redisplaying (restoring) the main window will also redisplay any dialogs that were open when the window was minimized.
Dialogs can be modal, which means that the user must dismiss the displayed dialog before interacting with any other part of the application that owns the dialog. Typically, a dialog will have a do and cancel button or equivalents.
Listing 5.4 shows a dialog box in action. Clicking on the button in the main frame of the application will bring up a dialog box. Notice that a reference to the main application frame is passed to the Dialog constructor, specifying the dialog's owner.
Don't worry about any event handling code in this application that looks foreign right now. You will learn about event handling in Chapter 9.
Listing 5.4 Creating a Dialog From a Parent Frame
import java.awt.BorderLayout; import java.awt.Button; import java.awt.Dialog; import java.awt.FlowLayout; import java.awt.Font; import java.awt.Frame; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.Label; import java.awt.Panel; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; /** Defines a simple frame. The dialog created by this example must have an associated frame. An instance of this class provides that frame. <p> We don't need to specify a getPreferredSize() method because we are adding a button to the frame. The size required by the button will be the minimum size allocated for the frame. */ public class DialogExample extends Frame implements ActionListener { /** Constructor. Creates an instance of a frame with a button. Pressing the button brings up a dialog. @param title the title of the frame, not the dialog. */ public DialogExample(String title) { super(title); Font f18 = new Font("SansSerif", Font.PLAIN, 18); Font f14 = new Font("SansSerif", Font.PLAIN, 14); Button b = new Button("Bring up dialog"); b.setFont(f18); b.addActionListener(this); Panel p = new Panel(); p.add; add(p); } public void actionPerformed(ActionEvent e) { d = new CustomDialog(this, "Make a decision", true); d.setVisible(true); } public static void main(String [] args) { DialogExample app = new DialogExample("Dialog Example"); app.pack(); app.setVisible(true); } Dialog d; } /** Creates a dialog box. Dialog boxes must be associated with a frame. */ class CustomDialog extends Dialog { /** Constructor. Builds a dialog box. A reference to a frame is required to create a dialog. @param parent the associated parent frame of this dialog. @param title this dialog's title. @param modal the behavior of the dialog. <code>true</code> means modal, otherwise it's non-modal. */ CustomDialog(Frame parent, String title, boolean modal) { super(parent, title, modal); Panel p1 = new Panel(new FlowLayout(FlowLayout.LEFT)); Label question = new Label("And now what?"); question.setFont(new Font("SansSerif", Font.PLAIN, 18)); p1.add(question); add(p1, BorderLayout.CENTER); Panel p2 = new Panel(new FlowLayout(FlowLayout.RIGHT)); dontknow = new Button("Don't know"); dontknow.setFont(new Font("SansSerif", Font.PLAIN, 18)); cancel = new Button("Cancel"); cancel.setFont(new Font("SansSerif", Font.PLAIN, 18)); p2.add(dontknow); p2.add(cancel); add(p2, BorderLayout.SOUTH); pack(); } Button dontknow; Button cancel; }
Figure 5.5 displays the main frame and the dialog box that appears after clicking the frame's button. Table 5.4 lists the methods of the Dialog class.
FIGURE 5.5
Dialogs appear in their own native platform frame.
Table 5.4 Dialog Class Constructors and Methods
Dialog Constructor or Method Name | Description |
Dialog(Dialog owner) | Constructs a dialog with another dialog as its owner. |
Dialog(Dialog owner, String title) | Constructs a dialog with the specified title and the dialog as its owner. |
Dialog(Dialog owner, String title, boolean modal) | Constructs a dialog with the specified modal behavior and name, and the specified dialog as its owner. |
Dialog(Frame owner) | Constructs a dialog with the specified frame as its owner. |
Dialog(Frame owner, boolean modal) | Constructs a dialog with the specified frame as its owner and the given modal behavior. |
Dialog(Frame owner, String title) | Constructs a dialog with the frame as owner and the specified title. |
Dialog(Frame owner, String title, boolean modal) | Constructs a dialog with the specified modal behavior and title, and the specified frame as its owner. |
String getTitle() | Gets the dialog's title. |
boolean isModal() | Indicates if this dialog is modal. |
boolean isResizable() | Indicates if this dialog is resizable. |
void setModal(boolean modal) | Sets the dialog's modal behavior as specified. |
void setResizable (boolean resizable) | Sets the dialog's resizing behavior as specified. |
void setTitle(String title) | Sets the dialogs title. |
void show() | Must be called to make the dialog visible. |
Labels
Labels are components that contain a simple text string that can appear in a container. Labels are not selectable like the text in text fields or text areas, which I will introduce in the following section. However, because labels are bona fide components, they can be placed in containers like any other component.
You can set the lateral alignment of a label's text to specify that it be anchored at the left, center or right of the area allocated for the label's layout. The valid values for specifying the label's anchor position are the constants Label.LEFT, Label.CENTER, or Label.RIGHT.
Listing 5.5 shows the source code for the program that creates Figure 5.6. Figure 5.6 shows the GUI produced by the program in Listing 5.5. The left column labels are right justified and the right column labels are left justified. The position of the label text doesn't represent the extend of the area allocated for the label component. Most likely, the bounds of the label extends beyond the left edge of the text for right-justified text, and beyond the right edge for left-justified text.
Listing 5.5 Program That Demonstrates Labels With Different Alignments
import java.awt.Choice; import java.awt.Font; import java.awt.Frame; import java.awt.GridLayout; import java.awt.Label; import java.awt.Panel; /** Creates a panel of labels with various alignments. No getPreferredSize() method is needed. The layout manager will call the inherited version. The size of the panel will be at least the size required to lay out all of the labels that are children of the panel. */ public class Labels extends Panel { /** No-arg constructor. */ public Labels() { Font f18 = new Font("SansSerif", Font.PLAIN, 18); Font f14 = new Font("SansSerif", Font.PLAIN, 14); // This label's text is aligned to the right edge of its // display area. Label name = new Label("Name : "); name.setAlignment(Label.RIGHT); name.setFont(f14); // This label's text is aligned to the left edge of its // display area. Label nameVal = new Label("Jim Morrison"); nameVal.setAlignment(Label.LEFT); nameVal.setFont(f14); Label address = new Label("Address : "); address.setAlignment(Label.RIGHT); address.setFont(f14); Label addVal = new Label("Cimetiere Pere LaChese"); addVal.setAlignment(Label.LEFT); addVal.setFont(f14); Label city = new Label("City/State/Zip : "); city.setAlignment(Label.RIGHT); city.setFont(f14); Label cityVal = new Label("Paris, France Cedex 01432"); cityVal.setAlignment(Label.LEFT); cityVal.setFont(f14); Label phone = new Label("Phone : "); phone.setAlignment(Label.RIGHT); phone.setFont(f14); Label phoneVal = new Label("213-555-1212"); phoneVal.setAlignment(Label.LEFT); phoneVal.setFont(f14); Panel p = new Panel(); p.setLayout(new GridLayout(0, 2)); p.add(name); p.add(nameVal); p.add(address); p.add(addVal); p.add(city); p.add(cityVal); p.add(phone); p.add(phoneVal); add(p); } public static void main(String [] args) { Labels app = new Labels(); Frame f = new Frame("Labels"); f.add(app); f.pack(); f.setVisible(true); } } Label name = new Label("Name : "); name.setAlignment(Label.RIGHT); Label nameVal = new Label("Jim Morrison"); nameVal.setAlignment(Label.LEFT); Label address = new Label("Address : "); address.setAlignment(Label.RIGHT); Label addVal = new Label("Cimetiere Pere LaChese"); addVal.setAlignment(Label.LEFT); Label city = new Label("City/State/Zip : "); city.setAlignment(Label.RIGHT); Label cityVal = new Label("Paris, France Cedex 01432"); cityVal.setAlignment(Label.LEFT); Label phone = new Label("Phone : "); phone.setAlignment(Label.RIGHT); Label phoneVal = new Label("213-555-1212"); phoneVal.setAlignment(Label.LEFT); Panel p = new Panel(); p.setLayout(new GridLayout(0, 2)); p.add(name); p.add(nameVal); p.add(address); p.add(addVal); p.add(city); p.add(cityVal); p.add(phone); p.add(phoneVal); add(p);
FIGURE 5.6
Labels are simple components that display a string of text. They can be manipulated just like other components.
Table 5.5 shows the constructors and methods of the Label class.
Table 5.5 Dialog Class Constructors and Methods
Label Constructor or Method Name | Description |
Label() | Constructs an empty label. |
Label(String text) | Constructs a label with the specified text. |
Label(String text, int alignment) | Constructs a label with the specified text and alignment. |
int getAlignment() | Gets the label's alignment. |
String getText() | Gets the label's text. |
void setAlignment(int alignment) | Sets the label's alignment |
void setText(String text) | Sets the label's text. |
Lists
Lists are groups of items that are formatted inside of a kind of scrolling pane. The list can be scrolled up and down in order to see all its elements. The list gives you a window in which to view some subset of the list elements.
Lists can be single selection or multiple selection, which means, respectively, that only one, or multiple items can be selected simultaneously. Selected elements can be retrieved from a list component and used for various purposes by your application.
Listing 5.6 shows a program that creates a list in a container. Don't worry about any code that looks unfamiliar; I will get to it soon enough.
The GUI created by this program is shown in Figure 5.7. The left-hand list of Figure 5.7 uses a single selection model, while the right-hand list uses a multiple selection model.
Listing 5.6 Program That Demonstrates Single and Multiple Selection Lists
import java.awt.Choice; import java.awt.Font; import java.awt.Frame; import java.awt.GridLayout; import java.awt.GridBagLayout; import java.awt.GridBagConstraints; import java.awt.Insets; import java.awt.Label; import java.awt.List; import java.awt.Panel; /** A class that creates two juxtaposed lists. The left-hand list only supports the selection of a single item. The right-hand list supports the selection of multiple items. Again, no getPreferredSize() method is needed. */ public class Lists extends Panel { /** No-arg constructor. */ public Lists() { Font f18 = new Font("SansSerif", Font.PLAIN, 18); Font f14 = new Font("SansSerif", Font.PLAIN, 14); Label single = new Label("A single selection list"); single.setFont(f14); // The single selection list. // List singleList = new List(6, false); singleList.setFont(f14); singleList.add(new String("Ludwig von Beethoven")); singleList.add(new String("Lee Ritenaur")); singleList.add(new String("Thelonious Monk")); singleList.add(new String("Elton John")); singleList.add(new String("Julio Eglesias")); singleList.add(new String("Benny Goodman")); Label multiple = new Label("A multiple selection list"); multiple.setFont(f14); // The multiple selection list. // List multipleList = new List(6); multipleList.setMultipleMode(true); multipleList.setFont(f14); multipleList.add(new String("Classical")); multipleList.add(new String("Pop")); multipleList.add(new String("Rock")); multipleList.add(new String("Swing")); multipleList.add(new String("Jazz")); GridBagLayout gbl = new GridBagLayout(); GridBagConstraints gbc = new GridBagConstraints(); setLayout(gbl); gbl.setConstraints(single, gbc); add(single); gbc.insets = new Insets(5, 5, 5, 5); gbc.gridx = GridBagConstraints.RELATIVE; gbl.setConstraints(multiple, gbc); add(multiple); gbc.gridx = 0; gbc.gridy = GridBagConstraints.RELATIVE; gbl.setConstraints(singleList, gbc); add(singleList); gbc.gridx = GridBagConstraints.RELATIVE; gbc.gridy = 1; gbl.setConstraints(multipleList, gbc); add(multipleList); } public static void main(String [] args) { Lists app = new Lists(); Frame f = new Frame("Lists"); f.add(app); f.pack(); f.setVisible(true); } } Label single = new Label("A single selection list"); single.setFont(f14); List singleList = new List(6, false); singleList.setFont(f14); singleList.add(new String("Ludwig von Beethoven")); singleList.add(new String("Lee Ritenaur")); singleList.add(new String("Thelonious Monk")); singleList.add(new String("Elton John")); singleList.add(new String("Julio Eglesias")); singleList.add(new String("Benny Goodman")); Label multiple = new Label("A multiple selection list"); multiple.setFont(f14); List multipleList = new List(6); multipleList.setMultipleMode(true); multipleList.setFont(f14); multipleList.add(new String("Classical")); multipleList.add(new String("Pop")); multipleList.add(new String("Rock")); multipleList.add(new String("Swing")); multipleList.add(new String("Jazz")); GridBagLayout gbl = new GridBagLayout(); GridBagConstraints gbc = new GridBagConstraints(); setLayout(gbl); gbl.setConstraints(single, gbc); add(single); gbc.insets = new Insets(5, 5, 5, 5); gbc.gridx = GridBagConstraints.RELATIVE; gbl.setConstraints(multiple, gbc); add(multiple); gbc.gridx = 0; gbc.gridy = GridBagConstraints.RELATIVE; gbl.setConstraints(singleList, gbc); add(singleList); gbc.gridx = GridBagConstraints.RELATIVE; gbc.gridy = 1; gbl.setConstraints(multipleList, gbc); add(multipleList); }
Figure 5.7 shows an example of a list.
FIGURE 5.7
Lists give you a way to aggregate strings. They can support both single and multiple selection behavior.
Table 5.6 lists most of the methods in the List class. Again, I omit methods related to event handling at this time.
Table 5.6 List Constructors and Methods
List Constructor or Method Name | Description |
List() | Creates a new scrolling list. |
List(int rows) | Creates a new list with the number of visible rows specified. |
List(int rows, boolean multipleMode) | Creates a new list with the number of visible rows and the specified selection mode behavior. |
void add(String item) | Adds a new item to the list. |
void add(String item, int index) | Adds a new item at the specified position. |
void addItem(Sring item) | Adds a new item to the list. |
void addItem(String item, int index) | Adds a new item at the specified position. |
void deselect(int index) | Deselects the item at the specified index. |
String getItem(int index) | Gets the item at the specified index. |
int getItemCount() | Gets the number of elements in the list |
String [] getItems() | Gets an array of the element names. |
int getRows() | Gets the number of lines that are currently visible. |
int getSelectedIndex() | Gets the index of the selected item. |
int [] getSelectedIndexes() | Gets a list of items that are all selected. |
String getSelectedItem() | Gets the string that represents the text of the selected item. |
String [] getSelectedItems() | Gets a list of the strings that represent the selected items. |
Object [] getSelectedObjects() | Gets a list of selected strings as Objects. |
int getVisibleIndex() | Gets the index of the item that was last made visible by the makeVisible() method. |
boolean isIndexSelected (int index) | Indicates if the specified index represents a selected element. |
boolean isMultipleMode() | Indicates if multiple elements can be simultaneously selected. |
void makeVisible(int index) | Makes the item at the specified index visible. |
void remove(int position) | Removes the item at the specified position. |
void remove(String item) | Removes the first occurrence of the item that matches the string. |
void removeAll() | Removes all items from this list. |
void replaceItem(String newValue, int index) | Replaces the item at the specified position with the new item. |
void select(int index) | Selects the item at the specified position. |
void setMultipleMode (boolean b) | Makes this list use a multiple selection policy. |
Menus
Menus are elements that are included as members of menu bars. A menu bar can be placed on a frame. The frame manages its location and layout.
Menus display a list of member menu items when clicked. Selecting the menu item usually results in some action performed by the application. These components behave as their counterparts in other window programming environments.
Menus contain menu items. These two elements are defined by the Menu and MenuItem classes. Menu bars are defined by the MenuBar class.
Menu items can be either simple labels, separators--simply horizontal lines that separate menu items--or other menus. Listing 5.7 shows the program that creates some menus on a menu bar. The menu bar is attached to a frame. The GUI is shown in Figure 5.8.
You can see examples of all the types of menu items, simple labels, separators, and other menus that produce walking menus.
Listing 5.7 Program Which Demonstrates How to Use Menus and Menu Items
FIGURE 5.8
Menus can contain menu items, which include other menus. This allows menus to be organized in a cascading or walking menu structure.
The program that displays this frame and its menus is shown in Listing 5.7.
In this example, I created three menus and added some menu items to the help menu. The help menu contains another menu, which contains additional menu items.
The capability for menus to contain other menus allows you to create walking or cascading menus. In order for this to be possible, menus must be a type of menu item. The relationship between the Menu and MenuItem classes makes this possible. This relationship follows a pattern that you've seen before. The relationship between the Component and Container classes is conceptually the same.
NOTE: Notice the similarity between the relationship shared by the Menu and MenuItem classes, and the relationship shared by the Component and Container classes. Both relationships exhibit the same pattern, namely, one that defines a recursive structure.In fact, this pattern has been given the name Composite in a popular text that identifies and names patterns that occur commonly in object-oriented design and programming. See Gamma, E. et al, Design Patterns, Addison-Wesley, C. 1995.
Chapter 10, "The Swing Model Architecture," will discuss how to recognize patterns by identifying the underlying abstraction.
Figure 5.9 shows the UML static class diagram for the relationship between the Menu and MenuItem classes.
FIGURE 5.9
Menus are menu items, allowing menus to include other menus as their items.
From Figure 5.9 you can see that menus and menu items are somewhat different from other components. Technically, they are not components because they do not extend the Component class. Yet, effectively, they are components in terms of their behavior.
Notice in Figure 5.9 the MenuComponent class. Its presence defines both menus and menu items to be a type of menu component. This class defines attributes and behavior common to all types of menu components.
The reason that the menu classes don't belong to the normal component hierarchy is that they cannot always be treated as true components. For instance, you cannot add a menu to an arbitrary container in your program. So, even though they appear to function like components, they are different in some important ways. In Chapter 7, "The Swing Components," you will see that menus are defined much more flexibly in Swing.
CAUTION: Beware that the model for menus and menu items changes in Swing. You should anticipate this if you plan to program in AWT now but later convert your program to use Swing menu components.
Unlike the AWT menu components, Swing menu components are true components. This makes it much more flexible for you to use them in more places within your GUI.
Table 5.7 lists the constructors and methods of the Menu class.
Table 5.7 The Menu Class Constructors and Methods
Menu Constructor or Method Name | Description |
Menu() | Creates a menu. |
Menu(String label) | Creates a menu with the specified name. |
Menu(String label, boolean tearOff) | Creates a tear-off menu with the specified name. |
void add(MenuItem mi) | Adds a menu item to this menu. |
void add(String label) | Adds a simple menu item with the specified label to this menu. |
void addSeparator() | Adds a horizontal line separator as a menu item. |
int getItem(int index) | Gets the menu item with the specified name. |
int getItemCount() | Gets the number of items in this menu. |
void insert(MenuItem, | Inserts the specified menu item in |
int index) | the indicated position. |
void insert(String label, | Inserts a new menu item with the |
int index) | given label in the indicated |
position. | |
void insertSeparator(int index) | Inserts a separator at the specified position. |
boolean isTearOff() | Indicates if this menu is capable of being "torn-off", that is, displayed in a separate frame. |
void remove(int index) | Removes the menu item at the indicated position from this menu. |
void remove (MenuComponent item) | Removes the specified menu item from this menu. |
void removeAll() | Removes all menu items from this menu. |
Menus support adding, removing, and inserting menu items that include other menus and separators that help make the menus more readable. You can define a menu to be a "tear-off" menu, which means it will be rendered in a window detached from the frame that contains the menu bar to which the menu belongs.
Table 5.8 lists the constructors and methods of the MenuItem class.
Table 5.8 The MenuItem Class Constructors and Methods
MenuItem Constructor or Method Name | Description |
MenuItem() | Constructs a new menu item. |
MenuItem(String label) | Constructs a new menu item with the specified label. |
MenuItem(String label, MenuShortcut s) | Constructs a new menu item with the specified label and shortcut. |
void deleteShortcut() | Deletes the short cut item associated with this menu item. |
String getActionCommand() | Gets this menu item's string that represents a command name. |
String getLabel() | Gets this menu item's text label. |
MenuShortcut getShortcut() | Gets the menu short cut item associated with this menu item. |
boolean isEnabled() | Indicates if this menu item is enabled. |
void setActionCommand (String command) | Sets the action command string for this menu item. |
void setEnabled() | Enables this menu item. |
void setLabel(String label) | Sets this menu item's text label to the specified string. |
void setShortcut (MenuShortcut s) | Sets the short cut for this menu item. |
Most of the behavior that you will use is defined in the Menu and MenuItem classes. However, the MenuComponent class defines the common behavior for all menu related types, including MenuBars.
Table 5.9 lists the constructors and methods of the MenuComponent class.
Table 5.9 The MenuComponent Class Constructors and Methods
MenuComponent Constructor or Method | Description |
MenuComponent() | Constructor. |
Font getFont() | Gets the font used for this menu component's text. |
String getName() | Gets the name of this menu component. |
void setFont() | Sets the font used for this menu component's text. |
void setName (String name) | Sets the name of this menu component. |
The MenuComponent class is abstract, so you can't instantiate it. It's purpose is to define common attributes and methods related to all menu classes. From Figure 5.9, you can see that Menus, MenuItems, and MenuBars are all subclasses of MenuComponent.
From Table 5.10, and from the source code in Listing 5.7, you can see that help menus are treated differently from other menus. The MenuBar class interprets a help menu as the menu to be placed to the far right side of the menu bar. You need to specify such a menu by using the setHelpMenu() method. Simply adding menus by using the add() method will add the menus from left to right, always starting at the left hand side, and treat them like regular menus.
Table 5.10 The MenuBar Class Constructors and Methods
MenuBar Constructor or Method Name | Description |
MenuBar() | Creates a new menu bar. |
Menu add(Menu m) | Adds the specified menu to this menu bar. |
int deleteShortcut(MenuShortcut s) | Deletes the specified shortcut. |
Menu getHelpMenu() | Gets the Help menu from this menu bar. |
Menu getMenu(int i) | Gets the menu at the specified index on this menu bar. |
int getMenuCount() | Gets the number of menus on this menu bar. |
MenuItem getShortcut MenuItem()(MenuShortcut s) | Gets the menu item identified by the specified menu short cut. |
void remove(int index) | Removes the menu at the specified index. |
void remove (MenuComponent c) | Removes the specified menu component from this menu bar. |
void setHelpMenu(Menu m) | Adds the specified menu as this menu bar's Help menu. |
Enumeration shortcuts() | Gets all the short cuts for this menu bar. |
Text Areas and Text Fields
Text components are components that store and display text which can be selected and altered. Text components support a number of features including text insertion, editing, selection, and deletion.
The text component classes are subclasses of the TextComponent class, which defines attributes and behavior that is applicable to all text components. The TextComponent class supports text selection, caret positioning, text setting, and toggling of the component's editable state because these features are common to both text fields and text areas.
The AWT defines two types of text components. A text area is a multi-line, multicolumn component that supports typing in its display area. Text fields are similar except that they support only one line of text. Because these two types are so closely related, I will discuss them together.
The TextField and TextArea classes define an echo character. An echo character can be specified as the one that is echoed when the user types in the text field or text area. This is useful for fields such as password fields that want to hide the user's key strokes. For example, a password field could set the echo character to a space or asterisk.
Listing 5.8 shows a program that creates a container that includes various text components. Figure 5.10 shows some text fields and a text area created by the program in Listing 5-8.
Notice in Figure 5.10 that the name text field is gray instead of white like the others. The program disables this field. When a field is not editable, the peer component changes the color to gray. This behavior, of course, is dictated by the peer class and not by the text field. Another peer implementation could define a different policy for representing disabled fields. Text areas work the same way incidentally.
Listing 5.8 Program Which Demonstrates Use of the Different Text Component Classes
FIGURE 5.10
Text areas and text fields are text components that support a variety of text entry and editing functions.
From Tables 5.11-5.13, you can see which classes define which methods.
Table 5.11 shows the constructors and methods of the TextComponent class. You can tell that these methods do represent functions that are common to both TextArea and TextField objects.
Table 5.11 The TextComponent Class Constructors and Methods
TextComponent Constructor or Method Name | Description |
int getCaretPosition() | Gets the position of the text insertion caret for this component. |
String getSelectedText() | Gets the text that is currently selected in this component. |
int getSelectedEnd() | Gets the position that marks the beginning of the selected text. |
int getSelectedStart() | Gets the position that marks the end of the selected text. |
String getText() | Gets all the text in this text component. |
boolean isEditable() | Indicates if editing is currently allowed on this text component. |
void select(int selectionStart, int selectionEnd) | Marks as selected the text region indicated by the specified begin and end marks. |
void selectAll() | Marks all text in this component as selected. |
void setCaretPosition (int position) | Sets the caret to be at the specified position. |
void setEditable (boolean b) | Sets this text component to be editable or not. |
void setSelectedEnd (int selectionEnd) | Marks the end of the selected region for this text component. |
void setSelectedStart (int selectionStart) | Marks the beginning of the selected region for this text component. |
void setText(String t) | Sets the text that is presented by this text component. |
Among other things, the TextField and TextArea classes must present methods to set and get their minimum and preferred sizes, based on the number of columns for text areas, and the number of rows and columns for text fields. This behavior is specific to each type of component and is, therefore, overridden from the TextComponent class.
Table 5.12 The TextArea Class Constructors and Methods
TextArea Constructor or Method Name | Description |
TextArea() | Constructs a new text area. |
TextArea(int rows, int columns) | Constructs a new text area with the specified number of rows and columns. |
TextArea(String text) | Constructs a new text area with the specified initial text. |
TextArea(String text, int rows, int columns) | Constructs a new text area with the specified initial text, and the specified rows and columns. |
TextArea(String text, int rows, int columns, int scrollbars) | Constructs a new text area with the specified initial text, the specified number of rows and columns, and the specified policy for displaying scrollbars. |
void append(String str) | Appends the specified text to the contained text of this text area. |
int getColumns() | Gets the number of columns of this text area. |
Dimension getMinimumSize() | Determines the minimum size of this text area. |
Dimension getMinimumSize | Determines the minimum size of an |
(int rows, int columns) | area with the specified number of |
rows and columns. | |
Dimension | Determines the preferred size of |
getPreferredSize() | this text area. |
Dimension getPreferredSize | Determines the preferred size of a |
(int rows, int columns) | text area with the specified number |
of rows and columns. | |
int getRows() | Gets the number of rows in this text area. |
int getScrollbar Visibility() | Gets a value that determines which scrollbars this text area uses. |
void insert(String str, | Inserts the specified text starting at the indicated position in this text area. |
void replaceRange(String str, int start, int end) | Replaces with the specified string the range of text indicated by the start and end positions in this text area. |
void setColumns(int columns) | Sets the number of columns for this text area. |
void setRows(int rows) | Sets the number of rows for this text area. |
Table 5.13 The TextField Class Constructors and Methods
TextField Constructor or Method Name | Description |
TextField() | Constructs a new text field. |
TextField(int columns) | Constructs a new text field with the specified number of columns. |
TextField(String text) | Constructs a new text field that initializes the specified text. |
TextField(String text, int columns) | Constructs a new text field with the initial text and the number of columns specified. |
boolean echoCharIsSet() | Indicates if this text field has an echo character that is currently set. |
int getColumns() | Gets the number of columns of this text field. |
char getEchoChar() | Gets the echo character currently set on this text area. |
Dimension getMinimumSize() | Gets the minimum dimension for this text field. |
Dimension getMinimumSize (int columns) | Gets the minimum dimension for this text field with the specified number of columns. |
Dimension getPreferredSize() | Gets the preferred size of this text field. |
Dimension getPreferredSize(int columns) | Gets the preferred size of a text field with the specified number of columns. |
void setColumns(int columns) | Sets the number of columns for thistext field. |
void setEchoChar(char c) | Sets the echo character to be used by this text field. |
void setText(String t) | Sets the text presented by this text field to the specified string. |
Summary
The java.awt package contains the AWT component classes. Many of these have visual representations and define standard metaphors such as buttons, lists, text fields, and so on.
All the AWT components have heavyweight implementations, which means each instance creates a native peer window object.
You can use these components to build GUI applications. Components can be organized in a variety of configurations to meet the needs of each application. Additional containers like Panels can be used to nest components so that it becomes easier for you to organize and manage the components in your GUI.
Although you can write non-trivial applications using only the AWT components, you are encouraged to use the Swing set of visual components instead. Chapter 7 introduces the Swing components.
Before you look at the Swing components, you need to understand the concepts that surround the Swing component set. The Swing components introduce some new abstractions not found in the AWT components. Therefore, the next chapter introduces the concepts that surround Swing. You will then be ready to tackle the Swing components.