CS212 - Brief Introduction to Writing Java Code that has a Graphical User Interface

This workshop will probably take about one hour.

  1. Go to the website:http://java.sun.com/docs/books/tutorial/ui/features/components.html and browse to see what you can do
  2. Start eclipse on gaul by typing eclipse or on windows by clicking on the icon OR on windows by select Eclipse from the programs list
  3. Do File>New>Project>Java Project, give it any project name you want, then finish
  4. Do File>New>Class Call your class Simple1, make sure it has public static void main
  5. In Simple1, create a simple gui, (copy and paste the code below) into that file. This will have a frame (this is your outer window), a panel inside your frame that holds components, in this case 2 components (2 buttons),  this code does the following:
    1. Creates a frame
    2. Creates a panel
    3. Creates 2 buttons
    4. Puts the panel inside the frame
    5. Puts the buttons inside the panel
    6. Add listeners for the 2 buttons
    7. Does something if either of the buttons is pressed
    8. Makes the frame visible


Sample code:
 

/*
* Simple1.java - an example of handling events.
* For this example, we implement a single ActionListener
* which is then used to catch all events. A series of ifs
* are used to determine which object caused the event.
*/

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Simple1
{
    private static JFrame frame; // static so main can use it
    private static JPanel myPanel; // panel for the contentPane
    private JButton button1; // Define out here to make
    private JButton button2; // visible to ActionListener

    public Simple1() // Construct, build GUI
    {
        // Create a panel
        myPanel = new JPanel();
        // Create the buttons.
        button1 = new JButton("Button 1"); // Create buttons
        button2 = new JButton("Button 2");

        SimpleListener ourListener = new SimpleListener();
        // Set action listener for both buttons to share
        button1.addActionListener(ourListener);
        button2.addActionListener(ourListener);

        myPanel.add(button1); // Adds to current JFrame
        myPanel.add(button2);
    }

    private class SimpleListener implements ActionListener
    {
    /*
    * We will use a simple inner class to implement an
    * ActionListener to use to get the button events. We
    * could have instead used the Simple1 class itself to
    * implement ActionListener instead, but this way is
    * more consistent with the other examples.
    */

        public void actionPerformed(ActionEvent e)
        {
        // We will use getActionCommand to get the button
        // name, but we could use getSource() instead and
        // the if tests would then be like:
        // if (e.getSource() == button1) etc.

            String buttonName = e.getActionCommand();
            if (buttonName.equals("Button 1"))
                  JOptionPane.showMessageDialog(frame, "Button 1 pressed");
            else if (buttonName.equals("Button 2"))
                  JOptionPane.showMessageDialog(frame,"Button 2 pressed");
            else
                 JOptionPane.showMessageDialog(frame,"Unknown event");
         }
      }

     public static void main(String s[])
     {
          Simple1 gui = new Simple1(); // Create Simple1 component

          frame = new JFrame("Simple1"); // JFrame for the panel
          // Standard idiom to catch close event
          frame.addWindowListener(new WindowAdapter() {
               public void windowClosing(WindowEvent e)
                         {System.exit(0);} });

          frame.getContentPane().add(myPanel);
          frame.pack(); // Ready to go
          frame.setVisible(true);
     }
} //from The essence of OO programming with java and uml by wampler

  1. Save the code (save the code will display any syntax errors you have, if you just cut and pasted the code from above, you should NOT have any syntax errors). Then run the program to see what is displayed.NOTE: The first time you run it, run it from the Menu Bar (dont use the button on the tool bar), to run it from the menu bar: select Run>Run As>Java Application
  2. See if you can figure out how to change the buttons background colour and foreground colour. Hint: go to the java api for javax.swing. Then look up JButton and find the method that will set the background color...I have bolded the words that might help you find the correct methods ;-), they are methods from the JComponent class that are inherited by the JButton class. You might want to use the static Color class constants for the colours you want, for example Color.BLACK). Set the background color BEFORE the button is added to panel. Hint: In Eclipse, if you type slowly, after you hit a period, you will see available methods for that object. For example, type button1. and then wait for a second after hitting the period and you will see some methods pop up, then continue typing like this button1.s (just the s) and you will see all methods that start with s. Try this also with Color.
  3. See if you can figure out how to add a menu: Hint: create a JMenuBar (this is a menu bar at the top of a window) and attach it to the frame, create a JMenu (this would be like the File menu or the Edit menu) object, create some JMenuItem objects (these would be like the New, Open, Print, Print Preview or Exit inside the File menu)  and add them to the JMenu, attach the JMenu object to the JMenuBar. I had to make the JMenuBar static (like my JFrame) and construct it (using new) inside the main, then I had to use a command setJMenuBar from the frame inside the main. HINT: when you use the new command to create a JMenu or JMenuItem, make sure you put the name you want as a parameter, for example: printMenu= new JMenuItem("Print"); or else it wont show up on the menu bar. After you get the menu displaying, try adding a separator (addSeparator)
  4. Add an exit menu item and make the code quit when the user its that menu item. Hint: System.exit(0); will cause the code to quit, so this is the action you want to occur when the user picks the exit option from the menu. (remember to tell the Exit JMenuItem to listen by adding an actionlistener to it, like was done for the JButtons, also a menuitem is considered a button, so you can just add onto the if that is checking the buttonName and see if the has the same text as your Exit menuitem )
  5. Add 3 more buttons. Make one of the buttons change the colour of the background of myPanel. Hint: not only will you need to define the buttons and created them and add them, to make one of the buttons change the background colour, but you will need to add an action listener. When testing the new button, try resizing the window FIRST, then set the background colour. Notice that the buttons dont resize.
  6. We are now going to try moving the buttons around. Change the code as follows and then try resizing the windows and try clicking on your button to change the background.
