CS-140 Lab 8 -- Making a GUI

Let's make a GUI for our bank account code. First, we will make a simple GUI that just shows the balance. Then, we will update that GUI to provide the capability to deposit, withdraw, or ask for a statement with our GUI, giving us a chance to use some of what we have been learning.

Getting Started

Create an lab09 package, and import your homework 04 Bank Account code (or start with my solution to homework 04 at hw04_sol.zip. For instructions on how to import a zip file into a package, see the instructions in Using Eclipse web page.

The first thing we are going to modify is the Account class. You will need to make the following changes:

  1. Make the Account class a child of the JPanel class from the Swing library.
  2. Add a field to the Account class called balanceLabel, a reference to a JLabel object. This is the part of the GUI that will hold the current balance of the account.
  3. Create a newBalance method that takes a single argument called newBal. This should set the balance field to the new balance passed in as a parameter, and if we have a non-null balance lab, it should set the text of the balanceLab to String.format("$%.02f", newBal).
  4. Now, everywhere the balance is updated, either in the Account class itself or in any children of the Account class, whenever balance is changed, replace the assignment of the new balance with an invocation of the newBalance method.
  5. Create a createGUI method. This method contains all the GUI related initializations. Put it in a separate method so that if you don't want to use a GUI, you don't have to invoke this method and incur the extra cost of a GUI. For now, the createGUI method will deal with just three components. First, the this object points at an Account object, but contained within that Account object is a JPanel object. This is our container component that will contain everything about this account. In this panel, we want two labels. (We will make this panel more sophisticated later.) The first is a constant string that defines which account this is. We can create a local JLabel and set its text to the string name + " " + acctNumber +" balance :"

Next, you will need to modify the Tester class. The easiest way to do this is to copy the main method and the createAndShowGUI method from HelloWorldSwing.java code. The createAndShowGUI method should create a new Savings account, initialized with $1,000.00; and a new Checking Account initialized with $200.00. It should then create GUIs for each of these, and add the accounts to the frame. To make each account show up on its own line, you can code:

  frame.add(acct1,BorderLayout.LINE_START);
  frame.add(acct2,BorderLayout.AFTER_LAST_LINE);

Run your main function. You should get something that looks like:

Good so far, but still pretty static. Wouldn't it be nice if we could enhance this GUI to enable deposits and withdrawals?

Adding Buttons and Actions

We will be making some major changes to the Account class to add buttons and actions, as follows.

  1. Add implements ActionListener to the definition of the Accounts class. Eclipse will then tell you that if you implement ActionListener, you will need an actionPerformed method. Let Eclipse create an actionPerformed method for you. (We will have to fill in the instructions in this method later.)
  2. If we are going to support a deposit and a withdrawal from the GUI, we will need a text field to enable our users to enter the amount to deposit or withdraw. Since we are going to use that field in the actionPerformed method, we need it to be generally available. The easiest way to do this is to add a field to the Accounts class that is a reference to a JTextField, and call it amountField.
  3. Our panel for this account is going to get a lot more complicated. We need a more sophisticated layout manager. It turns out that the Border Layout manager is good enough for this GUI. (We haven't talked much about layout managers yet, but we will be soon. In the meantime, I will give you everything you need to implement to use the layout manager.) Add the instruction setLayout(new BorderLayout()); as the new first line in the createGUI method.
  4. Our panel for this account will have three major components. The top component will be the header for this account, an will include everything we have already done. However, we are going to put this in its own panel to separate it from the rest of the components associated with the account. Add a new line that says JPanel header = new JPanel();. Then rather than adding the balanceLabel and the name and account number JLabel to this, add them to header. Then add header to this, using the instruction add(header,BorderLayout.PAGE_START);
  5. The next component of the Account panel will be another panel that contains buttons. In order to get the buttons to lay out one on top of each other, we will use a different layout manager for this panel, called the "GridLayout" layout manager. Let's call this component the actionSelections panel, and create it with the instruction JPanel actionSelections = new JPanel(new GridLayout(0, 1));
  6. Next, let's put some buttons in the actionSelections panel. The first button is the withdrawal button. We can create this button with the instruction JButton withDrawButton = new JButton("Withdraw");

    Next, we need to register our Action class as the action listener to any actions which occur on our new button. This is done with the instruction: withDrawButton.addActionListener(this);

    Finally, we need to ad the withdraw button to the actionSelections panel. This is accomplished with actionSelections.add(withDrawButton);

  7. Add two more buttons, using similar instructions to those above... one for a deposit, and one called Statement to print a statement. To get these buttons to line up under the withdraw button, we need to add a constraint to the "add" method invocation, like the following: actionSelections.add(depositButton, BorderLayout.AFTER_LAST_LINE);
  8. Now that we have created the actionSelections panel, we need to add the actionSections panel as a component of the Accounts panel, but this time, on the left side of the panel. We do this with: add(actionSelections,BorderLayout.LINE_START);
  9. Next, we want to provide a space for our user to enter the amount to deposit or withdraw. This will be kept in an amount panel. Since no special layout management is required for this, we can just: JPanel amtPanel = new JPanel();
  10. The amtPanel is going to have two components. The first is a label that tells the user what we are asking for. Since we never need to reference this again, we don't need to create a reference variable for this... we can just add a new JLabel to the amtPanel directly, using an instruction like: amtPanel.add(new JLabel("Amount-->"));
  11. Our second component for amtPanel is one that we will need to reference in the future. This is a user editable text field. In fact, we already created a reference field for this in the Account class called amountField. We just have to instantiate that reference variable with an instruction like: amountField = new JTextField();

    Let's make sure the user has enough space to type in a reasonable number by reserving columns using the instruction: amountField.setColumns(10);

    We can also initialize this field to make it easier to understand what is supposed to be there... Why not: amountField.setText("0.00");

    Don't forget to add this field to the amtPanel panel

  12. Also, add the amtPanel to the Account panel on the right side using the instruction: add(amtPanel,BorderLayout.LINE_END);
  13. Since the user enters a string for the amount field, when we want to read that amount field, we will have to convert the users string into a double number. Lets code a getAmount method to handle that conversion. This method will look like:
       private double getAmount() {
    	return Double.parseDouble(amountField.getText());
      } 
      
  14. Now we can go down to our actionPerformed method. The first step is to figure out what button was pushed. We can add code like:
       if ("Withdraw".equals(e.getActionCommand())) {
        withdraw(getAmount());    		
      } else if ("Deposit".equals(e.getActionCommand())) {
      	deposit(getAmount());
      } else if ("Statement".equals(e.getActionCommand())) {
      	printStatement();
      } 
      

After making all these changes, compile and run your new code. Does it work as expected? What happens if you try to withdraw more than what is available in the checking account? What happens when you ask to print a statement?

Grading Criteria

Zip your code in the lab09 pacakge, and submit it on myCourses. This lab is worth 10 points. You will get the full 10 points if your code compiles without warnings, and produces the correct output. The following are reasons for deductions: