Button & Menu Components
Peter Komisar    ©     Conestoga College     latest version 5.8  /  2010


The Button Class Hierarchy 


The button family of components are controls that you 'click'
on. These include buttons, menus, checkboxes and radio
buttons. Most often the component will react to a mouse click
but can also be activated by key accelerators and the 'enter'
key. The 'action' object that is generated when a button
component is activated can be used in processing a response.

// mouse clicks, Enter key or key 'accelerators' , Ctrl or Alt + a letter

Following is the AbstractButton class hierarchy. This class
defines most of the characteristic behavior for the Button
family components. Subclasses are further customized. 
 

The Button Class Hierarchy

     Object
          |
 Component //  java.aw
          |
 Container
       |
JComponent   // javax.swing
         |
AbstractButton
         |
         |____JButton
         |____JMenuItem
         |                |
         |                |___JCheckBoxMenuItem
         |                |___JMenu
         |                |___JRadioButtonMenuItem
         |
         |____JToggleButton
                          |
                          |___JCheckbox
                          |___JRadioButton

  


AbstractButton


The AbstractButton class defines the core behavior for
the group of components that act as buttons. This includes
sub-classes like JButton, JMenuItem and JToggleButton.
The class is abstract so can't itself be instantiated.


AbstractButton Methods

AbstractButton defines a large number of methods that
are available to the subclasses including the methods
required to process actions.

// action processing methods are defined in AbstractButton

AbstractButton defines the addActionListener( ) method
that descendant classes use to register listeners. Button
listeners responds to the mouse being clicked. The method
addChangeListener( ) registers a ChangeListener object.

AbstractButton's Listener Registration Methods

// the top level abstract class supplies listener registration methods

ChangeListener is a new listener that comes in the
javax.swing.event package. It reacts to mouse over
actions, triggering when the button zone is entered
and exited.

Abstract button also includes the addItemListener( )
which is used to handle item events created by check,
toggle and combo box components.

doClick( )

The doClick( ) method programmatically performs a
click and an overloaded version of the method allows
specifying the amount of time the click lasts.

There are methods for positioning text and icons as
well as for setting enabled and disabled icons. Some
methods can be used to change the icon that is used
when the mouse rolls over the button. Following is a
sampling of these methods from the documentation
for AbstractButton. Check AbstractButton's extensive
list of methods in the JDK documentation.

Selected Abstract Button Click, Positioning & Icon Methods


Many of the methods defined in AbstractButton are used
'under the hood' by components for processing events.
For instance the following 'fire' methods notify a source
component's registered listeners that an action has
occurred. The calls to fire methods are  hidden away in
the component code  that is part of the JavaBean design
specification. 
 

Fire Methods of AbstractButton Used in the JavaBean Design

fireActionPerformed(ActionEvent event)
fireItemStateChanged(ItemEvent event)
fireStateChanged( )


Swing Is Expanded to Support HTML Labeling

While only single lines of text can be added by conventional
techniques, multi-line labels can be created for buttons using
work arounds as shown in code below using layout managers
or by using HTML code as the text parameters.  It is also
shown here that common escapes do not work in labels.

The doClick( ) method is demonstrated here as well in it's
form that allows contolling how long the button appears to be
depressed on clicking. The time is specified in milliseconds.


Multi-line Labeling Example

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

class OneButton extends JFrame implements ActionListener{
    JButton b1,b2,b3;  

    OneButton( ) {
     JPanel panel = new JPanel( );

    // first effort doesn't work using \n or escaped \\n    
 
     panel.setBackground(Color.darkGray);
     b1 = new JButton("Plain or \\n \n multi line button?");     
     b1.addActionListener(this);

     // JavaWorld work around

     b2 = new JButton();
     b2.setLayout(new BorderLayout());
     JLabel label1 = new JLabel("Your");
     JLabel label2 = new JLabel("Name");
     b2.add(BorderLayout.NORTH,label1);
     b2.add(BorderLayout.SOUTH,label2);

    // Swing components now support HTML
     
     b3 = new JButton("<html>Hello<p>World</html>");
      
           panel.add(b1);
           panel.add(b2);
           panel.add(b3);
     
      getContentPane().add(panel);
         
            setDefaultCloseOperation(EXIT_ON_CLOSE);
            setSize(600,200);
            setVisible(true);
            }
      public static void main(String[]args){
            new OneButton( );
            }

