INFORMATION & COMPUTER SCIENCE DEPARTMENT, KFUPM

ICS201, SECTIONS 52  (002 Semester)

INTRODUCTION TO COMPUTER SCIENCE

LAB  #05 Further GUI and Event Handling

 

Instructor: Bashir M. Ghandi

 


Objectives:

To gain experience with:

 

1.                  Using Layout managers to organize GUI components on a frame.

Java provides a number of Layout managers which can be used to layout GUI components on a frame.  The following diagram shows some of the most commonly used layout managers.

 

Each of these layout managers has its purpose so that most of the times we need to combine them to achieve the desired effect.

 

For example, what layout managers do we need in order to get the following interface?   Also how do we combine them to get the desired effect?

 

Example 1:  The figure above is the output of the following program.  Examine it carefully to understand how the how the various managers are combined, then test-run it to see the output.

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import javax.swing.border.*;

import javax.swing.event.*;

 

public class FlightReservation extends JFrame {

 

  public FlightReservation() {

    super("Flight Reservation Dialog");

    setSize(400, 300);

 

    JPanel p1 = new JPanel();

    p1.setLayout(new BoxLayout(p1, BoxLayout.X_AXIS));

 

    JPanel p1r = new JPanel();

    p1r.setBorder(new EmptyBorder(10,10,10,10));

 

    JPanel p11 = new JPanel();

    p11.setLayout(new GridLayout(3, 1));

   

    JPanel p12 = new JPanel();

    p12.setLayout(new GridLayout(3, 1));

 

    p11.add(new JLabel("Date:"));

    p12.add(new JTextField());

   

    p11.add(new JLabel("From:"));

    JComboBox cb1 = new JComboBox();

    cb1.addItem("Dammam");

    cb1.addItem("Madinah");

    cb1.addItem("Makkah");

    cb1.addItem("Riyadh");

    p12.add(cb1);

   

    p11.add(new JLabel("To:"));

    JComboBox cb2 = new JComboBox();

    cb2.addItem("Riyadh");

    cb2.addItem("Makkah");

    cb2.addItem("Madinah");

    cb2.addItem("Dammam");

    p12.add(cb2);

   

    p1r.setLayout(new BorderLayout());

    p1r.add(p11, BorderLayout.WEST);

    p1r.add(p12, BorderLayout.CENTER);

    p1.add(p1r);

 

    JPanel p3 = new JPanel();

    p3.setLayout(new GridLayout(3, 1));

    p3.setBorder(new TitledBorder("Options"));

 

    ButtonGroup group = new ButtonGroup();

    JRadioButton r1 = new JRadioButton("First class");

    group.add(r1);

    p3.add(r1);

 

    JRadioButton r2 = new JRadioButton("Business");

    group.add(r2);

    p3.add(r2);

 

    JRadioButton r3 = new JRadioButton("Economy");

    group.add(r3);

    p3.add(r3);

 

    p1.add(p3);

     

    getContentPane().add(p1, BorderLayout.NORTH);

 

    JPanel p2 = new JPanel(new BorderLayout());

    p2.setBorder(new TitledBorder("Available Flights"));

     

    JTextArea text = new JTextArea();

    JScrollPane ps = new JScrollPane(text);

 

    p2.add(ps, BorderLayout.CENTER);

    getContentPane().add(p2, BorderLayout.CENTER);

 

    JPanel p4 = new JPanel();

    JPanel p4c = new JPanel();

    p4c.setLayout(new GridLayout(1, 3));

       

    JButton b1 = new JButton("Search");

    p4c.add(b1);

       

    JButton b2 = new JButton("Purchase");

    p4c.add(b2);

       

    JButton b3 = new JButton("Exit");

    p4c.add(b3);

 

    p4.add(p4c);

    getContentPane().add(p4, BorderLayout.SOUTH);

  }

 

  public static void main(String argv[]) {

    FlightReservation frame = new FlightReservation();

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  /Version 1.3

    frame.show();

  }

}

 

2.         Adding menu bar, menu items and pop-up menu to a frame.

The following figure shows the inheritance hierarchy for the menu-related classes:

 

As the figure shows, menu items (including menus) are simply buttons.  Thus, to detect when the user selects a JMenuItem, you can listen for action events (just as you would for a JButton).

To detect when the user selects a JRadioButtonMenuItem, you can listen for either action events or item events, just as for Radio buttons.

For JCheckBoxMenuItems, you generally listen for item events, just as is the case for Check boxes.

 

The following example is an extension of HandlingMenuEvents.java example of Lecture 5.   Few new things are introduced as explained below:

JScrollPane :  This provides a scrollable view of a component. When screen real estate is limited, use a JScrollPane to display a component that is large or one whose size can change dynamically.

 