myPanel = new JPanel();
myPanel.setLayout(new BorderLayout());
myPanel.add(button1, BorderLayout.NORTH); // Adds to current JFrame
myPanel.add(button2, BorderLayout.EAST);
myPanel.add(button3, BorderLayout.WEST);
myPanel.add(button4, BorderLayout.CENTER);
myPanel.add(button5, BorderLayout.SOUTH);
  1. Now change the line: myPanel.setLayout(new BorderLayout()); to be myPanel.setLayout(new BorderLayout(10,20));  save the program, run it again and click on your background button.
  2. Now change that line to: myPanel.setLayout(new GridLayout(1,5)); and run the program and try resizing the window, TRY MAXIMIZING YOUR WINDOW.
  3. Now change that line to: myPanel.setLayout(new GridLayout(5,1)); and run the program
  4. Now change that line to: myPanel.setLayout(new GridLayout(5,1,10,20)); and run the program
  5. Now change that line to: myPanel.setLayout(new GridLayout(3,5)); and run the program
  6. Now change that line to: myPanel.setLayout(new GridLayout(4,6)); and run the program
  7. Now add the following pieces of code in the appropriate places:
private JPanel myInnerPanel;

myInnerPanel = new JPanel();
myInnerPanel.setLayout(new BorderLayout(10,10));

myPanel.add(button1); // Adds to current JFrame
myPanel.add(button2);
myPanel.add(myInnerPanel);
myInnerPanel.add(button3, BorderLayout.WEST);
myInnerPanel.add(button4, BorderLayout.CENTER);
myInnerPanel.add(button5, BorderLayout.SOUTH);


19. Try changing the GridLayout rows and columns and see what happens (try 3,1 then try 1, 3, then try 2,2)

20. Create a new class called Simple2.java (copy the code below) and watch how the action listeners work.

/*
* Simple2.java - an example of handling events.
* For this example, we will use anonymous inner classes to
* implement an ActionListener for each button. This approach
* can avoid long switch-type if statements from the approach
* used in the Simple1 example.
*/

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Simple2
{
     private static JFrame frame; // static so main can use it
     private static JPanel myPanel; // panel for the contentPane
     private JButton button1; // Define out here to make
     private JButton button2; // visible to ActionListeners

     public Simple2() // Construct, build GUI
     {
          // Create a panel
          myPanel = new JPanel();
          // Create the buttons
          button1 = new JButton("Button 1");
          button2 = new JButton("Button 2");

          // For each component that needs a listener, define an
          // anonymous inner class to implement ActionListener
          button1.addActionListener(
             new ActionListener()
             {
               public void actionPerformed(ActionEvent e)
               {
                    JOptionPane.showMessageDialog(frame,"Button 1 pressed");
               }
             }
          );

          button2.addActionListener(
             new ActionListener()
             {
                 public void actionPerformed(ActionEvent e)
                 {
                   JOptionPane.showMessageDialog(frame, "Button 2 pressed");
                 }
             }
        );


        myPanel.add(button1); // Adds to current JFrame
        myPanel.add(button2);
     }

     public static void main(String s[])
     {
          Simple2 gui = new Simple2(); // Create Simple2 component

          frame = new JFrame("Simple2"); // JFrame for the panel
          // Standard idiom to catch close event
          frame.addWindowListener(new WindowAdapter() {
          public void windowClosing(WindowEvent e)
               {System.exit(0);} });
          frame.getContentPane().add(myPanel);
          frame.pack(); // Ready to go
          frame.setVisible(true);
     }
}