      // time dictates how long the button seems to be clicked.

      public void actionPerformed(ActionEvent ae){
          b2.doClick(2000);
          b3.doClick(2000);
          }
}



Abstract Button Descendants


JButton

A JButton is the stock component used to activate any
of a number of processes that might be useful when
using a GUI. When JButton is pressed an ActionEvent
is created. This event has to be processed in the
associated action method that provides a response to
the button being activated. We example this action
shortly.

JButtons can be plain or include icons. Like other
JComponents such as JLabel, icons can be added
via a constructor or after construction using the setIcon(  )
method. To demonstrate these examples on your
machine you will need to add images. I have added
a few small images to the following page.

Small Icon Images

http://www.sentex.net/~pkomisar/J2/Square.html

Example  

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

class ButtonDemo extends JFrame {
      ButtonDemo( ) {
        JPanel panel = new JPanel( );
         panel.setBackground(Color.darkGray);
     
            // setting the icon with the set method        
            Icon squareIcon = new ImageIcon("square.jpg");
            JButton sqButtonPlus = new JButton("Square" );
            sqButtonPlus.setIcon( squareIcon );
          
            // plain Vanilla button      
            JButton sqButton = new JButton("Plain");      
       
            // setting icon via the constructor
            Icon circleIcon = new ImageIcon("circle.jpg");
            JButton triButton = new JButton("Triangle", circleIcon);
           
            panel.add(sqButtonPlus);
            panel.add(sqButton);
            panel.add(triButton);
            getContentPane().add(panel);
          
            setDefaultCloseOperation(EXIT_ON_CLOSE);
            setSize(600,200);
            setVisible(true);
            }
      public static void main(String[]args){
            new ButtonDemo( );
            }
    }

JCheckBox 

A JCheckBox allows a user to make choices from a list
of selections. This component is the one to use when multiple
choices are allowed for a given item.  The following code
sample shows JCheckBox components in use. A convenient
technique is shown here, where a component is nested
in a panel to allow the component to remain it's preferred
size.

JCheckBox Example

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

 class CheckPanel extends JPanel {
       CheckPanel() {
       setLayout(new GridLayout(5, 1));
       JLabel jl=new JLabel("Pick desired features");
       add(jl);
       JCheckBox jcb1 = new JCheckBox("Automatic Transmission");
       JCheckBox jcb2 = new JCheckBox("Air Conditioning");
       JCheckBox jcb3 = new JCheckBox("CD player");

        jcb1.setSelected(true);

    /*  default is false. could omit next line  */
        jcb2.setSelected(false);   
        jcb3.setSelected(true);
        add(jcb1);
        add(jcb2);
        add(jcb3);

        // notice nesting a component in a panel with a default
           // flow layout allows it to remain it's preferred size

        JPanel nestPanel=new JPanel( );
        JButton next=new JButton("Next");
        nestPanel.add(next);
        add(nestPanel);
        }
   
     // added a main method with JFrame for convenience

    public static void main(String[]args){
      JFrame frame = new JFrame();
      frame.getContentPane( ).add(new CheckPanel( ));
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setSize(400,300);
      frame.setVisible(true);      
     }
  }

 
In the above code, it is possible any number of the
selections to true using the setSelected( ) method.

Example    

checkbox.setSelected(true);  


JRadioButton

JRadioButton is the component to use where only one
choice is allowed from a list
of choices. ButtonGroup
is an invisible class that is used to group radio buttons
and
provide the mutually exclusive behavior they display.
( In AWT the class was called
Checkbox group.)

By default nothing is preset. The setSelected( ) method
may be used to preset one of the selections.

// a main method has been added to the following
// in case the is not working where you are

JRadioButton Example

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

class RadioPanel extends JPanel {

    RadioPanel( ) {
    setLayout(new GridLayout(5, 1));
    // a label, three radio buttons and a regular button
    JLabel jl=new JLabel("Select the installation mode");
    add(jl);
    ButtonGroup bg=new ButtonGroup( );
   JRadioButton rb1 = new JRadioButton("Standard (Recommended)");
   JRadioButton rb2 = new JRadioButton("Custom");
   JRadioButton rb3 = new JRadioButton("Expert");
   // by default nothing is preset
   rb1.setSelected(true);
   
  // trying to set two to true causes the second setting to be ignored
   add(rb1);
   add(rb2);
   add(rb3);
 
// if you cancel addding to a button group, mutually exclusive behavior is eliminated
 
   bg.add(rb1);
   bg.add(rb2);
   bg.add(rb3);

   // nesting a button in a panel allows retention of preferred size in a grid layout

   JPanel nestPanel=new JPanel();
   JButton next=new JButton("Next");
   nestPanel.add(next);
   add(nestPanel);
   }
  public static void main(String[] args){
      JFrame f=new JFrame();
      RadioPanel rp=new RadioPanel();
       f.add(rp);
       f.setSize(300,300);
       f.setVisible(true);
 }
}

Applet Version shows Exclusive Behaviour Provided
by Adding to a Button Group


 


Menu Components


Menus

Menus operate like buttons and create ActionEvents but
are unique in
that a place in JFrame is reserved especially
to locate the menus. The nesting of a
typical arrangement
involves putting JMenuItems into JMenus which are added
to
a JMenuBar. The JMenuBar is finally set to the JFrame.
New to Swing, a menu bar
can also be added to a JApplet.

Like other JComponents, icons can be added to the JMenu
class of objects.  A convenience method called addSeparator( )
can be used
to add separators to a JMenu.

// new to Swing, a JMenuBar can be added to an applet


Recipe for Menu Creation

1.  Create JMenuBar
2.  Create JMenu
3   Create JMenuItems
4   Add JMenuItems to JMenu
5   Add JMenu to JMenuBar
6   Set the JMenuBar to Frame using setJMenuBar( ) method


Review: Using the Container Class to Listen for Events

Reviewing events, in the following example the class itself
is acting as the ActionListener. This is achieved by adding
'implements ActionListener' after the name of the class.
Once this is done the compiler will expect to find an
implementation of the single method defined in the 
ActionListener interface, actionPerformed( ).

If you look at the end of the following example you will
see an implementation of this method is provided. The
other requirement is to register the listener, in this case,
'this', to containing class. This is done using the
addActionListener( ) method.

 

Example

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

public class MenuFrame implements ActionListener {
       public MenuFrame( ) {
             JFrame frame=new JFrame( );
             JMenuBar bar = new JMenuBar( );

             JMenu file = new JMenu("File");
              // new
             JMenuItem noo = new JMenuItem("New");
              noo.addActionListener(this);
              file.add(noo); // can't use the keyword 'new'
             JMenuItem open = new JMenuItem("Open Page");
             open.addActionListener(this);
             file.add(open);
             file.addSeparator( );
             // save
             JMenuItem save = new JMenuItem("Save");
             save.addActionListener (this);
             file.add(save);
              // exit
            JMenuItem exit = new JMenuItem("Exit");
             exit.addActionListener(this);
             file.add(exit);
             bar.add(file);
             // edit
            JMenu edit = new JMenu("Edit");

            JMenuItem cut = new JMenuItem("Cut");
            cut.addActionListener(this);
            edit.add(cut);
            // copy
           JMenuItem copy = new JMenuItem("Copy");
           copy.addActionListener(this);
           edit.add(copy);
            // paste
          JMenuItem paste = new JMenuItem("Paste");
           paste.addActionListener(this);
           edit.add(paste);
          bar.add(edit);
           // set bar
          frame.setJMenuBar(bar);
          frame.setSize(300,100);
          frame.setVisible(true);
          }
  public static void main( String [] args){
               new MenuFrame( );
              }
 public void actionPerformed(ActionEvent e) {
       System.out.println
       ("The source reference is: " +  e.getActionCommand( ) +"\n");
       }
 }


JPopupMenu & JComboBox


JPopupMenu

JPopupMenu is a context-sensitive menu object that
pops up to show a number of choices. It is invoked in
association with a particular component in a GUI. The
steps that must be taken to add a JPopupMenu are as
follows. First a popup menu needs to be created.

Mouse show( ) Behaviour Trumps Using setInvoker( )

There  is a setInvoker( ) method that may be used to set
the component that the PopUp is associated with. It also
has a matching getInvoker( ) method.

Example  

void setInvoker(Component invoker)


