CS 161 Lab J - Calculator
Due Thurs Apr 11 at 11:59pm
Overview
In this lab, you will be completing a program implementing a Calculator (because math is fun!). You will be providing a Graphical User Interface (GUI) that allows people to easily interact with the calculator. You will be using the Java swing libraries to build the GUI. When executed, the program might display a calculator similar to any one of those shown below (in the order of difficulty from left to right):
(The different background colors are just because of the Windows OS interface, and will not be part of your program).
Before you begin, you might have a look at the Calculator program that comes with the operating system you are using. The calculator GUI you are developing may not be quite as graceful, but will be similar in terms of functionality (you might even say they share an interface!)
This lab will be completed in pairs. Be sure to review the pair programming guidelines. You also must work with a different partner than you have before!
Objectives
- To experiment with the built-in classes used to create GUIs
- To practice using swing LayoutManagers to organize an GUI
- To practice implementing event handling
Necessary Files
You will need to download and extract the BlueJ project from the LabJ.zip file. This project will supply you with the following classes:
-
Calculator
This class represents the "engine" underlying the calculator, with methods and variables to represent the calculator's core operations. For example, this class contains a variable that represents the result computed so far. There are methods to operate on the value (that is: to add, subtract, multiply, or divide). However, this class does not provide any input/output mechanism needed to interact with the calculator---that's what you will be doing! Skim through the class to get a sense for how it works and what methods it has; you will be using these methods to perform necessary operations in response to user inputs, as well as to get the output to show to the user. -
CalculatorTester
A simple tester class to run the CalculatorGUI program (which is what you will write!)
Details
For this lab, you will be making one new class: a CalculatorGUI
Details for building this class are below:
- Remember you will need to import the necessary packages (
java.awt.*
,javax.swing.*
, andjava.awt.event.*
) for building a GUI. -
Your
CalculatorGUI
should should extend the built-inJFrame
class---your GUI will be a JFrame! -
As always when making classes, the next step is to declare your instance variables. You will need a number of these to get your calculator working. Try to think about what variable you might need; you can also add more later as you discover you need them!
- At the very least, you'll likely want an instance of the
Calculator
engine to perform the mathematical operations! -
You'll also likely want some instances of the
JButton
class to represent the buttons of your calculator. As you will be using several buttons, it might be convenient (but not necessary) to use an array of JButton objects. This will make it easy to loop through the buttons and can reduce the amount of code you right. -
You'll probably also want a
JTextField
to act as the "display" of your calculator. JTextField is somewhat like JLabel, but looks a little different (and can by default be edited by the user)
- At the very least, you'll likely want an instance of the
-
The first big piece of making your GUI will be to fill in the constructor.
- Remember to explicitly call your parent's constructor! Good style.
- Add in the other "basic" JFrame methods (e.g.,
setDefaultCloseOperation()
,setVisible()
, etc.) Feel free to look through class notes, old labs/homeworks, etc for the signatures and uses of these methods. -
You'll also need to instantiate the instance variables you declared (the JButtons, JTextField, Calculator, etc).
-
JTextField
is normally for taking input; since we will be using it for output, you should disable the textfield using thesetEditable()
method. Also, the default alignment for a JTextField is to the left--to make the text show up aligned to the right, you can use thesetHorizontalAlignment()
method.
-
-
Don't forget to
pack()
and set the frame's visiblity in order to make it actually show up! -
This next step is the big important one!
You'll need to organize your buttons and textfields so that they are laid out like a calculate (similar to the images above)! To do this, you will need to use
LayoutManager
s and possibly nestedJPanel
s. Here are a few suggestions (but you are welcome to use your own process):-
Start with a
BorderLayout
to divide your calculator into two parts: the display which goes at the top, and the buttons which go below. -
Use a JPanel with a
GridLayout
as a container to hold the buttons. Think about how many rows and how many columns you need (check the GridLayout's constructor for what parameters to use). Add the buttons to this panel, then add the panel to the frame.
-
Start with a
- Make sure you've got your calculator laid out currently and showing up--it should look good before you add in the next part!
-
The next part is adding the event handling, so that our calculator buttons actually do something. Recall that there are three steps to add event handling:
- Implement the
ActionListener
interface (be sure to define the required method! You can start by leaving it empty). - Register the listener for every button using the
addActionListener()
method. Remember thatthis
CalculatorGUI is the ActionListener! - Fill in the
actionPerformed()
method to respond to each button being pressed. Remember to use thegetSource()
method of the ActionEvent parameter to figure out which button was pressed!
The following code sample demonstrates how to implement event handling:
public class ButtonTest extends JFrame implements ActionListener{ //STEP 1 JButton button; public ButtonTest(){ button = new JButton(); button.addActionListener(this); //STEP 2 add(button); } public void actionPerformed(ActionEvent e){ //STEP 3 if(e.getSource() == button){ System.out.println("button pressed!"); } } }
- Implement the
-
In STEP 3, you'll need to make you Calculator buttons perform particular actions. You'll need to fill in the
actionPerformed
method, callinggetSource()
on the event to figure out which button was pressed. The following pseudocode demonstrates your logic:if e.getSource() == a digit button call addDigit() passing in the digit else if e.getSource() == the decimal button call addDecimal() else if e.getSource() == the clear button call clearCalc() ................... ................... else // meaning an operation button has been clicked if add operation button is clicked get the value of the display call applyOperation(displayValue, Calculator.ADD) update the dispaly with the result of applyOperation() ................ ................
The helper methods you might need are described below:
-
clearCalc()
This helper method should initialize the engine, display and other variables to represent the operation of the "C" (Clear) button. You will be using this method in the constructor and whenever "C" button is used. At this point, invoke this method from the constructor, use the tester class to execute the program and check whether variables have been initialized properly. Note: this method is similar in purpose to the setupGame() method from the Hangman assignment! -
addDigit()
This helper method updates the display when a digit-button is clicked. Some pseudocode for this method is below:get the current text on the display and store it as a local variable (e.g., newText) if length of newText < maximum allowed number of digits if we're starting a new number OR newText starts with "0" make newText the empty String to clear it append the pressed digit to the local text variable update the display to have newText
You can use the
getText()
andsetText()
methods to get and set the text of the JTextField.Note: You can use a boolean variable to keep track of whether you are starting a new number or not! You start a new number (set to true) when the program begins and when any operation or the "clear" button is pressed. You need to mark that you are NOT starting a new variable (set to false) when any digit or decimal button is pressed.
-
addDecimal()
This helper method adds a decimal point to the number on the display. The method will look really similar toaddDigit()
, one except that instead of checking if you have hit the maximum number of digits, you will be checking whether the number on the display already contains a "." (there are methods in the String class that to find whether a String contains a character or String---we've used some of them before! If the number already has a decimal point, what should you do? -
getDisplayValue()
This helper method converts the number on the display from String type to a double type, returning the number as a double. For the conversion, you can use the parseDouble() static method in the Double class. A sample use of the method is shown below:String str = new String("3.142"); double value = Double.parseDouble(str);
-
Calling
applyOperation()
This method is defined in the Calculator class. It takes two parameters: the first is a double representing the value of the operand (e.g., the number currently displayed on the calculator). The second is an integer representing the operation. You can use the constants defined in the Calculator class (e.g.,Calculator.ADD
) for this second parameter.
-
Submitting
- Once you are sure that your program works, make sure that both your and your partner's names are in a class comment at the top of the file. Then submit your program to the submissions folder.
- Upload your entire BlueJ project folder to the LabJ folder on the submission folder on hedwig. Make sure you upload your work to the correct folder! The lab is due at midnight on the day of the lab.
- Pretty, pretty please fill out the lab partner evaluation on Moodle?
Grading
This assignment will be graded on approximately the following criteria:
- Implementing the constructor with display and buttons layed out using layout managers [25%]
- Having necessary steps for event handling [15%]
- Completed actionPerformed() method [20%]
- clearCalc() method [5%]
- addDigit() method [10%]
- addDecimal() method [5%]
- getDisplayValue() method [5%]
- You have used good programming style and documentation [10%]
- You completed your lab partner evaluation [5%]