In this lab, you will learn two ways to create a graphical user interface (GUI): By writing the code directly (Part 2) and by using the Netbeans GUI Builder (Part 1). Feel free to do these in whichever order you prefer. After completing Parts 1 and 2, you will create a GUI for your Make Change program.
The goal of this lab is for you to create a GUI for a simplified version of your Make Change program as displayed here. The user enters an amount, presses the compute button, and the program calculates and diplays the number of dollars and coins cooresponding the amount entered.
However, before attempting this assignment, you need to learn about how to make GUIs. To do this, work through Parts 1 and 2 below. Once you are familiar with creating a GUI you can begin work on your Make Change program.
![]() | Make Change Program - you will need: 8 labels, 1 textfield, and 1 button. Add an action listener to the button. The calculations can be done in the ActionPerformed method for the button. Please remember to rename your components when using the GUI Builder. |
To receive full credit, you need to:
Make sure that your Java code:
Demonstrate your program to the instructor or lab assistant during the lab on the due date. You will be asked to display your commented/formatted code and to run the code on a few inputs.
Submit your code as attachments to Lab 6 in Wise.
![]() | Part 1: Using the Netbeans GUI Builder:
|
The two videos below show how to create a temperature conversion program using the Netbeans GUI Builder:
It is suggested that you follow along in Netbeans as you watch the video. The video makes reference to some of the concepts discussed in the sections below where you create an interface by hand. However, you may prefer to do this part first.![]() | Part 2: Creating a GUI by Hand |
Create a new Netbeans project containing a class containing the main method. Modify main to be the following:
public static void main(String[] args) {
JFrame myFrame = new JFrame("My Window Title"); // you will need to "fix imports"
myFrame.setSize(400, 300); // sets the size of the window
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Closing the window will stop the program.
myFrame.setVisible(true); // Make the window visible.
}
Run the program. It should create a window. You can close the window by clicking on the "x". Try commenting out some of the above lines containing myFrame.xxx to see how it changes the program.
The above program will create a window with the title "My Window Title", but the window doesn't do or contain anything. In order to add items to the window, you need to "extend" the JFrame class. This will allow you to add keep all of the functionality of the JFrame class while also adding your own functionality. To do this, add a new Java class to your Netbeans project and name it something like, MyJFrame. Modify your new class by adding "extends JFrame" as shown here:
public class MyJFrame extends JFrame {
}
You will also need to "fix imports".
Now, back in main, modify your original code by changing the one line
JFrame myFrame = new JFrame();
to have the name of your new class:
MyJFrame myFrame = new MyJFrame();
Run the code. It should be identical to your previous code. That is because, MyJFrame is really the same as a JFrame, because it extends it.
Now, let's start to modify MyJFrame. The first thing to do is to add a constructor (this will take the place of the JFrame's constructor). In the constructor, we will place all the initialization that was originally placed in main. Thus main becomes:
public static void main(String[] args) {
MyJFrame myFrame = new MyJFrame("My Window Title");
}
and the constructor in MyJFrame is:
public MyJFrame(String title) {
super(title); // this calls the original JFrame constructor in order to set the title
setSize(400, 300); // sets the size of the window
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Closing the window will stop the program.
setVisible(true); // Make the window visible.
}
Run the code to see that, once again, nothing has changed!
Before continuing, read the section in your text "Adding Components to a Window" on page 758.
Now, lets add a component (e.g. buttons, labels, textfields, etc) . Let's start with a Label. We first want to add a Label object as a member variable and initialize it in the constructor:
public class MyJFrame extends JFrame {
private JLabel messageLabel;
public MyJFrame(String title) {
super(title);
setSize(400, 300); // sets the size of the window
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Closing the window will stop the program.
messageLabel = new JLabel("This is a message"); // creates the Label object
add(messageLabel); // adds the Label to the window
setVisible(true); // Make the window visible.
}
}
Run the code to see that the message is now written in the window.
public class MyJFrame extends JFrame {
private JLabel messageLabel;
private JButton myButton;
public MyJFrame(String title) {
super(title);
setSize(400, 300); // sets the size of the window
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Closing the window will stop the program.
messageLabel = new JLabel("This is a message");
add(messageLabel);
myButton = new JButton("Click Here!");
myButton.setBackground(Color.red);
add(myButton);
setVisible(true); // Make the window visible.
}
}
But when you run this, all you will see is the button. If you flip the order of the button and label code,
all you will see is the label. This is because one component overlays the other. In order to have them
placed in different places in the window, we need to specify a LayoutManager. The default one is called a
BorderLayout Manager. A picture of it is given on page 785 in figure 11-26. The window is divided into
5 distinct regions. We will modify our code above to place the label in the west region and the button in the east
region. Since the other regions are not used, their size is shrunk to zero, i.e. the west and east will fill the
entire window. Here constructor code now contains:
public MyJFrame(String title) {
super(title);
setSize(400, 300); // sets the size of the window
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Closing the window will stop the program.
messageLabel = new JLabel("This is a message");
add(messageLabel,java.awt.BorderLayout.WEST);
myButton = new JButton("Click Here!");
myButton.setBackground(Color.red);
add(myButton,java.awt.BorderLayout.EAST);
setVisible(true);
}
Run the code. You should get:Try changing the locations of the components, e.g. use NORTH and SOUTH.
Add 3 more labels and/or buttons so that you have a total of 5. Place them in different sections of the
layout. Note, you can only have one component per region of the layout manager, e.g. you can't put 2 components in the
SOUTH area - if you do, only one will show.
For example:
Textfields enable a user to enter data. You can create one just like you did the button and label. For example, in the above code, the blue button is replaced with a textfield. The code for the textfield member variable is:
private JTextField myTextField;
and in the constructor, create the textfield object and add it to the frame:
myTextField = new JTextField("This is a text field");
add(myTextField,java.awt.BorderLayout.WEST);
to give:myButton2 = new JButton("My green button.");
myButton2.setBackground(Color.green);
add(myButton2,java.awt.BorderLayout.CENTER);
myButton2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
Color color = new Color((int) (256*Math.random()), (int) (256*Math.random()),(int) (256*Math.random()) );
myButton2.setBackground(color);
}
});
Modify the code for one of your buttons to look like the above. Run the code to test that it works. When you click on the button, it should change color.
Note, the above code is a little more compact than what was done in the text and it is a little hard to parse given all of the parentheses and brackets, so let's break it down. First, we want to add an actionListener object to myButton2. To do this we call the method addActionListener:
myButton2.addActionListener(we need an ActionListener object here!);
Inside of the parentheses, we need an ActionListener object as an argument. Your textbook creates a private class (e.g. called CalcButtonListener). What we do here instead, is to create an unnamed class right inside of the parentheses. If you look at the code closely, you will see that the entire following code is the argument for the addActionListener method:
new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
Color color = new Color((int) (256*Math.random()), (int) (256*Math.random()),(int) (256*Math.random()) );
myButton2.setBackground(color);
}
}
It creates an unnamed ActionListener object that has a method called actionPerformed:
public void actionPerformed(java.awt.event.ActionEvent evt) {
Color color = new Color((int) (256*Math.random()), (int) (256*Math.random()),(int) (256*Math.random()) );
myButton2.setBackground(color);
}
The action we want to perform (changing the color of the button) is written inside of the actionPerformed method:
Color color = new Color((int) (256*Math.random()), (int) (256*Math.random()),(int) (256*Math.random()) );
myButton2.setBackground(color);
The complete final code for the above is here:
import java.awt.Color;
import java.awt.event.ActionEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
public class MyJFrame extends JFrame {
private JLabel messageLabel1;
private JLabel messageLabel2;
private JButton myButton1;
private JButton myButton2;
private JTextField myTextField;
public MyJFrame(String title) {
super(title);
setSize(400, 300); // sets the size of the window
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Closing the window will stop the program.
messageLabel1 = new JLabel("Here is message 1");
add(messageLabel1, java.awt.BorderLayout.NORTH);
messageLabel1 = new JLabel("Here is message 2");
add(messageLabel1, java.awt.BorderLayout.SOUTH);
myButton1 = new JButton("My green red.");
myButton1.setBackground(Color.red);
add(myButton1, java.awt.BorderLayout.EAST);
myButton2 = new JButton("My green button.");
myButton2.setBackground(Color.green);
add(myButton2, java.awt.BorderLayout.CENTER);
myButton2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
Color color = new Color((int) (256 * Math.random()), (int) (256 * Math.random()), (int) (256 * Math.random()));
myButton2.setBackground(color);
}
});
myTextField = new JTextField("This is a text field");
add(myTextField, java.awt.BorderLayout.WEST);
setVisible(true);
}
}
The Netbeans GUI Builder organizes its code into separate methods (just like you did for your Expert system). Let's rearrange the above code to better match what you will see in the GUI Builder. First, we create a private method called initComponents where all of the components are initialized. This method is called from the JFrame constructor. Next, we move the contents of myButton2's actionPerformed method into a separate private method called myButton2ActionPerformed. The result is closer to (but not exactly equal to) what you will see in the GUI Builder. Carefully study how things were moved around. No new functionality has been added, rather instructions have just been moved around. New method calls are in red. The new method headers are in green.
import java.awt.Color;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
public class MyJFrame extends JFrame {
private JLabel messageLabel1;
private JLabel messageLabel2;
private JButton myButton1;
private JButton myButton2;
private JTextField myTextField;
public MyJFrame(String title) {
super(title);
setSize(400, 300); // sets the size of the window
initComponents();
setVisible(true);
}
private void initComponents() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Closing the window will stop the program.
messageLabel1 = new JLabel("Here is message 1");
add(messageLabel1, java.awt.BorderLayout.NORTH);
messageLabel1 = new JLabel("Here is message 2");
add(messageLabel1, java.awt.BorderLayout.SOUTH);
myButton1 = new JButton("My green red.");
myButton1.setBackground(Color.red);
add(myButton1, java.awt.BorderLayout.EAST);
myButton2 = new JButton("My green button.");
myButton2.setBackground(Color.green);
add(myButton2, java.awt.BorderLayout.CENTER);
myButton2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
myButton2ActionPerformed(evt);
}
});
myTextField = new JTextField("This is a text field");
add(myTextField, java.awt.BorderLayout.WEST);
}
private void myButton2ActionPerformed(java.awt.event.ActionEvent evt) {
Color color = new Color((int) (256 * Math.random()), (int) (256 * Math.random()), (int) (256 * Math.random()));
myButton2.setBackground(color);
}
}
In the above example, when you press myButton2, the button changes color. We now show how to use a button to change value of another component. Specifically, myButton1 will copy the text from myTextField, and place it on the label messsageLabel1. That is, when you run the program, a user can enter text into myTextField, press myButton1 (the red one), and have the text appear on the label messageLabel1 (the bottom label).
To accomplish this, start with the modularized code above. Then add an action listener to myButton1:
myButton1 = new JButton("My green red.");
myButton1.setBackground(Color.red);
add(myButton1, java.awt.BorderLayout.EAST);
myButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
myButton1ActionPerformed(evt);
}
});
You next need to add the method called myButton1ActionPerformed. Place this method right before or after the method myButton2ActionPerformed.
private void myButton1ActionPerformed(java.awt.event.ActionEvent evt) {
String myText = myTextField.getText(); // get the text from the textfield
messageLabel1.setText(myText); // copy the text to the label
}
What this code does is to grab the text that appears in myTextField and then copy it into the text of the label. All of this happens when one presses myButton1. Try running it.
Whew! I know this is confusing! Unfortunately, GUI programming is complicated. We have used the above compact code because we soon want to use the Netbeans GUI Builder. It uses this kind of compact code. The Netbeans GUI Builder is drag-and-drop and writes the code for you. While you don't have to write the code yourself, you do need to understand what the code is doing, or at least, understand the portions of the code you need to modify to get the program to do what you want.