If you are using mouse listeners to process your pop-up
methods this method is overidden in it's effect. This is
because in the mouse action methods, the popup menus
show( ) method is called which takes the invoker as it's
first argument. If this is obtained using MouseEvent's
getComponent( ) method, whatever the mouse was
over becomes the invoker.

Coordinates are returned from the mouse event object
to locate the popup menu. Following is the show( ) method
signature showing it takes as arguments the invoking
component and x, y coordinates which will locate the pop-up
menu relative to the space of the invoking component.

Example   

void show(Component invoker, int x, int y)

// the show( ) method

The following code shows how these elements function
together. This code also shows the form refered to as the
'anonymous inner class'  being used to add an 'inlined' 
mouse listener, here utilizing the MouseAdapter class.

Example

// Assume each label represents a house, the first three of which
// are sold.
The popup menu is associated with the last, House 4.

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

class PopUps{
    JLabel j1, j2, j3, j4;
    JLabel[] labels={j1,j2,j3,j4};
     PopMenu p;
        PopUps( ){
    JFrame frame=new JFrame("Click on House 4" );
    p=new PopMenu( );
    frame.getContentPane( ).setLayout(new GridLayout(2,2));
    for(int i=0;i<4;i++){
    labels[i]=new JLabel("House " + ( i +1), SwingConstants.CENTER );
    labels[i].setOpaque(true);
    labels[i].setBackground(new Color(i*33,i*44,i*55));
    labels[i].setForeground(new Color(225,210,195));
    frame.getContentPane( ).add(labels[i]);
    }

 //  setInvoker can be commented out as it's effects are
//   overidden by the show method in the action methods. 

//     p.setInvoker(labels[3]); 

// a listener being added 'inline' in the form of an anonymous
// inner class

     labels[3].addMouseListener(new MouseAdapter( ){
                     public void mousePressed (MouseEvent me){
                        if(me.isPopupTrigger( )){
                          // tests if default selector for platform's popup
                        p.show(me.getComponent( ),
                        me.getX( ), me.getY( ));
                        }
                    }
                   public void mouseReleased (MouseEvent me){
                      if(me.isPopupTrigger( )){
                        p.show (me.getComponent(),
                        me.getX(), me.getY());
                       }
                  }
             });
    frame.setSize(400,300);
    frame.setVisible(true);
    }

public static void main(String [] args){
   new PopUps( );
   }
}

class PopMenu extends JPopupMenu{
        PopMenu(){
            super();
           JMenuItem info=new JMenuItem("Description");
           add (info);
           addSeparator( );
           JMenuItem lastPrice=new JMenuItem("Last Selling Price");
           add (lastPrice);
           addSeparator( );
           JMenuItem bid=new JMenuItem("Make A Bid");
           add (bid);
           } // end of constructor
       } // end of class

Applet Version of PopUps Code
// Uses BorderLayout North instead of JFrame( String ) constructor



Separate PopUps for Separate Invokers

What if you want to invoke a different pop-up for different
components. One might subclass the pop-up component
and supply it with different behaviours based on some
argument passed to it, perhaps a class that carries different
sets of data.

In the following scenario, the getComponent( ) method of
the MouseEvent class is used to capture the event source
and compare it to different components. Each component
is then associated with it's own pop-up menu. The following
code shows this.

This example when compared to the one above shows the
usefulness of using the Adapter classes. In the following
example, because we are implementing MouseListener, we
need to provide stub methods for interface methods, even
when we are not interested in using them.

 

Different PopUps for different Labels

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

class PopsUp2 implements MouseListener {
   PopMenu1 p1;
   PopMenu2 p2;
   JLabel label1,label2;
   JFrame frame;

PopsUp2( ) {
    frame=new JFrame("Click on House 4" );
     p1=new PopMenu1( );
     p2=new PopMenu2( );

    frame.getContentPane( ).setLayout(new GridLayout(3,1));

    label1=new JLabel("Label 1" );
    label2=new JLabel("Label 2" );

    label1.addMouseListener(this);
    label2.addMouseListener(this);

    frame.getContentPane( ).add(label1);
    frame.getContentPane( ).add(label2);

    frame.setSize(400,900);
    frame.setVisible(true);
    }

public static void main(String [] args){
   new PopsUp2( );
   }
public void mousePressed (MouseEvent me){
         if( me.getComponent( ).equals(label1) && me.isPopupTrigger( )){
              p1.show(me.getComponent( ) ,
              me.getX( ), me.getY( ));
              }
        else if (me.getComponent( ).equals(label2) && me.isPopupTrigger( )){
             p2.show(me.getComponent( ),
             me.getX( ), me.getY( ));
             }
         }

public void mouseReleased(MouseEvent me){
          if(me.getComponent( ).equals(label1) && me.isPopupTrigger( )){
                 p1.show(me.getComponent( ),
                 me.getX( ), me.getY( ));
          }
         else if (me.getComponent( ).equals(label2) && me.isPopupTrigger( )){
                p2.show(me.getComponent( ),
                 me.getX( ), me.getY( ));
                }
      }

// stubbed out mouse listener methods

public void mouseEntered(MouseEvent me){  }
public void mouseClicked(MouseEvent me){  }
public void mouseExited(MouseEvent me){  }

 

}

