Package org.jcsp.awt

# Class ActiveMenu

java.lang.Object
java.awt.MenuComponent
java.awt.MenuItem
java.awt.Menu
org.jcsp.awt.ActiveMenu

All Implemented Interfaces:
  `MenuContainer`, `Serializable`, `Accessible`, `CSProcess`

public class ActiveMenu extends Menu implements CSProcess
``java.awt.Menu`` with a channel interface.

## Process Diagram

## Description

`ActiveMenu` is a process extension of `java.awt.Menu` with channels for run-time configuration and event notification. The event channel should be connected to an application-specific server process (instead of registering a passive object as a Listener to this component).

The `configure` and `event` channels are settable from a constructor. The `event` channel delivers the command string associated with this `ActiveMenu` whenever it is selected. Messages can be sent down the `configure` channel at any time to configure the component. See the table below for details.

All channels are managed by independent internal handler processes. It is, therefore, safe for a serial application process both to service the event channel and configure the component -- no deadlock can occur.

IMPORTANT: it is essential that a (non-null) event channel from this process is always serviced -- otherwise the Java Event Thread will be blocked and the GUI will stop responding. A simple way to guarantee this is to use channels configured with overwriting buffers. For example:

       final One2OneChannel myMenuEvent = Channel.one2one (new OverWriteOldestBuffer (n));

       final ActiveMenu myMenu =
         new ActiveMenu (null, myMenuEvent.out (), "Look at this");

This will ensure that the Java Event Thread will never be blocked. Slow or inattentive readers may miss rapidly generated events, but the `n` most recent events will always be available.

## Channel Protocols

Input Channels
configure | String | Change the label on the `ActiveMenu` to the value of the `String`
java.awt.MenuShortcut | Sets the `MenuShortcut` for the `ActiveMenu`
Integer | Inserts a separator at the specified position.

Boolean

1. If this is the `Boolean.TRUE` object, the menu is made active
2. If this is the `Boolean.FALSE` object, the menu is made inactive
3. Other `Boolean` objects are ignored

ActiveMenu.Configure | Invoke the user-defined `Configure.configure` method on the activeMenu.
Output Channels
event | String | The command for the `ActiveMenu` (when the menu is selected)

## Example

     import java.awt.*;
     import java.awt.event.*;
     import org.jcsp.lang.*;
     import org.jcsp.util.*;
     import org.jcsp.awt.*;

     public class ActiveMenuExample {

       public static void main (String argv[]) {

         final ActiveClosingFrame activeClosingFrame =
           new ActiveClosingFrame ("ActiveCheckboxMenuItem Example");

         final ActiveFrame frame = activeClosingFrame.getActiveFrame ();

         final MenuBar menuBar = new MenuBar ();
         frame.setMenuBar (menuBar);

         final Menu fileMenu = new Menu ("File");
         menuBar.add (fileMenu);

         final String[] fileOptions = {"Hello World", "Rocket Science", "CSP",
                                       "Monitors", "Ignore Me", "Goodbye World"};

         final Any2OneChannel event[] = Channel.any2oneArray (2, new OverWriteOldestBuffer (10));

         final ActiveMenuItem[] fileMenuItem =
           new ActiveMenuItem[fileOptions.length];
         for (int i = 0; i invalid input: '<' fileOptions.length; i++) {
           fileMenuItem[i] = new ActiveMenuItem (null, event[0].out (), fileOptions[i]);
           fileMenu.add (fileMenuItem[i]);
         }

         fileMenu.addSeparator ();

         final Any2OneChannel langConfigure = Channel.any2one ();
         final ActiveMenu langMenu = new ActiveMenu (langConfigure.in (), null, "Language");
         fileMenu.add (langMenu);  // set up the active langMenu as a sub-menu

         final String[] langOptions = {"occam-pi", "Java", "Smalltalk", "Algol-60",
                                       "Pascal", "Haskell", "SML", "Lisp"};

         final ActiveCheckboxMenuItem[] langCheckboxMenuItem =
           new ActiveCheckboxMenuItem[langOptions.length];
         for (int i = 0; i invalid input: '<' langOptions.length; i++) {
           langCheckboxMenuItem[i] =
             new ActiveCheckboxMenuItem (null, event[1].out (), langOptions[i]);
           langMenu.add (langCheckboxMenuItem[i]);
         }

         frame.setSize (700, 350);
         frame.setBackground (Color.green);
         frame.setVisible (true);

         new Parallel (
           new CSProcess[] {     // don't forget to include all active processes
             langMenu,
             activeClosingFrame,
             new Parallel (fileMenuItem),
             new Parallel (langCheckboxMenuItem),
             new CSProcess () {
               public void run () {
                 boolean running = true;
                 while (running) {
                   final String s = (String) event[0].in ().read ();
                   System.out.println ("File ==> `" + s + "' selected ...");
                   if (s == fileOptions[0]) {
                     langConfigure.out ().write (Boolean.TRUE);
                     System.out.println ("`Language' enabled ...");
                   }
                   running = (s != fileOptions[fileOptions.length - 1]);
                 }
                 frame.setVisible (false);
                 System.exit (0);
               }
             },
             new CSProcess () {
               public void run () {
                 while (true) {
                   final ItemEvent e = (ItemEvent) event[1].in ().read ();
                   final String item = (String) e.getItem ();
                   System.out.print ("Language ==> `" + item);
                   if (e.getStateChange () == ItemEvent.SELECTED) {
                     System.out.println ("' selected ...");
                     if (item == langOptions[0]) {
                       langConfigure.out ().write (Boolean.FALSE);
                       System.out.println ("`Language' disabled ...");
                     }
                   } else {
                     System.out.println ("' deselected ...");
                   }
                 }
               }
             }
           }
         ).run ();

       }

     }

