Concurrent Programming with Java
Lab Manual, Version 1.0, F. Astha Ekadiyanto,
2002.
The Control Panel Class is responsible for all the user interfaces and regulate how users can control the Applet. Of course this means that the User Interface must adapt with the states of the Threads.

Create the ControlPanel Class and replace it with the code below:
import java.awt.*; import java.awt.event.*; /** * The class ControlPanel controls the threads in the monitor demonstration. * @author Stephan Fischli * @version 1.0 */ public class ControlPanel extends Panel implements ActionListener { /** * The threads to control. */ private DemoThread[] threads; /**
* The thread choice.
*/
private Choice threadChoice;
/**
* The state field.
*/
private TextField stateField;
/**
* The start button.
*/
private Button startButton;
/**
* The stop button.
*/
private Button stopButton;
/**
* The enter monitor button.
*/
private Button enterButton;
/**
* The leave monitor button.
*/
private Button leaveButton;
/**
* The wait condition button.
*/
private Button waitButton;
/**
* The signal condition button.
*/
private Button signalButton;
/**
* Creates a ControlPanel object.
* @param threads the threads to control
*/
public ControlPanel( DemoThread[] threads )
{
this.threads = threads;
GridBagLayout layout = new GridBagLayout();
setLayout( layout );
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.WEST;
gbc.fill = GridBagConstraints.HORIZONTAL;
// add thread label
Label threadLabel = new Label( "Thread:" );
gbc.gridx = 0; gbc.gridy = 0;
gbc.insets = new Insets( 10, 20, 0, 0 );
layout.setConstraints( threadLabel, gbc );
add( threadLabel );
// add thread choice
threadChoice = new Choice();
for ( int i = 0; i < threads.length; i++ )
threadChoice.add( i + "" );
gbc.gridx = 1; gbc.gridy = 0;
gbc.insets = new Insets( 10, 0, 0, 10 );
layout.setConstraints( threadChoice, gbc );
add( threadChoice );
// add state label
Label stateLabel = new Label( "State:" );
gbc.gridx = 0; gbc.gridy = 1;
gbc.insets = new Insets( 5, 20, 20, 0 );
layout.setConstraints( stateLabel, gbc );
add( stateLabel );
// add state text
stateField = new TextField( 5 );
stateField.setEditable( false );
gbc.gridx = 1; gbc.gridy = 1;
gbc.insets = new Insets( 5, 0, 20, 10 );
layout.setConstraints( stateField, gbc );
add( stateField );
// add start button
startButton = new Button( "Start Thread" );
gbc.gridx = 2; gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.insets = new Insets( 10, 10, 0, 10 );
layout.setConstraints( startButton, gbc );
add( startButton );
startButton.addActionListener( this );
// add stop button
stopButton = new Button( "Stop Thread" );
gbc.gridx = 2; gbc.gridy = 1;
gbc.insets = new Insets( 5, 10, 20, 10 );
layout.setConstraints( stopButton, gbc );
add( stopButton );
stopButton.addActionListener( this );
// add enter monitor button
enterButton = new Button( "Enter Monitor" );
gbc.gridx = 3; gbc.gridy = 0;
gbc.insets = new Insets( 10, 10, 0, 10 );
layout.setConstraints( enterButton, gbc );
add( enterButton );
enterButton.addActionListener( this );
// add leave monitor button
leaveButton = new Button( "Leave Monitor" );
gbc.gridx = 3; gbc.gridy = 1;
gbc.insets = new Insets( 5, 10, 20, 10 );
layout.setConstraints( leaveButton, gbc );
add( leaveButton );
leaveButton.addActionListener( this );
// add wait condition button
waitButton = new Button( "Wait Condition" );
gbc.gridx = 4; gbc.gridy = 0;
gbc.insets = new Insets( 10, 10, 0, 20 );
layout.setConstraints( waitButton, gbc );
add( waitButton );
waitButton.addActionListener( this );
// add signal condition button
signalButton = new Button( "Notify Condition" );
gbc.gridx = 4; gbc.gridy = 1;
gbc.insets = new Insets( 5, 10, 20, 20 );
layout.setConstraints( signalButton, gbc );
add( signalButton );
signalButton.addActionListener( this );
}
/**
* Paints the panel.
* @param g the graphics context to use
*/
public void paint( Graphics g )
{
// disable buttons
Component[] comp = getComponents();
for ( int i = 0; i < comp.length; i++ )
if ( comp[i] instanceof Button )
comp[i].setEnabled( false );
// update state field and enable buttons
int i = threadChoice.getSelectedIndex();
switch ( threads[i].getState() ) {
case DemoThread.CREATED:
stateField.setText( "Created" );
startButton.setEnabled( true );
break;
case DemoThread.RUNNING:
stateField.setText( "Running" );
stopButton.setEnabled( true );
enterButton.setEnabled( true );
break;
case DemoThread.ENTERING_MONITOR:
stateField.setText( "Entering" );
break;
case DemoThread.RUNNING_MONITOR:
stateField.setText( "Running" );
leaveButton.setEnabled( true );
waitButton.setEnabled( true );
signalButton.setEnabled( true );
break;
case DemoThread.WAITING_CONDITION:
stateField.setText( "Waiting" );
break;
case DemoThread.DEAD:
stateField.setText( "Dead" );
break;
}
}
/**
* Handles an action event.
* @param event the action event
*/
public void actionPerformed( ActionEvent event )
{
Button button = (Button)event.getSource();
int i = threadChoice.getSelectedIndex();
if ( button.equals( startButton ) )
try { threads[i].start(); }
catch ( IllegalThreadStateException e ) {}
else if ( button.equals( stopButton ) )
threads[i].terminate();
else if ( button.equals( enterButton ) )
threads[i].enterMonitor();
else if ( button.equals( leaveButton ) )
threads[i].leaveMonitor();
else if ( button.equals( waitButton ) )
threads[i].waitCondition();
else if ( button.equals( signalButton ) )
threads[i].signalCondition();
}
}
|