class PopMenu1 extends JPopupMenu{
        PopMenu1( ){
            super();
           JMenuItem info=new JMenuItem("Mortage Information");
           add (info);
           addSeparator( );
           JMenuItem lastPrice=new JMenuItem("Yearly Taxes");
           add (lastPrice);
           addSeparator( );
           JMenuItem bid=new JMenuItem("Amenities");
           add (bid);
           } // end of constructor
       } // end of class

class PopMenu2 extends JPopupMenu{
        PopMenu2( ){
            super();
           JMenuItem info=new JMenuItem("Description");
           add (info);
           addSeparator( );
           JMenuItem lastPrice=new JMenuItem("Last Selling Price");
           add (lastPrice);
           addSeparator( );
           JMenuItem bid=new JMenuItem("Make A Bid");
           add (bid);

           } // end of constructor
       } // end of class


JComboBox 

JComboBox is a variation of a List that is designed to
supply a user with a list of choices. It mixes features
from a number of
components including menus which
leads to the name it was given. JComboBox
behaves
like a pull-down menu, a list and choice component all
in one. Entries are
highlighted by the inner class,
KeySelectionManager which can be used to provide

custom highlighting behavior.

// looks like a button component but really is a complex component
// acting like a pull-down menu, a list and a choice component

The component has four constructors, a no-args constructor,
one that takes a vector,
one an array and one that takes
a ComboBoxModel. ComboBoxModel is an interface
that
extends ListModel. Essentially it is a list model with the
added feature that an
element can be selected.

As you might expect, there is a DefaultComboBoxModel
class
that is an extension of AbstractListModel as well as
an implementation of the
ComboBoxModel interface. The
DefaultComboBoxModel has three constructors
itself, a
no-arg constructor, one that takes a vector and one taking
an Object array.


ComboBox Model Interface and Class Hierarchy // for reference


Classes         Interfaces

AbstractListModel  implements   ListModel
| |
| ComboBoxModel
| |
DefaultComboBoxModel MutableComboBoxModel


In the next example three arrays serve as arguments to
create three instances of DefaultComboBoxModel. Then
three JComboBox instances are created using these
default models as arguments to their constructors.  

 

Example  // Convenient to run as it includes a main( ) method

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

class CarCombo extends JPanel {
          CarCombo( ) {
                   setBackground(Color.darkGray);

                   String makeArray[] = {"MAKE","Chevrolet", "Ford", "Chrylser","Toyota",
                                            "Honda", "Mazda", "Saturn","Volkswagon", "BMW"};

                   String  typeArray[] = {"TYPE","compact", "sub-compact", "full-size","mini-van",
                                            "van", "pickup", "sports-utility", "sportscar"};

                   String yearArray[] = {"YEAR","1990","1991","1992","1993","1994","1995","1996",
                                            "1997","1998","1999","2000","2001","2002"};

                   ComboBoxModel makeMod=new DefaultComboBoxModel(makeArray);
                   ComboBoxModel typeMod=new DefaultComboBoxModel(typeArray);
                   ComboBoxModel yearMod=new DefaultComboBoxModel(yearArray);

                   JComboBox make = new JComboBox(makeMod);
                   JComboBox type = new JComboBox(typeMod);
                   JComboBox year = new JComboBox(yearMod);
                   
                    make.setEditable(true);

                    year.setEditable(true);
                   JPanel subpanel=new JPanel( );
                   subpanel.setLayout(new GridLayout(1,3));
                   subpanel.add(make);
                   subpanel. add(type);
                   subpanel.add(year);
              
                   add(subpanel);

                       }
                     }