JPopupMenu: This used for the menu that appears when the user selects an item on the menu bar. It is also used for "pull-right" menu that appears when the user selects a menu item that activates it. Finally, it can also be used anywhere else you want a menu to appear. For example, when the user right-clicks in a specified area.

 

ButtonGroup: This class is used to create a multiple-exclusion scope for a set of buttons. Creating a set of buttons with the same ButtonGroup object means that turning "on" one of those buttons turns off all other buttons in the group.

 

ItemListener:  This interface has just one method, so it has no corresponding adapter class. Here's the method:

            void itemStateChanged(ItemEvent)

The method is called just after a state change in the listened-to component.

The Swing components that generate ItemEvents include check boxes, check box menu items, and combo boxes

 

setAccelerator(): sets the KeyStroke which serves as an accelerator for the menu item.  Here is the example:

 

Example 2:

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;;

 

public class PopupMenuDemo extends JFrame

                           implements ActionListener, ItemListener {

    JTextArea output;

    JScrollPane scrollPane;

    String newline = "\n";

    JPopupMenu popup;

 

    public PopupMenuDemo() {

        JMenuBar menuBar;

        JMenu menu, submenu;

        JMenuItem menuItem;

        JRadioButtonMenuItem rbMenuItem;

        JCheckBoxMenuItem cbMenuItem;

 

        //Add regular components to the window, using the default BorderLayout.

        Container contentPane = getContentPane();

        output = new JTextArea(5, 30);

        output.setEditable(false);

        scrollPane = new JScrollPane(output);

        contentPane.add(scrollPane, BorderLayout.CENTER);

 

        //Create the menu bar.

        menuBar = new JMenuBar();

        setJMenuBar(menuBar);

 

        //Build the first menu.

        menu = new JMenu("A Menu");

        menu.setMnemonic(KeyEvent.VK_A);

        menuBar.add(menu);

 

        //a group of JMenuItems

        menuItem = new JMenuItem("A text-only menu item",

                                 KeyEvent.VK_T);

        //menuItem.setMnemonic(KeyEvent.VK_T); //used constructor instead

        menuItem.setAccelerator(KeyStroke.getKeyStroke(

                KeyEvent.VK_1, ActionEvent.ALT_MASK));

        menuItem.addActionListener(this);

        menu.add(menuItem);

        menuItem = new JMenuItem("Both text and icon",

                                 new ImageIcon("images/middle.gif"));

        menuItem.setMnemonic(KeyEvent.VK_B);

        menuItem.addActionListener(this);

        menu.add(menuItem);

        menuItem = new JMenuItem(new ImageIcon("images/middle.gif"));

        menuItem.setMnemonic(KeyEvent.VK_D);

        menuItem.addActionListener(this);

        menu.add(menuItem);

 

        //a group of radio button menu items

        menu.addSeparator();

        ButtonGroup group = new ButtonGroup();

        rbMenuItem = new JRadioButtonMenuItem("A radio button menu item");

        rbMenuItem.setSelected(true);

        rbMenuItem.setMnemonic(KeyEvent.VK_R);

        group.add(rbMenuItem);

        rbMenuItem.addActionListener(this);

        menu.add(rbMenuItem);

        rbMenuItem = new JRadioButtonMenuItem("Another one");

        rbMenuItem.setMnemonic(KeyEvent.VK_O);

        group.add(rbMenuItem);

        rbMenuItem.addActionListener(this);

        menu.add(rbMenuItem);

 

        //a group of check box menu items

        menu.addSeparator();

        cbMenuItem = new JCheckBoxMenuItem("A check box menu item");

        cbMenuItem.setMnemonic(KeyEvent.VK_C);

        cbMenuItem.addItemListener(this);

        menu.add(cbMenuItem);

        cbMenuItem = new JCheckBoxMenuItem("Another one");

        cbMenuItem.setMnemonic(KeyEvent.VK_H);

        cbMenuItem.addItemListener(this);

        menu.add(cbMenuItem);

 

        //a submenu

        menu.addSeparator();

        submenu = new JMenu("A submenu");

        submenu.setMnemonic(KeyEvent.VK_S);

 

        menuItem = new JMenuItem("An item in the submenu");

        menuItem.setAccelerator(KeyStroke.getKeyStroke(

                KeyEvent.VK_2, ActionEvent.ALT_MASK));

        menuItem.addActionListener(this);

        submenu.add(menuItem);

 

        menuItem = new JMenuItem("Another item");

        menuItem.addActionListener(this);

        submenu.add(menuItem);

        menu.add(submenu);

 

        //Build second menu in the menu bar.

        menu = new JMenu("Another Menu");

        menu.setMnemonic(KeyEvent.VK_N);

        menu.getAccessibleContext().setAccessibleDescription(

                "This menu does nothing");

        menuBar.add(menu);

 

        //Create the popup menu.

        popup = new JPopupMenu();

        menuItem = new JMenuItem("A popup menu item");

        menuItem.addActionListener(this);

        popup.add(menuItem);

        menuItem = new JMenuItem("Another popup menu item");

        menuItem.addActionListener(this);

        popup.add(menuItem);

 

        //Add listener to components that can bring up popup menus.

        MouseListener popupListener = new PopupListener();

        output.addMouseListener(popupListener);

        scrollPane.addMouseListener(popupListener);

        menuBar.addMouseListener(popupListener);

    }

 

    public void actionPerformed(ActionEvent e) {

        JMenuItem source = (JMenuItem)(e.getSource());

        String s = "Action event detected."

                   + newline

                   + "    Event source: " + source.getText()

                   + " (an instance of " + getClassName(source) + ")";

        output.append(s + newline);

    }

 

    public void itemStateChanged(ItemEvent e) {

        JMenuItem source = (JMenuItem)(e.getSource());

        String s = "Item event detected."

                   + newline

                   + "    Event source: " + source.getText()

                   + " (an instance of " + getClassName(source) + ")"

                   + newline

                   + "    New state: "

                   + ((e.getStateChange() == ItemEvent.SELECTED) ?

                     "selected":"unselected");

        output.append(s + newline);

    }

 

    // Returns just the class name -- no package info.

    protected String getClassName(Object o) {

        String classString = o.getClass().getName();

        int dotIndex = classString.lastIndexOf(".");

        return classString.substring(dotIndex+1);

    }

 

    public static void main(String[] args) {

        PopupMenuDemo window = new PopupMenuDemo();

 

        window.setTitle("PopupMenuDemo");

        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        window.setSize(450, 260);

        window.setVisible(true);

    }

 

    class PopupListener extends MouseAdapter {

        public void mousePressed(MouseEvent e) {

            maybeShowPopup(e);

        }

        public void mouseReleased(MouseEvent e) {

            maybeShowPopup(e);

        }

        private void maybeShowPopup(MouseEvent e) {

            if (e.isPopupTrigger()) {

                popup.show(e.getComponent(),

                           e.getX(), e.getY());

            }

        }

    }

}

 

 

