1. Understanding Swing Components

    Computer programs usually are more user friendly (and more fun to use) when they contain graphical user interface (GUI) components. GUI components are buttons, text fields, and other components with which the user can interact. Java contains several sets of prewritten GUI components. These include: • The Abstract Windows Toolkit (AWT), whose components are older and not as portable as the newer frameworks • Swing, whose components are newer than those included in the AWT and are still used in many programming environments • JavaFX, which is even newer, and which is the focus of Chapter 15. In the AWT, the components have simple names, such as Frame and Button. When Java’s creators designed new, improved classes, they needed new names for the classes, so they used a J in front of each new class name. Hence, Swing components have names such as JFrame and JButton. In the AWT, the components have simple names, such as Frame and Button. When Java’s creators designed new, improved classes, they needed new names for the classes, so they used a J in front of each new class name. Hence, Swing components have names such as JFrame and JButton. GUI components are also called controls or widgets. Each Swing component is a descendant of JComponent, which in turn inherits from the java.awt.Container class. You can insert the statement import javax.swing.*; at the beginning of your Java program files so you can take advantage of all the Swing GUI components and their methods. The x in javax originally stood for extension, so named because the Swing classes were an extension of the original Java language specifications. When you use Swing components, you usually place them in containers. A container is a type of component that holds other components so that you can treat a group of them as a single entity. Containers are defined in the Container class. Often, a container takes the form of a window that you can drag, resize, minimize, restore, and close. As you know from reading about inheritance in Chapters 10 and 11, all Java classes descend from the Object class. The Component class is a child of the Object class, and the Container class is a child of the Component class. Therefore, every Container object “is a” Component, and every Component object (including every Container) “is an” Object. The Container class is also a parent class, and the Window class is a child of Container. A window is a rectangular container that can hold GUI controls. However, Java programmers often prefer to create a frame instead of a window. A frame is a window that has a title bar and border. In Java, Frame is a child of Window, and JFrame is the Swing object that is a child of Frame.
  2. Using the JFrame Class

    You usually create a JFrame so that you can place other objects within it for display. Figure 14-1 shows the JFrame’s inheritance tree. Recall that the Object class is defined in the java.lang package, which is imported automatically every time you write a Java program. However, Object’s descendants (shown in Figure) are not imported automatically.
    java.lang.Object | +--java.awt.Component | +--java.awt.Container | +--java.awt.Window | +--java.awt.Frame | +--javax.swing.JFrame The JFrame class has four constructors: • JFrame() constructs a new frame that initially is invisible and has no title. • JFrame(String title) creates a new, initially invisible JFrame with the specified title. • JFrame(GraphicsConfiguration gc) creates a JFrame in the specified GraphicsConfiguration of a screen device with a blank title. (You will learn about the GraphicsConfiguration class as you continue to study Java.) • JFrame(String title, GraphicsConfiguration gc) creates a JFrame with the specified title and the specified GraphicsConfiguration of a screen. You can construct a JFrame as you do other objects, using the class name, an identifier, the assignment operator, the new operator, and a constructor call. For example, the following two statements construct two JFrames: one with the title Hello and another with no title: JFrame firstFrame = new JFrame("Hello"); JFrame secondFrame = new JFrame(); After you create a JFrame object, you can use the now-familiar object-dot-method format you have used with other objects to call methods that manipulate a JFrame’s features. Table describes some useful JFrame class methods.
    MethodPurpose
    void setTitle(String)Sets a JFrame’s title using the String argument
    void setSize(int, int)Sets a JFrame’s size in pixels with the width and height as arguments
    void setSize(Dimension)Sets a JFrame’s size using a Dimension class object; the Dimension(int, int) constructor creates an object that represents both a width and a height
    String getTitle()Returns a JFrame’s title
    void setResizable(boolean)Sets the JFrame to be resizable by passing true to the method, or sets the JFrame not to be resizable by passing false to the method
    boolean isResizable()Returns true or false to indicate whether the JFrame is resizable
    void setVisible(boolean)Sets a JFrame to be visible using the boolean argument true and invisible using the boolean argument false
    void setBounds(int, int, int, int)Overrides the default behavior for the JFrame to be positioned in the upper-left corner of the computer screen’s desktop; the first two arguments are the horizontal and vertical positions of the JFrame’s upper-left corner on the desktop, and the final two arguments set the width and height
    import javax.swing.*; public class JFrame1 { public static void main(String[] args) { JFrame aFrame = new JFrame("First frame"); aFrame.setSize(250, 100); aFrame.setVisible(true); } }
    When a user closes a JFrame by clicking the Close button in the upper-right corner, the default behavior is for the JFrame to be hidden and for the application to keep running. This makes sense when there are other tasks for the program to complete after the main frame is closed—for example, displaying additional frames, closing open data files, or printing an activity report. To change this behavior, you can call a JFrame’s setDefaultCloseOperation() method and use one of the following four values as an argument: • JFrame.EXIT_ON_CLOSE exits the program when the JFrame is closed. • WindowConstants.DISPOSE_ON_CLOSE closes the frame, disposes of the JFrame object, and keeps running the application. • WindowConstants.DO_NOTHING_ON_CLOSE keeps the JFrame and continues running. In other words, it disables the Close button. • WindowConstants.HIDE_ON_CLOSE closes the JFrame and continues running; this is the default operation that you frequently want to override.
    Customizing a JFrame’s Appearance
    The appearance of the JFrame is provided by the operating system in which the program is running (in this case, Windows). For example, the coffee-cup icon in the frame’s title bar and the Minimize, Restore, and Close buttons look and act as they do in other Windows applications. The icon and buttons are known as window decorations. By default, window decorations are supplied by the operating system; however, you can request that Java’s look and feel provide different decorations for a frame. Look and feel comprises the elements of design, style, and functionality in any user interface. Optionally, you can set a JFrame’s look and feel using the setDefaultLookAndFeelDecorated() method. For example, Figure shows an application that calls this method.
    import javax.swing.*; public class JFrame2 { public static void main(String[] args) { JFrame.setDefaultLookAndFeelDecorated(true); JFrame aFrame = new JFrame("Second frame"); aFrame.setSize(250, 100); aFrame.setVisible(true); } }
  3. Using the JLabel Class
    In a GUI environment, a label is an uneditable component that most often is used to provide information for a user. (Editable describes a component that can accept keystrokes.) JLabel is a built-in Java Swing class that allows you to create a label that you can display in a JFrame. The inheritance hierarchy of the JLabel class is shown in Figure. java.lang.Object | +--java.awt.Component | +--java.awt.Container | +--javax.swing.JComponent | +--javax.swing.JLabel Available constructors for the JLabel class include the following: • JLabel() creates a JLabel instance with no image and with an empty string for the title. • JLabel(Icon image) creates a JLabel instance with the specified image. • JLabel(Icon image, int horizontalAlignment) creates a JLabel instance with the specified image and horizontal alignment. • JLabel(String text) creates a JLabel instance with the specified text. • JLabel(String text, Icon icon, int horizontalAlignment) creates a JLabel instance with the specified text, image, and horizontal alignment. • JLabel(String text, int horizontalAlignment) creates a JLabel instance with the specified text and horizontal alignment. For example, you can create a JLabel named greeting that holds the words Good day by writing the following statement: JLabel greeting = new JLabel("Good day"); You then can add the greeting object to the JFrame object named aFrame using the add() method as follows: aFrame.add(greeting);
    import javax.swing.*; public class JFrame3 { public static void main(String[] args) { final int FRAME_WIDTH = 250; final int FRAME_HEIGHT = 100; JFrame aFrame = new JFrame("Third frame"); aFrame.setSize(FRAME_WIDTH, FRAME_HEIGHT); aFrame.setVisible(true); aFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JLabel greeting = new JLabel("Good day"); aFrame.add(greeting); } }
    The counterpart to the add() method is the remove() method. The following statement removes greeting from aFrame: aFrame.remove(greeting); If you add or remove a component from a container after it has been made visible, you also should call the invalidate(), validate(), and repaint() methods, or you will not see the results of your actions. Each performs slightly different functions, but all three together guarantee that the results of changes in your layout will take effect. The invalidate() and validate() methods are part of the Container class, and the repaint() method is part of the Component class. You can change the text in a JLabel by using the Component class setText() method with the JLabel object and passing a String to it. For example, the following code changes the value displayed in the greeting JLabel: greeting.setText("Howdy"); You can retrieve the text in a JLabel (or other Component) by using the getText() method, which returns the currently stored String.
    Changing a JLabel’s Font
    You probably are not very impressed with the simple application displayed in Figure 14-9. You might think that the string Good day is plain and lackluster. Fortunately, you can change the font of strings displayed in GUI components. A font is the size, weight, and style of a typeface, and Java provides you with a Font class from which you can create an object that holds typeface and size information. The setFont() method requires a Font object argument. To construct a Font object, you need three arguments: typeface, style, and point size. • The typeface argument to the Font constructor is a String representing a font. Common fonts have names such as Arial, Century, Monospaced, and Times New Roman. The typeface argument in the Font constructor is only a request; the system on which your program runs might not have access to the requested font, and if necessary, it substitutes a default font. • The style argument applies an attribute to displayed text and is one of three values: Font.PLAIN, Font.BOLD, or Font.ITALIC. • The point size argument is an integer that represents about 1/72 of an inch. Printed text is commonly 12 points; a headline might be 30 points. To give a JLabel object a new font, you can create a Font object, as in the following: Font headlineFont = new Font("Monospaced", Font.BOLD, 36); The typeface name is a String, so you must enclose it in double quotation marks. You can use the setFont() method to assign the Font to a JLabel with a statement such as: greeting.setFont(headlineFont); Figure shows a class named JFrame4. Notice the changes from the JFrame3 program.
    import javax.swing.*; import java.awt.*; // import statement for the Font class public class JFrame4 // new class name { public static void main(String[] args) { final int FRAME_WIDTH = 250; final int FRAME_HEIGHT = 100; Font headlineFont = new Font("Arial", Font.BOLD, 36); // Font object declared JFrame aFrame = new JFrame("Fourth frame"); // new frame title aFrame.setSize(FRAME_WIDTH, FRAME_HEIGHT); aFrame.setVisible(true); aFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JLabel greeting = new JLabel("Good day"); greeting.setFont(headlineFont); // new font applied to greeting aFrame.add(greeting); } }
    You are not required to provide an identifier for a Font. For example, you could omit the statement that declares headlineFont in Figure 14-10 and set the greeting Font with the following statement that uses an anonymous Font object that is established within the method call: greeting.setFont(new Font("Arial", Font.BOLD, 36)); After you create a Font object, you can create a new object with a different type and size using the deriveFont() method with appropriate arguments. For example, the following two statements create a headlineFont object and a textBodyFont object that is based on the first object: Font headlineFont = new Font("Arial", Font.BOLD, 36); Font textBodyFont = headlineFont.deriveFont(Font.PLAIN, 14); Basing one font on another ensures that if the original font is changed in the future, the derived font will have the same look and feel relative to the first one.
  4. Using a Layout Manager

    When you want to add multiple components to a JFrame or other container, you usually need to provide instructions for the layout of the components. For example, Figure shows an application in which two JLabels are created and added to a JFrame.
    import javax.swing.*; import java.awt.*; public class JFrame5 { public static void main(String[] args) { final int FRAME_WIDTH = 250; final int FRAME_HEIGHT = 100; JFrame aFrame = new JFrame("Fifth frame"); aFrame.setSize(FRAME_WIDTH, FRAME_HEIGHT); aFrame.setVisible(true); aFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JLabel greeting = new JLabel("Hello"); JLabel greeting2 = new JLabel("Who are you?"); aFrame.add(greeting); // Athough two JLabels are added to the JFrame, only the last one added is visible. aFrame.add(greeting2); } }
    To place multiple components at specified positions in a container so they do not hide each other, you must explicitly use a layout manager—an object that controls component positioning. The normal (default) behavior of a JFrame is to use a border layout manager, which divides a container into regions. The Java class that provides this type of layout is named BorderLayout. When you use BorderLayout but do not specify a region in which to place a component (as the JFrame5 program fails to do), all the components are placed in the same region, and they obscure each other. When you use a flow layout manager, components do not lie on top of each other. Instead, the flow layout manager places components in rows; after any row is filled, additional components automatically spill into the next row. The Java class that provides this type of layout is FlowLayout. Three constants are defined in the FlowLayout class that specify how components are positioned in each row of their container. These constants are FlowLayout.LEFT, FlowLayout.RIGHT, and FlowLayout.CENTER. For example, to create a layout manager named flow that positions components to the right, you can use the following statement: FlowLayout flow = new FlowLayout(FlowLayout.RIGHT); If you do not specify how components are laid out, by default they are centered in each row. Suppose that you create a FlowLayout object named flow as follows: FlowLayout flow = new FlowLayout(); Then the layout of a JFrame named aFrame can be set to the newly created FlowLayout using the statement: aFrame.setLayout(flow); A more compact syntax that uses an anonymous FlowLayout object is: aFrame.setLayout(new FlowLayout()); Figure shows an application in which the JFrame’s layout manager has been set so that multiple components are visible.
    import javax.swing.*; import java.awt.*; public class JFrame6 { public static void main(String[] args) { final int FRAME_WIDTH = 250; final int FRAME_HEIGHT = 100; JFrame aFrame = new JFrame("Sixth frame"); aFrame.setSize(FRAME_WIDTH, FRAME_HEIGHT); aFrame.setVisible(true); aFrame.setDefaultC1oseOperation(JFrame.EXIT_ON_CL0SE); JLabel greeting = new JLabel("Hello"); JLabel greeting2 = new JLabel("Who are you?"); aFrame.setLayout(new FlowLayout()); // The layout manager allows multiple components in the JFrame to be visible. aFrame.add(greeting); aFrame.add(greeting2); } }
  5. Extending the JFrame Class

    You can instantiate a simple JFrame object within an application’s main() method or with any other method of any class you write. Alternatively, you can create your own class that descends from the JFrame class. The advantage of creating a child class of JFrame is that you can set the JFrame’s properties within your object’s constructor; then, when you create your JFrame child object, it is automatically endowed with the features you have specified, such as title, size, and default close operation. You already know that you create a child class by using the keyword extends in the class header, followed by the parent class name. You also know that you can call the parent class’s constructor using the keyword super, and that when you call super(), the call must be the first statement in the constructor. For example, the JMyFrame class in Figure extends JFrame. Within the JMyFrame constructor, the super() JFrame constructor is called; it accepts a String argument to use as the JFrame’s title. (Alternatively, the setTitle() method could have been used.) The JMyFrame constructor also sets the size, visibility, and default close operation for every JMyFrame. Each of the methods— setSize(), setVisible(), and setDefaultCloseOperation()—appears in the constructor in Figure without an object, because the object is the current JMyFrame being constructed. Each of the three methods could be preceded with a this reference with exactly the same meaning. That is, within the JMyFrame constructor, the following two statements have identical meanings: setSize(WIDTH, HEIGHT); this.setSize(WIDTH, HEIGHT); Each statement sets the size of “this” current JMyFrame instance.
    import javax.swing.*; public class JMyFrame extends JFrame { final int WIDTH = 300; final int HEIGHT = 120; public JMyFrame() { super("My frame"); setSize(WIDTH, HEIGHT); setVisible(true); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } }
    Figure shows an application that declares two JMyFrame objects. Each has the same set of attributes, determined by the JMyFrame constructor.
    public class CreateTwoJMyFrameObjects { public static void main(String[] args) { JMyFrame myFrame = new JMyFrame(); JMyFrame mySecondFrame = new JMyFrame(); } }
    You exit the application when you click the Close button on either of the two JMyFrame objects shown in Figure. Each object has the same default close operation because each uses the same constructor that specifies this operation. To allow only one JMyFrame to control the program’s exit, you could use the setDefaultCloseOperation() method with one or both of the objects in the application to change its close behavior. For example, you could use DISPOSE_ON_CLOSE to dismiss one of the frames but keep the application running. When you extend a JFrame to create a new custom class, you must remember to make decisions as to which attributes you want to set within the class and which you want to leave to the applications that will use the class. For example, you can place the setVisible() statement within the JFrame child class constructor (using either an explicit or implied this reference), or you can allow the application to use a setVisible() statement (using the name of an instantiated object followed by a dot and the method name). Either one works, but if you fail to do either, the frame will not be visible.
  6. Adding JTextFields and JButtons to a JFrame

    Adding JTextFields
    A text field is a component into which a user can type a single line of text data. (Text data comprises any characters you can enter from the keyboard, including numbers and punctuation.) The Swing class that creates a text field is JTextField. Figure 14-19 shows the inheritance hierarchy of the JTextField class. java.lang.Object | +--java.awt.Component | +--java.awt.Container | +--javax.swing.JComponent | +--javax.swing.text.JTextComponent | +--javax.swing.JTextField Typically, a user types a line into a JTextField and then presses Enter on the keyboard or clicks a button with the mouse to enter the data. You can construct a JTextField object using one of several constructors: • public JTextField() constructs a new JTextField. • public JTextField(int columns) constructs a new, empty JTextField with a specified number of columns. • public JTextField(String text) constructs a new JTextField initialized with the specified text. • public JTextField(String text, int columns) constructs a new JTextField initialized with the specified text and columns. For example, to provide a JTextField that allows enough room for a user to enter approximately 10 characters, you can code the following: JTextField response = new JTextField(10); To add the JTextField named response to a JFrame named frame, you write: frame.add(response); The number of characters a JTextField can display depends on the font being used and the actual characters typed. For example, in most fonts, w is wider than i, so a JTextField of size 10 using the Arial font can display 24 i characters, but only eight w characters. Try to anticipate how many characters your users might enter when you create a JTextField. The user can enter more characters than those that display, but the extra characters scroll out of view. It can be disconcerting to try to enter data into a field that is not large enough. It is usually better to overestimate than underestimate the size of a text field. Several other methods are available for use with JTextFields. The setText() method allows you to change the text in a JTextField (or other Component) that has already been created, as in the following: response.setText("Thank you"); After a user has entered text in a JTextField, you can clear it out with a statement such as the following, which assigns an empty string to the text: response.setText(""); The getText() method allows you to retrieve the String of text in a JTextField (or other Component), as in: String whatUserTyped = response.getText(); A JTextField is editable by default. If you do not want the user to be able to enter data in a JTextField, you can send a boolean value to the setEditable() method to change the JTextField’s editable status. For example, if you want to give a user a limited number of chances to answer a question correctly, you can count data-entry attempts and then prevent the user from replacing or editing the characters in the JTextField by using a statement similar to the following: if(attempts > LIMIT) response.setEditable(false);
    Adding JButtons
    In a GUI environment, a button is a component typically used to trigger an action or make a selection when the user clicks it. The Java class that creates a button is JButton. A JButton is even easier to create than a JTextField. There are five JButton constructors: • public JButton() creates a button with no set text. • public JButton(Icon icon) creates a button with an icon of type Icon or ImageIcon. • public JButton(String text) creates a button with text. • public JButton(String text, Icon icon) creates a button with initial text and an icon of type Icon or ImageIcon. • public JButton(Action a) creates a button in which properties are taken from the Action supplied. (Action is a Java class.) The inheritance hierarchy of the JButton class is shown java.lang.Object | +--java.awt.Component | +--java.awt.Container | +--javax.swing.JComponent | +--javax.swing.AbstractButton | +--javax.swing.JButton To create a JButton with the text Press when ready, you can write the following: JButton readyJButton = new JButton("Press when ready"); You can add a JButton to a JFrame (or other container) using the add() method. You can change a JButton’s text with the setText() method, as in: readyJButton.setText("Don’t press me again!"); You can retrieve the text from a JButton and assign it to a String object with the getText() method, as in: String whatsOnJButton = readyJButton.getText(); Figure 14-21 a class that extends JFrame and holds several components. As the components (two JLabels, a JTextField, and a JButton) are added to the JFrame, they are placed from left to right in horizontal rows across the JFrame’s surface. Figure 14-22 shows the program that instantiates an instance of the JFrame.
    import javax.swing.*; import java.awt.*; public class JFrameWithManyComponents extends JFrame { final int FRAME_WIDTH = 300; final int FRAME_HEIGHT = 150; public JFrameWithManyComponents() { super("Demonstrating many components"); setSize(FRAME_WIDTH, FRAME_HEIGHT); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JLabel heading = new JLabel("This frame has many components"); heading.setFont(new Font("Arial", Font.BOLD, 16)); JLabel namePrompt = new JLabel("Enter your name:"); JTextField nameField = new JTextField(12); JButton button = new JButton("Click to continue"); setLayout(new FlowLayout()); add(heading); add(namePrompt); add(nameField); add(button); } } public class ComponentDemo { public static void main(String[] args) { JFrameWithManyComponents frame = new JFrameWithManyComponents(); frame.setVisible(true); } }
  7. Learning About Event-Driven Programming

    An event occurs when a user takes action on a component, such as clicking the mouse on a JButton object. As you learned in Chapter 1, procedural programs are programs in which actions take place one at a time in the sequence in which statements appear within a method. In an event-driven program, however, the user might initiate any number of events in any order. For example, if you use a word-processing program, you have dozens of choices at your disposal at any time. You can type words, select text with the mouse, click a button to change text to bold, click a button to change text to italic, choose a menu item, and so on. With each word-processing document you create, you choose options in any order that seems appropriate at the time. The word-processing program must be ready to respond to any event you initiate. Within an event-driven program, a component on which an event is generated is the source of an event. An object that is interested in an event is a listener. Programmers sometimes say a source triggers an event or fires an event. For example, if a label appears or changes color when the user clicks a button, the button is the source of the event and the label is a listener. When the source fires an event, an event-handling method contained in the listener object’s class responds to the event. A source and a listener can be the same object. For example, you might program a button to change its own text when a user clicks it. Not all objects listen for all possible events—you probably have used programs in which clicking many areas of the screen has no effect. If you want an object to be a listener for an event, you must register or sign up the object as a listener for the source. Social networking sites maintain lists of people in whom you are interested and notify you each time a person on your list posts a comment or picture. Similarly, a Java component source object (such as a button) maintains a list of registered listeners and notifies all of them when an event occurs. To respond to user events within any class you create, you must do the following: • Prepare your class to accept event messages by importing and implementing the appropriate listener interface. • Tell your class to expect events to happen by registering it as a listener. • Tell your class how to respond to events by writing necessary action statements in a method.
    Preparing Your Class to Accept Event Messages
    The java.awt.event package includes event classes that provide the capability to work with user-generated events such as an ActionEvent, which is the type of event that occurs when a user clicks a button. You import the event package to gain access to the methods in the event classes, and then you prepare a class to work with events by adding an implements phrase to the class header. For example, implementing the ActionListener interface provides you with standard event method specifications that allow a listener to work with ActionEvents.
    Telling Your Class to Expect Events to Happen
    You tell your class to expect an event using a method name that begins with the appropriate listener-registering method. The method that registers an ActionEvent is the addActionListener() method. (You learn about other listener-registering methods later in this chapter.) For example, suppose that you are creating a class that represents a frame; within the class, you have declared a JButton named aButton, and you want to perform an action when a user clicks aButton. In this case, aButton is the source of a message, and your class is a listener. The following code in the frame class causes any ActionEvent messages (button clicks) that come from aButton to be sent to the frame: aButton.addActionListener(this); You learned in Chapter 4 that the this reference means “this current object.” In this case, this refers to the frame class in which this statement appears.
    Telling Your Class How to Respond to Events
    You tell your class what to do when an event is generated by writing statements in a specific method that is part of the listener interface. For example, the ActionListener interface contains the actionPerformed() method specification that executes when an event occurs. The method is an example of an event handler—it reacts to and takes care of generated events. When you implement the ActionListener interface, you must write the actionPerformed() method to overload the empty version in the interface. (In Chapter 11, you learned that all the methods in an interface are abstract, and therefore must be given a body in classes that use them.) Suppose that you have created a class that extends JFrame, and that you have registered it as a listener for events triggered by a JButton. When a user clicks the JButton, the actionPerformed() method executes automatically. The actionPerformed() method must have the following header, in which e represents any name you choose for the Event: public void actionPerformed(ActionEvent e) The body of the method contains any statements that you want to execute when the action occurs. You might want to perform mathematical calculations, construct new objects, produce output, or execute any other operation.
    An Event-Driven Program
    For example, first Figure shows a JFrame that reacts to a button click. The class contains a JLabel that prompts the user for a name, a JTextField into which the user can type a response, a JButton to click, and a second JLabel that displays the name entered by the user. The program imports the event package and implements the event listener. The frame is registered as a listener for button clicks; the actionPerformed() method is the method that executes when the button is clicked. Within the actionPerformed() method, the String that a user has typed into the JTextField is retrieved and stored in the name variable and then used in the text of a second JLabel. Second Figure shows an application that instantiates a JHelloFrame object and makes it visible.
    import javax.swing.*; import java.awt.*; import java.awt.event.*; // This program uses the event package. public class JHelloFrame extends JFrame implements ActionListener // This phrase implements the event listener { JLabel question = new JLabel("What is your name?"); Font bigFont = new Font("Arial", Font.BOLD, 16); JTextField answer = new JTextField(lO); JButton pressMe = new JButton("Press me"); Jlabel greeting = new JLabel(""); final int WIDTH = 275; final int HEIGHT= 225; public JHelloFrame() { super("Hello Frame"); setSize(WIDTH, HEIGHT); setLayout(new FlowLayout()); question.setFont(bigFont); greeting.setFont(bigFont); add(question); add(answer); add(pressMe); add(greeting); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); pressMe.addActionListener(this); // The class (the frame)is registered as a listener for button clicks. } @Override public void actionPerformed(ActionEvent e) // This method executes when the user clicks the button. { String name = answer.getText(); String greet = "Hello, " + name; greeting.setText(greet); } } public class JHelloDemo { public static void main(String[] args) { JHelloFrame frame = new JHelloFrame(); frame.setVisible(true); } }
    Using Multiple Event Sources
    You can add more than one event source component to a listener. For example, in the JHelloFrame class in Figure, you might want the user to be able to see the message after either clicking the button or pressing Enter in the JTextField. In that case, you would designate both the pressMe button and the answer text field to be message sources by using the addActionListener() method with each, as follows: pressMe.addActionListener(this); answer.addActionListener(this); These two statements make the JFrame a listener for messages from either object. The actionPerformed() method then executes when either the pressMe button or the answer text field generates an event. If you want different actions to occur depending on whether the user clicks the button or presses Enter, you must determine the source of the event. Within the actionPerformed() method, you can use the getSource() method with the event parameter to determine which component generated the event. For example, when the parameter to the actionPerformed() method is named e, you can use the following statement to determine which object generated the ActionEvent: Object source = e.getSource(); For example, if a JFrame contains two JButtons named option1 and option2, you can use the decision structure in the method in Figure 14-28 to take different courses of action based on which button is clicked. Whether an event’s source is a JButton, JTextField, or other Component, it can be assigned to an Object because all components descend from Object @Override public void actionPerformed(ActionEvent e) { Object source = e.getSource(); if(source == option1) //execute these statements when user clicks option1 else //execute these statements when user clicks any other option } Alternatively, you can also use the instanceof keyword to determine the source of the event. The instanceof keyword is used when it is necessary to know only the component’s type, rather than what component triggered the event. For example, if you want to take some action when a user enters data into any JTextField, but not when an event is generated by a different Component type, you could use the method format shown in Figure. @Override void actionPerformed(ActionEvent e) { Object source = e.getSource(); if(source instanceof JTextField) { // execute these statements when any JTextField // generates the event // but not when a JButton or other Component does } }
    Using the setEnabled() Method
    You probably have used computer programs in which a component becomes disabled or unusable. For example, a JButton might become dim and unresponsive when the programmer no longer wants the user to have access to the JButton’s functionality. Components are enabled by default, but you can use the setEnabled() method to make a component available or unavailable by passing true or false to it, respectively.
  8. Understanding Swing Event Listeners

    Many types of listeners exist in Java, and each of these listeners can handle a specific event type. A class can implement as many event listeners as it needs—for example, a class might need to respond to both a mouse button press and a keyboard key press, so you might implement both ActionListener and KeyListener interfaces. Table lists some event listeners and the types of events for which they are used.
    ListenerType of EventsExample
    ActionListenerAction eventsButton clicks
    AdjustmentListenerAdjustment eventsScroll bar moves
    ChangeListenerChange eventsSlider is repositioned
    FocusListenerKeyboard focus eventsText field gains or loses focus
    ItemListenerItem eventsCheck box changes status
    KeyListenerKeyboard eventsText is entered
    MouseListenerMouse eventsMouse clicks
    MouseMotionListenerMouse movement eventsMouse rolls
    WindowListenerWindow eventsWindow closes
    An event occurs every time a user types a character, clicks a mouse button, taps a touch screen, or takes a similar action. Any object can be notified about an event as long as it implements the appropriate interface and is registered as an event listener on the appropriate event source. You already know that you establish a relationship between a JButton and a JFrame that contains it by using the addActionListener() method. Similarly, you can create relationships between other Swing components and the classes that react to users’ manipulations of them. In followingTable, each component listed on the left is associated with a method on the right. For example, when you want a JCheckBox to respond to a user’s clicks, you can use the addItemListener() method to register the JCheckBox as the type of object that can create an ItemEvent. (You learn more about JCheckBox objects later in this chapter.) The argument you place within the parentheses of the call to the addItemListener() method is the object that should respond to the event. The format is: theSourceOfTheEvent.addListenerMethod(theClassThatShouldRespond); As you already have learned, the class that should respond is frequently the this class
    Component(s)Associated Listener-Registering Method(s)
    JButton, JCheckBox, JComboBox, JTextField, and JRadioButtonaddActionListener()
    JScrollBaraddAdjustmentListener()
    All Swing componentsaddFocusListener(), addKeyListener(), addMouseListener(), and addMouseMotionListener()
    JButton, JCheckBox, JComboBox, and JRadioButtonaddItemListener()
    All JWindow and JFrame componentsaddWindowListener()
    JSlider and JCheckBoxaddChangeListener()
    The class of the object that responds to an event must contain an event-handling method that accepts the event object created by the user’s action. You cannot choose your own name for event handlers—specific method identifiers react to specific event types. following Table lists just some of the methods that react to events.
    ListenerMethod
    ActionListeneractionPerformed(ActionEvent)
    AdjustmentListeneradjustmentValueChanged(AdjustmentEvent)
    FocusListenerfocusGained(FocusEvent) and focusLost(FocusEvent)
    ItemListeneritemStateChanged(ItemEvent)
    Until you become familiar with the event-handling model, it can seem quite confusing. For now, remember these tasks you must perform when you declare a class that handles an event: • You must import the java.awt.event package in the class that handles the event. • The class that handles an event must either implement a listener interface or extend a class that implements a listener interface. • You must register each instance of the event-handling class as a listener for one or more components using an addXXXListener() method. • You must write an event handler method with an appropriate identifier (as shown in Table) that accepts the generated event and reacts to it.
  9. Using the JCheckBox, ButtonGroup, and JComboBox Classes

    Besides JButtons and JTextFields, several other Java components allow a user to make selections in a GUI environment. These include JCheckBoxes, ButtonGroups, and JComboBoxes.
    The JCheckBox Class
    A check box consists of a label positioned beside a square; you can click the square to display or remove a check mark. Usually, you use a check box to allow the user to turn an option on or off. The Java Swing class that creates a check box is JCheckBox. For example, Figure shows the code for an application that uses four JCheckBox objects.
    import java.awt.*; import javax.swing.*; import java.awt.event*; public class CheckBoxDemonstration extends JFrame implements ItemListener { FlowLayout flow = new FlowLayout(); JLabel label = new JLabel("What would you like to drink?"); JCheckBox coffee = new JCheckBox("Coffee", false); JCheckBox cola = new JCheckBox("Cola", false); JCheckBox milk = new JCheckBox ("Milk", false); JCheckBox water = new JCheckBox("Water", false); public CheckBoxDemonstration() { super("CheckBox Demonstration"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLayout(new FlowLayout()); label.setFont(new Font("Arial", Font.ITALIC, 22)); coffee.additemListener(this); cola.additemListener(this); milk.additemListener(this); water.additemListener(this); add(label); add(coffee); add(cola); add(milk); add(water); } @Override public void itemStateChanged(ItemEvent check) { // Actions based on choice go here } public static void main(String [] arguments) { final int FRAME_WIDTH = 350; final int FRAME_HEIGHT = 120; CheckBoxDemonstration frame = new CheckBoxDemonstration(); frame.setSize(FRAME_WIDTH, FRAME_HEIGHT); frame.setVisible(true); } }
    The inheritance hierarchy of the JCheckBox class is shown in Figure 14-34; frequently used JCheckBox methods appear in Table. java.lang.Object | +--java.awt.Component | +--java.awt.Container | +--javax.swing.JComponent | +--javax.swing.AbstractButton | +--javax.swing.JToggleButton | +--javax.swing.JCheckBox
    MethodPurpose
    void setText(String)Sets the text for the JCheckBox
    String getText()Returns the JCheckBox text
    void setSelected(boolean)Sets the state of the JCheckBox to true for selected or false for unselected
    boolean isSelected()Gets the current state (checked or unchecked) of the JCheckBox
    Several constructors can be used with JCheckBoxes. When you construct a JCheckBox, you can choose whether to assign it a label; you also can decide whether the JCheckBox appears selected (JCheckBoxes start unselected by default). The following statements create four JCheckBox objects—one with no label and unselected, two with labels and unselected, and one with a label and selected. • JCheckBox box1 = new JCheckBox(); // No label, unselected • JCheckBox box2 = new JCheckBox("Check here"); // Label, unselected • JCheckBox box3 = new JCheckBox("Check here", false); // Label, unselected • JCheckBox box4 = new JCheckBox("Check here", true); // Label, selected If you do not initialize a JCheckBox with a label and you want to assign one later, or if you want to change an existing label, you can use the setText() method, as in the following example: box1.setText("Check this box now"); You can set the state of a JCheckBox with the setSelected() method; for example, you can use the following statement to ensure that box1 is unchecked: box1.setSelected(false); The isSelected() method is most useful in Boolean expressions, as in the following example, which adds one to a voteCount variable if box2 is currently checked. if(box2.isSelected()) ++voteCount; When the status of a JCheckBox changes from unchecked to checked (or from checked to unchecked), an ItemEvent is generated, and the itemStateChanged() method executes. You can use the getItem() method to determine which object generated the event and the getStateChange() method to determine whether the event was a selection or a deselection. The getStateChange() method returns an integer that is equal to one of two class variables—ItemEvent.SELECTED or ItemEvent.DESELECTED. For example, in Figure the itemStateChanged() method calls the getItem() method, which returns the object named source. Then, the value of source is tested in an if statement to determine if it is equivalent to a JCheckBox object named checkBox. If the two references are to the same object, the code determines whether the checkBox was selected or deselected, and in each case appropriate actions are taken.
    @Override public void itemStateChanged(ItemEvent e) { Object source = e.getItem(); if(source == checkBox) { int select = e.getStateChange(); if(select == ItemEvent.SELECTED) // statements that execute when the box is checked else // statements that execute when the box is unchecked } else { // statements that execute when the source of the event is // some component other than the checkBox object } }
    The ButtonGroup Class
    Sometimes, you want options to be mutually exclusive—that is, you want the user to be able to select only one of several choices. When you create a button group using the ButtonGroup class, you can group several components, such as JCheckBoxes, so a user can select only one at a time. When you group JCheckBox objects, all of the other JCheckBoxes are automatically turned off when the user selects any one check box. The inheritance hierarchy for the ButtonGroup class is shown in Figure. You can see that ButtonGroup descends directly from the Object class. Even though it does not begin with a J, the ButtonGroup class is part of the javax.swing package. java.lang.Object | +--javax.swing.ButttonGroup To create a ButtonGroup in a JFrame and then add a JCheckBox, you must perform four steps: • Create a ButtonGroup, such as ButtonGroup aGroup = new ButtonGroup();. • Create a JCheckBox, such as JCheckBox aBox = new JCheckBox();. • Add aBox to aGroup with aGroup.add(aBox);. • Add aBox to the JFrame with add(aBox); or this.add(aBox);. You can create a ButtonGroup and then create the individual JCheckBox objects, or you can create the JCheckBoxes and then create the ButtonGroup. If you create a ButtonGroup but forget to add any JCheckBox objects to it, then the JCheckBoxes act as individual, nonexclusive check boxes. A user can set one of the JCheckBoxes within a group to “on” by clicking it, or the programmer can select a JCheckBox within a ButtonGroup with a statement such as the following: aGroup.setSelected(aBox); Only one JCheckBox can be selected within a group. If you assign the selected state to a JCheckBox within a group, any previous assignment is negated. You can determine which, if any, of the JCheckBoxes in a ButtonGroup is selected using the isSelected() method. After a JCheckBox in a ButtonGroup has been selected, one in the group will always be selected. In other words, you cannot “clear the slate” for all the items that are members of a ButtonGroup. A trick that you can use to cause all the JCheckBoxes in a ButtonGroup to initially appear unselected is to add one JCheckBox that is not visible (using the setVisible() method). Then, you can use the setSelected() method to select the invisible JCheckBox, and all the others appear to be deselected.
    The JComboBox Class
    A combo box is a component that combines a button or an editable field and a drop-down list. The Swing class JComboBox creates a combo box. When a JComboBox appears on the screen, the default option is displayed in a field at the top of the box, and the list is not displayed. When the user clicks the button on the JComboBox, a list drops down; if the user selects an item from this list, it replaces the box’s displayed item. If the field at the top of the combo box is editable, the user also can type in it. The biggest advantage to using a JComboBox over displaying a series of choices with check boxes or buttons is that a combo box doesn’t take up much room in a frame until its list is expanded. The inheritance hierarchy of the JComboBox class is shown in Figure. java.lang.Object | +--java.awt.Component | +--java.awt.Container | +--javax.swing.JComponent | +--javax.swing.JComboBox You can build a JComboBox by using a constructor with no arguments and then adding items (for example, Strings) to the list with the addItem() method. The following statements create a JComboBox named majorChoice that contains three options from which a user can choose: JComboBox majorChoice = new JComboBox(); majorChoice.addItem("English"); majorChoice.addItem("Math"); majorChoice.addItem("Sociology"); In the declaration of the JComboBox, notice the use of String following the constructor call. By default, a JComboBox expects items that are added to be Object types. Adding the angle brackets and String notifies the compiler of the expected data types in the JComboBox and allows the compiler to check for errors if invalid items are added. If you do not insert a data type for a JComboBox, the program compiles, but a warning message is issued with each addItem() method call. Programmers say that JComboBox uses generics. Generic programming is a feature of modern languages that allows multiple data types to be used safely with methods. As an alternative, you can construct a JComboBox using an array of Objects as the constructor argument; the Objects in the array become the listed items within the JComboBox. For example, the following code creates the same majorChoice JComboBox as the preceding code: String[] majorArray = {"English", "Math", "Sociology"}; JComboBox majorChoice = new JComboBox(majorArray); Table lists some methods you can use with a JComboBox object. For example, you can use the setSelectedItem() or setSelectedIndex() method to choose one of the items in a JComboBox to be the initially selected item. You also can use the getSelectedItem() or getSelectedIndex() method to discover which item is currently selected.
    MethodPurpose
    void addItem(Object)Adds an item to the list
    void removeItem(Object)Removes an item from the list
    void removeAllItems()Removes all items from the list
    Object getItemAt(Int)Returns the list item at the index position specified by the integer argument
    int getItemCount()Returns the number of items in the list
    int getMaximumRowCount()Returns the maximum number of items the combo box can display without a scroll bar
    int getSelectedIndex()Returns the position of the currently selected item
    Object getSelectedItem()Returns the currently selected item
    Object[] getSelectedObjects()Returns an array containing selected Objects
    void setEditable(boolean)Sets the field to be editable or not editable
    void setMaximumRowCount(int)Sets the number of rows in the combo box that can be displayed at one time
    void setSelectedIndex(int)Sets the index at the position indicated by the argument
    void setSelectedItem(Object)Sets the selected item in the combo box display area to be the Object argument
    You can treat the list of items in a JComboBox object as an array; the first item is at position 0, the second is at position 1, and so on. It is convenient to use the getSelectedIndex() method to determine the list position of the currently selected item; then you can use the index to access corresponding information stored in a parallel array. For example, if a JComboBox named historyChoice has been filled with a list of historical events, such as “Declaration of Independence,” “Pearl Harbor,” and “Man walks on moon,” you can code the following to retrieve the user’s choice: int positionOfSelection = historyChoice.getSelectedIndex(); The variable positionOfSelection now holds the position of the selected item, and you can use the variable to access an array of dates so you can display the date that corresponds to the selected historical event. For example, if you declare the following, then dates[positionOfSelection] holds the year for the selected historical event: int[] dates = {1776, 1941, 1969}; In addition to JComboBoxes for which users click items presented in a list, you can create JComboBoxes into which users type text. To do this, you use the setEditable() method. A drawback to using an editable JComboBox is that the text a user types must exactly match an item in the list box. If the user misspells the selection or uses the wrong case, a negative value is returned from the getSelectedIndex() method. You can use an if statement to test the value returned or take action such as forcing a default option or issuing an appropriate error message.
  10. You Do It Exercises

    import javax.swing.*; public class JDemoFrame { public static void main(String[] args) { JFrame aFrame = new JFrame("This is a frame"); final int WIDTH = 300; final int HEIGHT = 250; aFrame.setSize(WIDTH, HEIGHT); aFrame.setVisible(true); } }
    import javax.swing.*; public class JDemoFrameThatCloses { public static void main(String[] args) { JFrame aFrame = new JFrame("This is a frame"); final int WIDTH = 300; final int HEIGHT = 250; aFrame.setSize(WIDTH, HEIGHT); aFrame.setVisible(true); aFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } }
    import javax.swing.*; import java.awt.*; public class JFrameWithComponents extends JFrame { JLabel label = new JLabel("Name?"); JTextField field = new JTextField(12); JButton button = new JButton("OK"); public JFrameWithComponents() { super("Frame with Components"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLayout(new FlowLayout()); add(label); add(field); add(button); } }
    import javax.swing.*; public class CreateJFrameWithComponents { public static void main(String[] arguments) { JFrameWithComponents aFrame = new JFrameWithComponents(); final int WIDTH = 350; final int HEIGHT = 100; aFrame.setSize(WIDTH, HEIGHT); aFrame.setVisible(true); } }
    import javax.swing.*; import java.awt.*; import java.awt.event.*; public class JAction extends JFrame implements ActionListener { JLabel label = new JLabel("Name?"); JTextField field = new JTextField(12); JButton button = new JButton("OK"); public JAction() { super("Action"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLayout(new FlowLayout()); add(label); add(field); add(button); button.addActionListener(this); field.addActionListener(this); } @Override public void actionPerformed(ActionEvent e) { label.setText("Thank you so much!"); button.setText("Application done"); } public static void main(String[] args) { JAction aFrame = new JAction(); final int WIDTH = 250; final int HEIGHT = 150; aFrame.setSize(WIDTH, HEIGHT); aFrame.setVisible(true); } }
    import javax.swing.*; import java.awt.*; import java.awt.event.*; public class JAction2 extends JFrame implements ActionListener { JLabel label = new JLabel("Name?"); JTextField field = new JTextField(12); JButton button = new JButton("OK"); public JAction2() { super("Action"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLayout(new FlowLayout()); add(label); add(field); add(button); button.addActionListener(this); field.addActionListener(this); } @Override public void actionPerformed(ActionEvent e) { Object source = e.getSource(); if(source == button) label.setText("You clicked the button"); else label.setText("You pressed Enter"); } public static void main(String[] args) { JAction2 aFrame = new JAction2(); final int WIDTH = 250; final int HEIGHT = 150; aFrame.setSize(WIDTH, HEIGHT); aFrame.setVisible(true); } }
    import javax.swing.*; import java.awt.*; import java.awt.event.*; public class JResortCalculator extends JFrame implements ItemListener { final int BASE_PRICE = 200; final int WEEKEND_PREMIUM = 100; final int BREAKFAST_PREMIUM = 20; final int GOLF_PREMIUM = 75; int totalPrice = BASE_PRICE; JCheckBox weekendBox = new JCheckBox ("Weekend premium $" + WEEKEND_PREMIUM, false); JCheckBox breakfastBox = new JCheckBox("Breakfast $" + BREAKFAST_PREMIUM, false); JCheckBox golfBox = new JCheckBox("Golf $" + GOLF_PREMIUM, false); JLabel resortLabel = new JLabel ("Resort Price Calculator"); JLabel priceLabel = new JLabel ("The price for your stay is"); JTextField totPrice = new JTextField(4); JLabel optionExplainLabel = new JLabel ("Base price for a room is $" + BASE_PRICE + "."); JLabel optionExplainLabel2 = new JLabel ("Check the options you want."); public JResortCalculator() { super("Resort Price Estimator"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLayout(new FlowLayout()); add(resortLabel); add(optionExplainLabel); add(optionExplainLabel2); add(weekendBox); add(breakfastBox); add(golfBox); add(priceLabel); add(totPrice); totPrice.setText("$" + totalPrice); weekendBox.addItemListener(this); breakfastBox.addItemListener(this); golfBox.addItemListener(this); } @Override public void itemStateChanged(ItemEvent event) { Object source = event.getSource(); int select = event.getStateChange(); if(source == weekendBox) if(select == ItemEvent.SELECTED) totalPrice += WEEKEND_PREMIUM; else totalPrice -= WEEKEND_PREMIUM; else if(source == breakfastBox) { if(select == ItemEvent.SELECTED) totalPrice += BREAKFAST_PREMIUM; else totalPrice -= BREAKFAST_PREMIUM; } else // if(source == golfBox) by default if(select == ItemEvent.SELECTED) totalPrice += GOLF_PREMIUM; else totalPrice -= GOLF_PREMIUM; totPrice.setText("$" + totalPrice); } public static void main(String[] args) { JResortCalculator aFrame = new JResortCalculator(); final int WIDTH = 300; final int HEIGHT = 200; aFrame.setSize(WIDTH, HEIGHT); aFrame.setVisible(true); } }
  11. Case Problems

    import javax.swing.*; import java.awt.*; import java.awt.event.*; public class JCarlysCatering extends JFrame implements ItemListener, ActionListener { FlowLayout flow = new FlowLayout(); JTextField guestsField = new JTextField(8); JLabel guestsLabel = new JLabel("Please enter number of guests"); JCheckBox beefBox = new JCheckBox("Beef", false); JCheckBox chickenBox = new JCheckBox("Chicken", false); JCheckBox fishBox = new JCheckBox("Fish", false); JCheckBox pastaBox = new JCheckBox("Pasta", false); JCheckBox saladBox = new JCheckBox("Salad", false); JCheckBox vegBox = new JCheckBox("Mixed vegetables", false); JCheckBox potBox = new JCheckBox("Baked potato", false); JCheckBox breadBox = new JCheckBox("Garlic bread", false); JCheckBox cakeBox = new JCheckBox("Chocolate cake", false); JCheckBox pieBox = new JCheckBox("Apple pie", false); JCheckBox pudBox = new JCheckBox("Butterscotch pudding", false); JLabel mainLabel = new JLabel("Carly's Catering"); Font font = new Font("Ariel",Font.ITALIC, 30); JLabel label2 = new JLabel("Total"); JLabel label1 = new JLabel("Select options"); JLabel totPrice = new JLabel(); double price = 0; String entreeString = ""; String sideString = ""; String dessertString = ""; String output; int numSelected = 0; public JCarlysCatering() { super("Menu options"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLayout(flow); ButtonGroup entreeGroup = new ButtonGroup(); entreeGroup.add(beefBox); entreeGroup.add(chickenBox); entreeGroup.add(fishBox); entreeGroup.add(pastaBox); //ButtonGroup sideGroup = new ButtonGroup(); //sideGroup.add(saladBox); //sideGroup.add(vegBox); //sideGroup.add(potBox); //sideGroup.add(breadBox); ButtonGroup dessertGroup = new ButtonGroup(); dessertGroup.add(cakeBox); dessertGroup.add(pieBox); dessertGroup.add(pudBox); add(mainLabel); add(guestsLabel); add(guestsField); add(label1); add(beefBox); add(chickenBox); add(fishBox); add(pastaBox); add(saladBox); add(vegBox); add(potBox); add(breadBox); add(cakeBox); add(pieBox); add(pudBox); mainLabel.setFont(font); add(label2); add(totPrice); totPrice.setText("$0"); guestsField.addActionListener(this); beefBox.addItemListener(this); chickenBox.addItemListener(this); fishBox.addItemListener(this); pastaBox.addItemListener(this); saladBox.addItemListener(this); vegBox.addItemListener(this); potBox.addItemListener(this); breadBox.addItemListener(this); cakeBox.addItemListener(this); pieBox.addItemListener(this); pudBox.addItemListener(this); } @Override public void actionPerformed(ActionEvent e) { Object source = e.getSource(); final int PRICE_PER_GUEST = 35; if(source == guestsField) { try { price = Integer.parseInt(guestsField.getText()) * PRICE_PER_GUEST; } catch(Exception exc) { price = 0; } output = "$" + price + " Menu includes " + entreeString + sideString + dessertString; totPrice.setText(output); } } @Override public void itemStateChanged(ItemEvent check) { Object source = check.getItem(); int select= check.getStateChange(); select = check.getStateChange(); if(select == ItemEvent.SELECTED) if(source == beefBox) entreeString = "- beef -"; else if(source == chickenBox) entreeString = "- chicken -"; else if(source == fishBox) entreeString = "- fish -"; else if(source == pastaBox) entreeString = "- pasta -"; if(select == ItemEvent.SELECTED) if(source == cakeBox) dessertString = "- chocolate cake -"; else if(source == pieBox) dessertString = "- apple pie -"; else if(source == pudBox) dessertString = "- butterscotch pudding -"; if(source == saladBox || source == vegBox || source == potBox || source == breadBox) { if(select == ItemEvent.SELECTED) ++numSelected; else --numSelected; sideString = ""; if(numSelected <= 2) { if(saladBox.isSelected()) sideString += "- salad -"; if(vegBox.isSelected()) sideString += "- mixed vegetables -"; if(potBox.isSelected()) sideString += "- baked potato -"; if(breadBox.isSelected()) sideString += "- garlic bread -"; } else { saladBox.setSelected(false); vegBox.setSelected(false); potBox.setSelected(false); breadBox.setSelected(false); } } output = "$" + price + " Menu includes: " + entreeString + sideString + dessertString; totPrice.setText(output); } public static void main(String[] args) { JCarlysCatering frame = new JCarlysCatering(); frame.setSize(550, 250); frame.setVisible(true); } }
    import javax.swing.*; import java.awt.*; import java.awt.event.*; public class JSammysSeashore extends JFrame implements ItemListener, ActionListener { FlowLayout flow = new FlowLayout(); JTextField hoursField = new JTextField(8); JLabel hoursLabel = new JLabel(" Please enter hours for rental"); JCheckBox jetSkiBox = new JCheckBox("Personal watercraft", false); JCheckBox pontoonBox = new JCheckBox("Pontoon boat", false); JCheckBox rowBoatBox = new JCheckBox("Row boat", false); JCheckBox canoeBox = new JCheckBox("Canoe", false); JCheckBox kayakBox = new JCheckBox("Kayak", false); JCheckBox beachChairBox = new JCheckBox("Beach chair", false); JCheckBox umbrellaBox = new JCheckBox("Umbrella", false); JCheckBox lessonBox = new JCheckBox("Lesson", false); JCheckBox noLessonBox = new JCheckBox("No lesson", true); JLabel mainLabel = new JLabel("Sammy's Seashore Rentals"); Font font = new Font("Ariel",Font.ITALIC, 30); Font font2 = new Font("Ariel",Font.PLAIN, 20); JLabel labelTotal = new JLabel("Total"); JLabel label1 = new JLabel("Select rental equipment"); JLabel label2 = new JLabel("Lessons?"); JLabel totPrice = new JLabel(); JLabel explainLabel = new JLabel(); int hourPrice = 0; int lessonPrice = 0; int equipPrice = 0; int price = 0; int hours; String output = ""; String equipString = ""; String timeString = ""; String lessonString = ""; public JSammysSeashore() { super("Menu options"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLayout(flow); ButtonGroup equipmentGroup = new ButtonGroup(); equipmentGroup.add(jetSkiBox); equipmentGroup.add(pontoonBox); equipmentGroup.add(rowBoatBox); equipmentGroup.add(canoeBox); equipmentGroup.add(kayakBox); equipmentGroup.add(beachChairBox); equipmentGroup.add(umbrellaBox); ButtonGroup lessonGroup = new ButtonGroup(); lessonGroup.add(lessonBox); lessonGroup.add(noLessonBox); add(mainLabel); add(hoursLabel); add(hoursField); add(label1); add(jetSkiBox); add(pontoonBox); add(rowBoatBox); add(canoeBox); add(kayakBox); add(beachChairBox); add(umbrellaBox); mainLabel.setFont(font); label1.setFont(font2); label2.setFont(font2); totPrice.setFont(font2); add(label2); add(lessonBox); add(noLessonBox); add(labelTotal); add(totPrice); totPrice.setText("$0"); add(explainLabel); hoursField.addActionListener(this); jetSkiBox.addItemListener(this); pontoonBox.addItemListener(this); rowBoatBox.addItemListener(this); kayakBox.addItemListener(this); canoeBox.addItemListener(this); beachChairBox.addItemListener(this); umbrellaBox.addItemListener(this); lessonBox.addItemListener(this); noLessonBox.addItemListener(this); } @Override public void actionPerformed(ActionEvent e) { Object source = e.getSource(); if(source == hoursField) { try { hours = Integer.parseInt(hoursField.getText()); } catch(Exception exc) { hours = 0; hoursField.setText("invalid entry"); } hourPrice = hours * equipPrice; price = hourPrice + lessonPrice; timeString = "- for " + hours + " hours - "; output = "$" + price; totPrice.setText(output); output = "Rental details: " + equipString + timeString + lessonString; explainLabel.setText(output); } } @Override public void itemStateChanged(ItemEvent check) { Object source = check.getItem(); int select = check.getStateChange(); final int HIGH_PRICE = 40; final int MED_PRICE = 20; final int LOW_PRICE = 7; final int LESSON_PRICE = 5; if(select == ItemEvent.SELECTED) { if(source == jetSkiBox) { equipString = "- personal watercraft @ $" + HIGH_PRICE + " per hour - " ; equipPrice = HIGH_PRICE; } else if(source == pontoonBox) { equipString = "- pontoon boat @ $" + HIGH_PRICE + " per hour - " ; equipPrice = HIGH_PRICE; } else if(source == rowBoatBox) { equipString = " - row boat @ $" + MED_PRICE + " per hour - " ; equipPrice = MED_PRICE; } else if(source == canoeBox) { equipString = "- canoe @ $" + MED_PRICE + " per hour - " ; equipPrice = MED_PRICE; } else if(source == kayakBox) { equipString = " - kayak @ $" + MED_PRICE + " per hour - " ;; equipPrice = MED_PRICE; } else if(source == beachChairBox) { equipString = " - beach chair @ $" + LOW_PRICE + " per hour - " ; equipPrice = LOW_PRICE; } else if(source == umbrellaBox) { equipString = " - umbrella @ $" + LOW_PRICE + " per hour - " ; equipPrice = LOW_PRICE; } else if(source == lessonBox) { lessonString = " - lesson @ $" + LESSON_PRICE; lessonPrice = LESSON_PRICE; } else { lessonString = " - no lesson"; lessonPrice = 0; } hourPrice = hours * equipPrice; price = hourPrice + lessonPrice; output = "$" + price; totPrice.setText(output); output = "Rental details: " + equipString + timeString + lessonString; explainLabel.setText(output); } } public static void main(String[] args) { JSammysSeashore frame = new JSammysSeashore(); frame.setSize(450, 250); frame.setVisible(true); } }