class ComboTester extends JFrame{
public static void main(String [] args){
    ComboTester ct=new ComboTester( );
    ct.getContentPane( ).add(new CarCombo());
    JLabel label=new JLabel("New Car Search!",SwingConstants.CENTER);
    label.setOpaque(true);
    label.setBackground(new Color(50,70,90));
    label.setForeground(Color.white);
    label.setFont(new Font("Helivitica",Font.PLAIN,26));
    ct.getContentPane( ).add(label ,BorderLayout.NORTH);
    ct.setSize(500,400);
    ct.setVisible(true);
    }
}

We now leave the world of buttons to look at miscellaneous
component
types.


JProgressBar, JScrollBar & JSlider  
// more sliders & other unique components


JProgressBar

JProgressBar is used to monitor the progress of a process.
The Internet download supplies the classic example of where
the progress bar would be usefully applied. This time consuming
process would best be managed running in a separate thread,
using Java's Thread class. 


JProgressBar Methods

JProgressBar can generate Change events and has the
addChangeListener( ) method for registering ChangeListeners.
The component also has 'get' & 'set' methods for setting and
getting the minimum and maximum values of the progress bar. 

JProgressBar has a getModel( ) method for returning it's model
type, BoundedRangeModel. The percent completed can be
returned as a double from the getPercentComplete( ) method.

JProgressBar has a getValue( ) method that returns the current
value. Among other methods, there is a setOrientation( ) method
that is used to set the orientation of the component.

The following code is an intentional kept simple to
show essential aspects of the component in action.


Example

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

class ProgBar extends JFrame{

   ProgBar( ){
     JLabel label=new JLabel( );
     label.setText(" JProgressBar incremented by some time consuming process.");
     getContentPane( ).add(label, BorderLayout.CENTER);

     JProgressBar prog=new JProgressBar( );
     prog.setMinimum(0);
     prog.setMaximum(100);
     prog.setStringPainted(true);
     getContentPane( ).add(prog,BorderLayout.SOUTH);
     setSize(400,200);
     setVisible(true);

   for(int i=0;i<101;i++){
       try{
           Thread.sleep(200);
           prog.setValue(i);
           }
           catch(InterruptedException io){
           }
        }
       }
public static void main(String[]args){
  new ProgBar( );
  }
}
 

 
 Using Progress Bar with Another Thread's Runnable Object
 
reference: Fundamentals of JFC/Swing: Part I,             //  just for reference

 http://java.sun.com/developer/onlineTraining/GUI/Swing1/shortcourse.html#JFCProgress


  There are special methods found in the class, SwingUtilities, called
  invokeLater( ) and invokeAndWait( ) that take as argument a Runnable
  object. This Runnable object represents a new thread and is the correct
  place from which to update the progress bar in a multithreaded situation,
  that is from a 'long process' being executed in a separate thread. It is a
  topic that straddles Swing and Multithreadiing. The Swing Tutorial at the
  Sun Microsystem's site supplies examples of these methods in being
  used to control separate thread processes.
 
  The steps described in the Sun Tutorial summarize by stating that the
  JProgressBar needs to be created and initialized.

    Sun Example  

    JProgressBar progressBar = new JProgressBar();
    progressBar.setMinimum(0);
    progressBar.setMaximum(numberSubOperations);

    Create a loop that iterates the number of sub operations.

    Sun Example    
  
   progressBar.setValue(progressBar.getMinimum());
   for (int i = 0; i < numberSubOperations; i++) {
           // Perform sub-operation i
          // Update bar value in event thread
         // Where runner is created outside for loop
        SwingUtilities.invokeAndWait(runner);
         }

   Outside the loop, a Runnable Object is created that gets the last
   value of the progress bar and increments the value via a setValue( )
   method.

   Sun Example   
          
  
Runnable runner = new Runnable() {
       public void run() {
            int value = progressBar.getValue();
            progressBar.setValue(value+1);
            }
       };

    See the full example at the Sun site Tutorial supplied above as a reference.


\
The following was created based on the above snippets.


Example

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

class RunThread extends JFrame{
   JProgressBar progressBar;
   int numberSubOperations;
   Runnable runner;

