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(); } } |