Implementing multiplexing components

In order to be used in a Multiplexer, site interfaces need to register an alternative default implementation with the org.eclipse.ui.part.SiteMultiplexerInitializer scope. Since this extends the site scope, the more specific multiplexer version will take priority over the default version when used in a Multiplexer.

A multiplexed component will almost always use the following pattern:
  1. Implement the INestedComponent lifecycle interface;
  2. Take an IMultiplexer in their constructor and use it to access the shared version of their interface;
  3. Store the part's state;
  4. Listen to state changes in the child and update the stored state appropriately;
  5. Each time the component is activated, it should forward the stored state to the shared interface in the multiplexer;
  6. While the component is active, it should forward state changes directly to the shared interface.
The following example demonstrates the code used by the workbench to multiplex the ISelectionHandler interface with ChildSelectionHandler.
/**
 * Multiplexed version of the ISelectionHandler interface
 *
 * @since 3.1
 */
public class ChildSelectionHandler implements ISelectionHandler, INestedComponent {

    private ISelectionHandler parent;
    private ISelection selection;
    private boolean isActive = false;
    private IMultiplexer multiplexer;

    public ChildSelectionHandler(IMultiplexer mplex) throws DependencyException {
        this.multiplexer = mplex;        
        // Get access to the shared ISelectionHandler being multiplexed (we should        
        // only modify it when we're the active child)        
        this.parent = (ISelectionHandler)
            mplex.getSharedComponents().getComponent(ISelectionHandler.class);        
                
        // Set the initial state (the part's initial selection will be null        
        // until it explicitly sets it).        
    }        

    public IMultiplexer getMultiplexer() {        
        // Return the multiplexer we were created with        
        return multiplexer;        
    }

    public void activate() {        
        // Forward our stored selection to the shared interface        
        parent.setSelection(selection);        
        isActive = true;        
    }        
            
    public void deactivate() {        
        isActive = false;        
    }        

    public void setSelection(ISelection newSelection) {        
        // Remember the child's new selection        
        selection = newSelection;        
        if (isActive) {        
             // If we're active, forward the selection directly to the
             // shared interface        
             parent.setSelection(newSelection);        
        }        
    }        
}        
Here is the associated extension point markup for ChildSelectionHandler.
<extension point="org.eclipse.core.component.types">        
    <component        
            implementation="org.eclipse.ui.internal.part.services.ChildSelectionHandler"        
            interface="org.eclipse.ui.part.services.ISelectionHandler"        
            singleton="false"        
            initializer="org.eclipse.ui.part.SiteMultiplexerInitializer"/>        
 </extension>        
Screenshot of TestCompositeView