Lab 8 In-Class: Graphical User Interfaces

Vote Counter - Using Buttons

The files VoteCounter.java and VoteCounterPanel.java contain a slightly modified version of the PushCounter program in Listings 4.10 & 4.11 of the text (pages 192-194). The VoteCounterPanel class is on the separate printout. This program counts the number of times the button is pushed; it assumes each push is a vote for Blue.

  1. Save the files to your directory, then compile the program and run it to see how it works. Resize the window to see the effect on the components.

    Our goal is to add a second button to the panel, one for candidate Red. We would need three new instance variables - a vote counter for Red, a button, and a label. Write the code on the printout to do the following:

    1. declare the 3 new instance variables
    2. initialize/instantiate them in the constructor
    3. add them to the panel
    4. add the voteListener object to the new button so it will now listen for both buttons being clicked (NOTE: don't instantiate a new listener object - use the one already there)

  2. Now type the code into the VoteCounterPanel class.

  3. If nothing else changes in the example above, what will happen when the user presses the button for Red? Think about this first then run the program to see!!

     

  4. You should have noted that the problem was that the actionPerformed method only directed the computer to update the counter for Blue no matter which button was pushed. Modify the actionPerformed method in the VoteButtonListener class so it checks to see which button generated the event (that is, which button was pushed) and then updates the appropriate counter and displays the results. To do this you need to use the getSource method for event objects. The event object is passed as a parameter to the actionPerformed method (the formal parameter name of the ActionEvent object is event). The getSource method returns a reference to the component that generated the event so you can compare it to your components as in the example on page 267 (explanation starting on page 261).

  • Run the program and verify that your program correctly records votes for Blue and Red.

  • Adding Some Color Modify the panel so that its color is blue if the Blue button is ahead in the number of "votes" and red if Red is ahead and magenta if it is a tie. Do the following:
    1. In actionPerformed, after the count has been updated and displayed, add a statement to set the background color of the panel based on who is ahead. All Java components have a method:

      void setBackground (Color color)

      that changes the background color of the component.
    2. Also, change the color of the labels so they clearly show up -- use different colors to go with each background (you can choose the colors). Components have a setForeground method that is analogous to the setBackground method. The setForeground method changes the color of the text in labels and in buttons. Note that the method must operate on the label objects!
    3. Compile and test your program. Be sure your colors look good and that the labels are visible. If you wish you can also change the foreground and/or background colors of the buttons.

    Using TextFields - Computing Body Mass Index

    The files Fahrenheit.java and FahrenheitPanel.java contain the example program in Listings 4.12 & 4.13 of the text (pages 196 - 198). The program converts temperatures in Fahrenheit to the Celsius equivalent. The user enters a temperature in the text field and when ENTER is pressed the Celsius equivalent is computed and displayed. Pressing ENTER on a text field generates an action event so the program must implement the ActionListener interface. Do the following:

    In this exercise you will write a similar program to compute a person's Body Mass Index. Body Mass Index (BMI) is a measure of weight that takes height into account. Generally, a BMI above 25 is considered high, that is, likely to indicate that an individual is overweight. BMI is calculated as follows for both men and women:

               (703 * weight in pounds) / (height in inches)2
    

    1. File BMI.java contains the main program that creates the frame for the GUI panel and adds the panel to the content pane of the frame. The file BMIPanel.java contains a skeleton for the GUI to calculate BMI. Since there are two input values needed (the height and weight) this program will not respond to the user pressing ENTER on a text field. Instead, we will put a button on the panel for the user to press to trigger the calculation. So, the user enters his or her height and weight and presses a "Calculate BMI" button; the program then displays the user's BMI. Much of the framework has been done for you, but you will need to fill in code. Do the following (follow the instructions and the comments in the program):

      In the constructor for the panel you need to do the following (put your code for each immediately after the corresponding comment in the code):

      • JLabels have already been created to identify the height and weight textfields. You need to create (instantiate) the JLabels for the output, and to hold the actual BMI. (NOTE: You need to use the variables that have already been declared.)
      • Create JTextFields to hold the person's height in inches and weight in pounds.
      • Create an appropriately labeled JButton for the user to press to calculate the BMI.
      • Create a BMIListener and make it listen for the button to be pressed. Note that the listener is added to the button, not the textfields, so the BMI is computed only when the button is pressed, not when the user presses Enter on the textfields.
      • Add the height label and textfield to the panel. Note that the components will appear on the panel in the order in which you add them (left to right, top to bottom).
      • Add the weight label and textfield to the panel.
      • Add the button to the panel.
      • Add the label identifying the result and the label holding the result to the panel.

      In the actionPerformed method of BMIListener:

      • Get the text from the height and weight textfields and store the results in the String variables provided.
      • Use Integer.parseInt to convert the text to integer values, and store them in the int values provided.
      • Calculate the BMI from the height and weight values (use double precision arithmetic). Use Math.round to round the answer.
      • Use Double.toString to convert the BMI to a string, and store the string in the result label.

      Compile the BMI program and run it.

    2. Add code to the BMIPanel to let the user have some idea of what their BMI means. You need to either modify the JLabel that displays the BMI or add a new JLabel. Your program should include a message based on the following: a BMI less than 19 indicates the person is underweight, a BMI between 19 and 25 (inclusive) means a healthy weight, a BMI between 26 and 30 (inclusive) indicates the person is overweight, and a BMI over 30 indicates the person is very overweight. NOTE: Use an if to choose the appropriate message.

    Using Buttons to Display Images

    In this exercise you will use buttons to select a picture to display on a GUI panel.
    1. First we will need some pictures to work with. The archive file pics.tgz contains some pictures of Cats and Dogs. You may already have this file from Lab 4. If not, save it to your Labs directory. Change directories to Labs and uncompress the archive using the command
           tar xzf pics.tgz   

    2. Verify that there is a pics directory in Labs that contains four .gif files.

    3. The files ImgApp.java and ImgPanel.java create a GUI application with a single button. When the button is pressed, the panel should display an image of a cat. Verify that the button works correctly (if it does not - you probably need to double check the location of your pictures).

    4. Study the code in ImgPanel. You should observe that it works in a very similar manner to the previous programs. The only thing that is different is that instead of setting the text of a JLabel, you are using the setIcon method to add a picture to the JLabel.
    5. This is a pretty exciting program - except that once we push the button once, all the fun is done. We are going to modify this program so that pushing the button toggles between two different cat pictures. To accomplish this, implement the following steps:

      1. The panel needs to understand which picture to display. Add an instance variable picNum to your panel class that can store an integer. You will use this to determine if you want image #1 or image #2. You should also initialize this variable (set it to equal 1 for the cat1.gif image) in your constructor.

      2. Now modify the program so that when the button is pushed, it should change the image from one to another. If the panel previously displayed image #1, it should now display image #2 and vice-versa. Write a conditional statement that determines which image should be displayed and sets the appropriate instance variable. Note: You should not attempt to load the image yet .

      3. Notice that the name of the image loaded is "pics/cat1.gif". In your pics directory, there is also a file named "cat2.gif". The only difference between these two names is the number. Another way of thinking about this is that the file name is "pics/cat" + picNum +".gif". Modify the statement that currently loads pics/cat1.gif so that it loads the appropriate image.

    6. Run your program to verify that it functions properly

    A GUI-based ATM Machine

    In this exercise you will create a simple GUI-based ATM machine. You will need the following files: Account.java, the bank account class; ATM.java, the main program for the GUI; ATMPanel.java, the GUI panel. Open ATMPanel.java in Eclipse and do the following:
    1. Create the components and listeners as instructed by the comments in the program. When you add the components to the panel add them in the following order: the welcome label, the label telling the user to enter the amount, the text field for the amount, the label instructing the user to click the appropriate button, the buttons, and the label giving the balance. (Note: Don't do actionPerformed yet - we'll get the GUI looking ok first.)

    2. Compile and run the program to see what it looks like. Not too pretty! This is what the default flow layout looks like.

    3. There are many ways to make things look better. The one we will use is nested panels (see Section 3.10 in the text, pages 144-146). We'll divide the panel into 4 subpanels (and specify the size of each), then add those to the main panel (which has a size specified). Do this as follows:
      1. Declare and instantiate a JPanel named welcomePanel. Set its size (the width should be the constant WIDTH - you choose an appropriate height). Add the welcome label to the panel.
      2. Declare and instantiate a JPanel named amtPanel. Set its size and add both the label for the text field and the text field to it.
      3. Similarly declare and instantiate a JPanel, appropriately sized, containing the label instructing the user to click a button, and two buttons.
      4. Finally declare and instantiate a JPanel, appropriately sized, containing the balance label.
      5. Instead of adding the individual components to the main panel add the four subpanels.
      6. Compile and run the program to see how it looks. Make necessary modifications, including setting colors for the panels, to make things look good.

    4. Implement the actionPerformed method in the ChoiceListener class. The method should get the amount from the text field and convert it to a double using the parseDouble method in the Double class. Then the method needs to see which button was clicked and, using methods from the Account class, perform the appropriate action. Finally use the setText method to update the balance label (remember to use the formatter to format the new balance).

    HAND IN

    Hand in printouts for VoteCounterPanel.java, BMIPanel.java, ImgPanel.java, and ATMPanel.java. Tar your directory and email the tar file to your instructor with a subject of cpsc120 lab8