Author:
  P.D. Austin and P.H. Welch
See Also:
  - `Menu`
  - `ItemEvent`
  - `ComponentEvent`
  - `FocusEvent`
  - `KeyEvent`
  - `MouseEvent`
  - `OverWriteOldestBuffer`
  - Serialized Form

## Nested Class Summary

Nested Classes
Modifier and Type
Class
Description
`static interface`
`ActiveMenu.Configure`
This enables general configuration of this component.

## Nested classes/interfaces inherited from class java.awt.Menu

`Menu.AccessibleAWTMenu`

## Nested classes/interfaces inherited from class java.awt.MenuItem

`MenuItem.AccessibleAWTMenuItem`

## Nested classes/interfaces inherited from class java.awt.MenuComponent

`MenuComponent.AccessibleAWTMenuComponent`

## Constructor Summary

Constructors
Constructor
Description
`ActiveMenu()`
Constructs an `ActiveMenu` with no initial label and no configuration or event channels.
`ActiveMenu(String label)`
Constructs an `ActiveMenu` with an initial label, but with no configuration or event channels.
`ActiveMenu(String label, boolean tearOff)`
Constructs an `ActiveMenu` with an initial label and a tear-off option, but with no configuration or event channels.
`ActiveMenu(ChannelInput configure, ChannelOutput event)`
Constructs an `ActiveMenu` with configuration and event channels, but with no initial label.
`ActiveMenu(ChannelInput configure, ChannelOutput event, String label)`
Constructs an `ActiveMenu` with configuration and event channels and an initial label.
`ActiveMenu(ChannelInput configure, ChannelOutput event, String label, boolean tearOff)`
Constructs an `ActiveMenu` with configuration and event channels, an initial label and a tear-off option.

## Method Summary

Modifier and Type
Method
Description
`void`
`run()`
The main body of this process.
`void`
`setConfigureChannel(ChannelInput configure)`
Sets the configuration channel for this `ActiveMenu`.

### Methods inherited from class java.awt.Menu

`add, add, addNotify, addSeparator, countItems, getAccessibleContext, getItem, getItemCount, insert, insert, insertSeparator, isTearOff, paramString, remove, remove, removeAll, removeNotify`

### Methods inherited from class java.awt.MenuItem

`addActionListener, deleteShortcut, disable, disableEvents, enable, enable, enableEvents, getActionCommand, getActionListeners, getLabel, getListeners, getShortcut, isEnabled, processActionEvent, processEvent, removeActionListener, setActionCommand, setEnabled, setLabel, setShortcut`

### Methods inherited from class java.awt.MenuComponent

`dispatchEvent, getFont, getName, getParent, getTreeLock, postEvent, setFont, setName, toString`

### Methods inherited from class java.lang.Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

### Methods inherited from interface java.awt.MenuContainer

`getFont, postEvent`

## Constructor Details

### ActiveMenu

public ActiveMenu()
Constructs an `ActiveMenu` with no initial label and no configuration or event channels.

### ActiveMenu

public ActiveMenu(String label)
Constructs an `ActiveMenu` with an initial label, but with no configuration or event channels.

Parameters:
  `label` - the label on the menu.

### ActiveMenu

public ActiveMenu(String label, boolean tearOff)
Constructs an `ActiveMenu` with an initial label and a tear-off option, but with no configuration or event channels.

Parameters:
  `label` - the label on the menu.
  `tearOff` - if true, this is a tear-off menu.

### ActiveMenu

public ActiveMenu(ChannelInput configure, ChannelOutput event)
Constructs an `ActiveMenu` with configuration and event channels, but with no initial label.

Parameters:
  `configure` - the channel for configuration events -- can be null if no configuration is required.

### ActiveMenu

public ActiveMenu(ChannelInput configure, ChannelOutput event, String label)
Constructs an `ActiveMenu` with configuration and event channels and an initial label.

Parameters:
  `configure` - the channel for configuration events -- can be null if no configuration is required.
  `label` - the label on the menu.

### ActiveMenu

public ActiveMenu(ChannelInput configure, ChannelOutput event, String label, boolean tearOff)
Constructs an `ActiveMenu` with configuration and event channels, an initial label and a tear-off option.

Parameters:
  `configure` - the channel for configuration events -- can be null if no configuration is required.
  `label` - the label on the menu.
  `tearOff` - if true, this is a tear-off menu.

## Method Details

### setConfigureChannel

public void setConfigureChannel(ChannelInput configure)
Sets the configuration channel for this `ActiveMenu`. This method overwrites any configuration channel set in the constructor.

Parameters:
  `configure` - the channel for configuration events -- can be null if no configuration is required.

### run

public void run()
The main body of this process.

Specified by:
  `run` in interface `CSProcess`