3.    Handling Focus Event.

Focus events are generated whenever a component gains or loses the keyboard focus. Exactly how components gain the focus depends on the window system. Typically, the user sets the focus by clicking a window or component, by tabbing between components. 

In order to respond to Focus events, a class must implement the FocusListener interface which has two methods:

    void focusGained(FocusEvent):Called just after the listened-to component gets the focus.

    void focusLost(FocusEvent): Called just after the listened-to component loses the focus.

 

Example 3:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class HandlingFocusEvents extends JFrame implements FocusListener{
    private JPanel p  = new JPanel();
    private JTextArea ta = new JTextArea();
 
    private JButton g1, g2, g3, g4;
 
    HandlingFocusEvents(){
        super("Testing Fucus Event");
        setSize(300,300);
        Container cp = getContentPane();
        p.setLayout(new GridLayout(2,2));
        p.add(g1=new JButton("Grid 1"));
        p.add(g2=new JButton("Grid 2"));
        p.add(g3=new JButton("Grid 3"));
        p.add(g4=new JButton("Grid 4"));
        cp.add(p, "North");
        
        ta.setBackground(Color.cyan);
        cp.add(ta, "Center");
        ta.addFocusListener(this);
        
        g1.addFocusListener(this);
        g2.addFocusListener(this);
        g3.addFocusListener(this);
        g4.addFocusListener(this);
    }
    
    public void focusGained(FocusEvent e){
              if (e.getComponent()==g1) 
                        ta.setText("Grid 1 gains Focus");
              else if (e.getComponent()==g2) 
                        ta.setText("Grid 2 gains Focus");
              else if (e.getComponent()==g3) 
                        ta.setText("Grid 3 gains Focus");
              else if (e.getComponent()==g4) 
                        ta.setText("Grid 4 gains Focus");
              else if (e.getComponent()==ta) 
                        ta.setText("Text Area gains Focus");
     }
     
    public void focusLost(FocusEvent e) {
    }
     
    public static void main(String args[]){
        HandlingFocusEvents frame = new HandlingFocusEvents();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.show();        
    }
}

 

 

4.            Assignment.

1.             Write an application to display the GUI of a calculator exactly as shown by the following figure.  Please do NOT  to handle the events generated by the buttons at this point.

 

2.             Modify your program in (1) above by adding two menus as shown below .  Also add a popup menu to display the same options as for the View menu.:

 

            A gain, you do not need to handle any event at this point.

 

  1. Now improve your program in (2) so by handling the basic arithmetic operations (do not worry about M+, M-, etc).