21. Now create a new class called Simple3.java (copy the code below). NOTE: Simple3 is the most flexible way to handle events.

/*
* Simple3.java - an example of handling events.
* For this example, we will use inner member classes to
* implement an ActionListener for each button. This approach
* can avoid some of the code clutter that anonymous classes
* can sometimes cause. It also concentrates the action code
* all in one place, and allows synonyms.
*/

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Simple3 extends JPanel
{
    private static JFrame frame; // static so main can use it
    private static JPanel myPanel; // a panel for contentPane
    private JButton button1; // Define out here to make
    private JButton button2; // visible to ActionListener

    // Define handlers for each event needed (button1, button2)
    private class Button1Handler implements ActionListener
    {
            public void actionPerformed(ActionEvent e)
            {
                    JOptionPane.showMessageDialog(frame,"Button 1 pressed");
            }
    }

    private class Button2Handler implements ActionListener
    {
            public void actionPerformed(ActionEvent e)
            {
                    JOptionPane.showMessageDialog(frame,"Button 2 pressed");
            }
    }


    public Simple3() // Construct, build GUI

    {
        // Create a panel
        myPanel = new JPanel();
        // Create the buttons
        button1 = new JButton("Button 1");
        button2 = new JButton("Button 2");

        // For each component add it ActionListener class
        button1.addActionListener(new Button1Handler());
        button2.addActionListener(new Button2Handler());

        myPanel.add(button1); // Adds to current JFrame
        myPanel.add(button2);
    }

    public static void main(String s[])

    {
        Simple3 gui = new Simple3(); // Simple3 component

        frame = new JFrame("Simple3"); // JFrame for the panel
        // Standard idiom to catch close event
        frame.addWindowListener(new WindowAdapter() {
        public void windowClosing(WindowEvent e)
                {System.exit(0);} });

        frame.getContentPane().add(myPanel);
        frame.pack(); // Ready to go
        frame.setVisible(true);
    }
}

 

More GUI Stuff --> Something fun, adding a slider

1. Edit the Simple3.java class file from above that you have already copied. NOTE: This is the way you SHOULD be doing your event handling, not the way it was done in Simple1.java MAKE SURE YOU CHANGE TO THE JAVA PERSPECTIVE IN ECLIPSE

2. Add a slider bar. I will give you the code, you have to figure out where it should go! Here are the pieces you will need to add (you just need to figure out where to put them AND you need to write the code to add the slider to the panel.)

import javax.swing.event.*;

private JSlider redSlider;

redSlider = new JSlider();
redSlider.setOrientation(JSlider.VERTICAL);
redSlider.setPaintLabels(true); //show tick mark labels
redSlider.setPaintTicks(true); //show tick marks
redSlider.setMinimum(0);
redSlider.setMaximum(255);
redSlider.setValue(100);
redSlider.setMajorTickSpacing(50);
redSlider.setMinorTickSpacing(25);
redSlider.addChangeListener(new SliderHandler());

private class SliderHandler implements ChangeListener {
    public void stateChanged(ChangeEvent event) {
          int r;
          r=redSlider.getValue();
          myPanel.setBackground(new Color(r,0,0));
    }
    }

 

3.After you get your red slider bar working, try adding a green and blue one!

 

More GUI Stuff -->Changing the color of groups of buttons/components

1. One fairly simple way to change the look of your window is to change the background and foreground of all the buttons/menu bars items/panels etc. on the window. For example, for a sunset theme, you might set the foreground to be red and the background to be yellow for some of the components on your window. One way to implement this, is to add all the components (buttons, etc) that you wish to change, to a bag/collections and then everytime you want to change the look, you just use an iterator to walk through the collection and change the colors. We are going to do this with Simple3 (and the sliders that you added).

2. Add the following code in the correct locations to get access to a linkedlist where we will store all the buttons:
import java.util.*;
private LinkedList itemsForSkin;

3. Add the code to construct the LinkedList and add code similar to this: itemsForSkin.add(button1) to add ALL the components whose look you wish to change to the LinkedList (we will add the 2 buttons and the 3 sliders you made)

4. Add the following code in the appropriate location, so that when the user clicks on button2, the foreground and background of the buttons and sliders change as indicated in the code: (NOTE: this code walks through all the items in the linkedlist and changes them all to have a foreground color of BLUE, also add the line of code needed to make sure the items have a background color of RED)

private Iterator itr;
JComponent holder;
itr = itemsForSkin.iterator();
while (itr.hasNext()) {
holder = (JComponent) itr.next();
holder.setBackground(Color.BLUE);
}