   RunThread()
   {   
    numberSubOperations = 100;
    progressBar = new JProgressBar();
    progressBar.setMinimum(0);
    progressBar.setMaximum(numberSubOperations);
    progressBar.setValue(progressBar.getMinimum());
    getContentPane().add(new JLabel
    ("Progress Bar in a Thread"),BorderLayout.NORTH);
    getContentPane().add(progressBar);

    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setSize(750,150);
    setVisible(true);

    // bypassing referencing getContentPane()

    runner = new Runnable() {
       public void run() {
             // do a system intensive task here
            int value = progressBar.getValue();
            progressBar.setValue(value+1);
         try{
             Thread.sleep(250);
            }     
          catch(InterruptedException ie){
          System.out.println("Inside Runnable: " + ie);
           }     
         }
       };
 try{
 
  for (int i = 0; i < numberSubOperations; i++) {    
        SwingUtilities.invokeAndWait(runner);
         }
    }
 catch(InterruptedException ie){
    System.out.println("At invocation: " + ie);
    }
 catch(java.lang.reflect.InvocationTargetException ite){
    System.out.println(ite);
    }  
   }

public static void main(String[] args){
    new RunThread();
    }
}


JScrollBar 

JScrollBar is a lot like the older AWT scrollbar. Although
it is most convenient to add scrollbars by simply adding
a component to a JScrollPane, there may be some occasions
where a JScrollBar component may be used. The constructor
that gives you most control over the component is shown
below. While the Swing documentation is pretty scant, looking
at the documentation for AWT's ScrollBar component is quite
informative.

Constructor Example

JScrollBar(int orientation, int value, int extent, int min, int max)

The first parameter can be specified with constants found in
the 'Adjustable' interface, HORIZONTAL and VERTICAL. The
second value describes the starting point of the slider. The third
value describes what the viewable range is. The size of the
slider controller is proportional to the viewable range. The final
two values represent the starting and finishing values of the
complete range of the slider.


Example
 

JScrollBar bar=
new JScrollBar(Scrollbar.HORIZONTAL, 0, 20, 0, 100 );

1. orientation
2. start of range
3. size of slider proportional to % of range

4. start value
5. finish value

Notice in the example below that the values of the range
has been extended to accomodate the value that the
slider button size takes. The upper range is set to 110 to
accomodate a slider control size of 10, leaving an effective
range of 100. The range might have been set to 105 if the
slider size had been set to 5.  This code also shows an
AdjustmentListerer being used.

The return value of the Y-axis, vertical slider has been
'fudged' (subtracted from 100) to appear to rise as the
slider ascends in the vertical range.


Example

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

class Scroll extends JFrame implements AdjustmentListener{
        JTextArea Xarea,Yarea;
        JScrollBar XBar,YBar;
      Scroll( ){
         JLabel label=new JLabel("Scroll");
        getContentPane().add(label, BorderLayout.NORTH);
        JPanel pane=new JPanel();
        pane.setLayout(new GridLayout(1,2));
        Xarea=new JTextArea("\n\n   X");
        Xarea.setFont(new Font("Monospaced",Font.PLAIN,40));
        pane.add(Xarea);
        Yarea=new JTextArea("\n\n   X" );
        Yarea.setFont(new Font("Monospaced",Font.PLAIN,40));
        pane.add(Yarea);

        XBar=new JScrollBar
        (JScrollBar.HORIZONTAL,0,10, 0,110);
        XBar.addAdjustmentListener(this);
        getContentPane().add(XBar, BorderLayout.SOUTH);
        YBar=new JScrollBar
        (JScrollBar.VERTICAL,0,10,0,110);
        YBar.addAdjustmentListener(this);

        // without a setting as follows the value starts
        //
at minimum which is at top of the slider
        YBar.setValue(110);

        getContentPane().add(YBar, BorderLayout.WEST);
        getContentPane( ).add(pane,BorderLayout.CENTER);
        setSize(400,400);
        setVisible(true);
        }
        public static void main(String[]args){
        new Scroll( );
        }
public void adjustmentValueChanged(AdjustmentEvent ae){
        if(ae.getSource().equals(XBar)){
        Xarea.setText("\n\n   "+ ae.getValue());
        }
    // value returned fudged to appear to increase with vertical ascent  
        if(ae.getSource().equals(YBar)){
        Yarea.setText("\n\n   "+ (100 - ae.getValue()) );
        }
      }
    }

 

JSlider

JSlider  adds marking to a JScrollBar in the form of major
and minor ticks. The ticks are added using a combination
of the methods, setPaintTicks( ), setMajorTickSpacing( )
and setMinorTickSpacing( ). The first method takes a
boolean value and determines if ticks are set. The second
method mentioned sets the major division points. The last
method dictates on which division the minor ticks will be
displayed.

Selected Key JSlider Methods


In the following example a major tick occurs every 5 units
of the scale and a minor tick occurs on every one of the
scale units. JSlider also allows the addition of labels to
markings on the slider. They are added first to a hash
table which then is added to the slider with a setLabelTable( );

Example

  JSlider slide =
        new JSlider (JSlider.HORIZONTAL, 0, 100, 50);
        slide.setPaintTicks(true);
        slide.setMajorTickSpacing(5);
        slide.setMinorTickSpacing(1);

An interesting feature of JSlider allows a 'label table' to
be created and associated with the component. The table
is contained in a hash table, that stores a wrapped integer
value along with an associated label.  One needs to import
the java.util package to use the hash table.

 

Example

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

class Sliders{

   Sliders( ){
    JFrame frame=new JFrame
    ("     HISTORICAL TIME FRAME" );
    SliderPanel2 s=new SliderPanel2();
    frame.getContentPane( ).add(s);
    frame.setSize(700,400);
    frame.setVisible(true);

    }

public static void main(String [] args){
   new Sliders( );
   }
}

 class SliderPanel2 extends JPanel {
       public SliderPanel2() {
          setLayout(new BorderLayout());
          JSlider era, year;
         era = new JSlider(JSlider.VERTICAL,0,10,3);
          Hashtable hash = new Hashtable( );

          hash.put (new Integer (1), new JLabel("Mesopotamia"));
          hash.put (new Integer (2), new JLabel("Greek"));
          hash.put (new Integer (3), new JLabel("Roman"));
          hash.put (new Integer (4), new JLabel("Holy Roman"));
          hash.put (new Integer (5), new JLabel("Dark Ages"));
          hash.put (new Integer (6), new JLabel("Renaissance"));
          hash.put (new Integer (7), new JLabel("Reformation"));
          hash.put (new Integer (8), new JLabel("Industrial Revolution"));
          hash.put (new Integer (9), new JLabel("ModernAge"));

          era.setLabelTable (hash);
          era.setPaintLabels (true);

          year= new JSlider(JSlider.HORIZONTAL, -4000,2000, 0);
          year.setPaintTicks(true);
          year.setMajorTickSpacing (1000);
          year.setMinorTickSpacing(100);
          year.setPaintLabels (true);

          add(era, BorderLayout.WEST);
          add(year, BorderLayout.SOUTH);
          }
    }



Self Test                                       Self Test With Answers

1) Which of the following is the parent to the others

a) JCheckbox
b JToggleButton
c) JRadioButton

2) The AbstractButton class does not incorporate the
     ability to process which
of the following event types?

a) Item
b) Action
c) Component
d) Change

3)
a) True or False.  JToggleButton looks like a regular JButton but has
    the selected behavior of JRadioButton.
b) True or False.  JToggleButton when activated it remains depressed.
 

4) Which of the following is not correct?

a) Separators can be added using the  addSeparator( ) method.
b) JMenuItems are added to JMenus using add( ) methods
c) JMenus are added to JMenuBars using add( ) methods
d) JMenuBars are added to JFrames using an addMenuBar( ) method
 

5) When a JPopupMenu is invoked using MouseEvent processing
which of the following methods is called on the popup menu object?

a) getComponent( )
b) addMouseListener( )
c)  getY( )
d) show( )
 

6 ) JProgressBar doesn't use which of the following methods.
a) setMaximum( )
b) getValue( )
c) addItemListener( )
d) getModel( )
 


Exercise

1) Look at two or three generic applications and determine a set of
menus and menuitems that are very common. Create a JFrame with
a menu bar set with these common entries. In the future, this class
can serve as a template for any GUI you create that might need these
functions.

2) Using the PopUp code example find 4 images that can be placed
in the code. Adapt the code so a popup menu comes up for each
image and has information that is specific for the house. For
expedience use the text on the popup menu's to show some minimal
information about that items that are pictured in the images.