DesktopModePlugin.java :  » Scripting » oscript-2.10.4 » ti » chimera » plugin » Java Open Source

Java Open Source » Scripting » oscript 2.10.4 
oscript 2.10.4 » ti » chimera » plugin » DesktopModePlugin.java
/*=============================================================================
 *     Copyright Texas Instruments, Inc., 2002.  All Rights Reserved.
 * 
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 * 
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */


package ti.chimera.plugin;


import ti.exceptions.ProgrammingErrorException;
import ti.chimera.*;
import ti.chimera.pref.ChoiceNodeContract;
import ti.chimera.registry.*;
import ti.chimera.service.*;

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


/**
 * This plugin provides an implementation of the window manager mode.  It
 * provides an implementation of the {@link WindowMode} service for the
 * window manager to use to activate/deactivate this mode.  The rest of
 * this plugin realizes the implementation of displaying dialogs, tool-
 * bars, menubar entries, etc., on behalf of the window manager plugin.
 * <p>
 * This plugin is only half of the equasion as far as window management.  
 * The other half is the plugin that implements the "window manager" 
 * service, which is the "front end" that the rest of the system uses.
 * <center><img src="WindowManagerArchitecture.png"></center>
 * The devision is labor is that the this plugin responds to data written
 * into the registry.
 *  
 * @author Rob Clark
 * @version 0.1
 */
public class DesktopModePlugin
  extends AbstractModePlugin
{
  /**
   * The desktop containing all the dialogs
   */
  private JDesktopPane desktopPane;
  
  /**
   */
  private NodeSubscriber mainWindowBoundsSubscriber = new SwingNodeSubscriber( new NodeSubscriber() {
      
      public void publish( Node node, Object value )
      {
        Rectangle rv = (Rectangle)value;
        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
        Insets    i = getScreenInsets();
        
        if( rv.x < i.left )
          rv.x = i.left;
        
        if( rv.y < i.top )
          rv.y = i.top;
        
        if( (rv.width + rv.x) > (d.width - i.right) )
          rv.width = d.width - i.right - rv.x;
        
        if( (rv.height + rv.y) > (d.height - i.bottom) )
          rv.height = d.height - i.bottom - rv.y;
        
        getMain().debug( 1, getName() + ": mainWindow.setBounds( " + rv + " )" );
        mainWindow.setBounds(rv);
      }
      
    } );
  
  /**
   */
  private NodeSubscriber dragModeSubscriber = new SwingNodeSubscriber( new NodeSubscriber() {
      
      public void publish( Node node, Object value )
      {
        getMain().debug( 1, getName() + ": desktopPane.setDragMode( " + value + " )" );
        desktopPane.setDragMode( ((Integer)value).intValue() );
      }
      
    } );

  
  /*=======================================================================*/
  /**
   * Class Constructor.
   * 
   * @param main         the main application
   */
  public DesktopModePlugin( Main main )
  {
    super( main, "Desktop Mode" );
    
    try
    {
      registry.link( 
        new PersistentNode( getDefaultMainWindowBounds(), 
                            new TypeNodeContract( Rectangle.class ),
                            "the bounds of the main window" ),
        "/Window Manager/" + getName() + "/bounds" );
      registry.link( 
        new PersistentNode( new Integer( JDesktopPane.LIVE_DRAG_MODE ), 
                            new ChoiceNodeContract( new Object[] { new Integer( JDesktopPane.LIVE_DRAG_MODE ), new Integer( JDesktopPane.OUTLINE_DRAG_MODE )},
                                                    new Object[] { "opaque", "outline" } ),
                            "what drag mode to use?" ),
        "/Preferences/Window Manager/Desktop Mode/Drag Mode" );
    }
    catch(RegistryException e)
    {
      throw new ProgrammingErrorException(e);
    }
    
    main.atExit( new Runnable() {
        
        public void run()
        {
          if( mainWindow != null )
          {
            try
            {
              registry.resolve("/Window Manager/Desktop Mode/bounds").setValue( mainWindow.getBounds() );
            }
            catch(RegistryException e)
            {
              throw new ProgrammingErrorException(e);
            }
          }
        }
      } );
    
    registerServiceFactory( new ServiceFactory() {
        
        public Service createService()
        {
          return new AbstractWindowMode("desktop mode") {
              
              /**
               * Called after mainWindow is created, but before subscribes in start()
               */
              protected void startHook()
              {
                // build the desktop pane containing all the dialogs (JInternalFrames)
                desktopPane = new JDesktopPane();
                
                registry.subscribeToValue( 
                  "/Window Manager/Desktop Mode/bounds", 
                  null, 
                  mainWindowBoundsSubscriber
                );
                
                registry.subscribeToValue( 
                  "/Preferences/Window Manager/Desktop Mode/Drag Mode", 
                  null,
                  dragModeSubscriber
                );
                
                ((RootPaneContainer)mainWindow).getRootPane().getContentPane().add( desktopPane, ti.swing.DockLayout.CENTER );
              }
              
              /**
               * Called after unsubscribes in stop()
               */
              protected  void stopHook()
              {
                registry.unsubscribeFromValue(mainWindowBoundsSubscriber);
                registry.unsubscribeFromValue(dragModeSubscriber);
                desktopPane = null;
              }
              
              /**
               * Called to realize a dialog
               */
              protected void createDialog( String name )
              {
                desktopPane.add( new DesktopModeDialogImplementation(name) );
              }
              
            };
        }
        
      } );
 }
  
  /*=======================================================================*/
  /**
   * Get the appropriate default main-window size for this mode
   */
  protected Rectangle getDefaultMainWindowBounds()
  {
    Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
    Insets    i = getScreenInsets();
    Rectangle r = new Rectangle();
    
    r.x = i.left;
    r.y = i.top;
    r.width  = d.width - i.left - i.right;
    r.height = d.height - i.top - i.bottom;
    
    getMain().debug( 1, getName() + ": getDefaultMainWindowBounds() => " + r);
    
    return r;
  }
  
  /*=======================================================================*/
  /**
   * Create the main-window, in which the menubar, toolbar, etc. are
   * displayed.
   * 
   * @return the main-window
   * @see #diposeMainWindow
   */
  protected Component createMainWindow()
  {
    JFrame mainWindow = new JFrame( getAppName() ) {
        public void setBounds( int x, int y, int width, int height )
        {
          super.setBounds( x, y, width, height );
          try {
            fixBounds();
          } catch(NullPointerException e) {
            /* XXX ignore... ugly hack to work around details of how java
             * implements inner-classes... if we access dialogUtilityTable
             * prior to this constructor returning, then the access method
             * generated by the compiler will throw a NPE.
             */
          }
        }
      };
    
    mainWindow.setDefaultCloseOperation( JFrame.DO_NOTHING_ON_CLOSE );
    mainWindow.addWindowListener( new WindowAdapter() {
        public void windowClosing( WindowEvent evt ) { main.exit(0); }
      } );
    
    // build the menu-bar-item tree:
    mainWindow.setJMenuBar( new ti.chimera.MenuBar( getMain(), "/MenuBar" ) );
    
    return mainWindow;
  }
  
  protected void fixMainWindowBounds() {}
  
  /*=======================================================================*/
  /**
   * Dispose of the main-window created by {@link #createMainWindow}.
   * 
   * @param mainWindow   the main-window to dispose
   * @see #createMainWindow
   */
  protected void disposeMainWindow( Component mainWindow )
  {
    ((JFrame)mainWindow).dispose();
  }
  
  /*=======================================================================*/
  /**
   * The dialog implementation realizes the display of a dialog created
   * by the window manager.  It handles subscribing to the children of
   * <code>/Dialogs/&lt;TITLE&gt;</code> to receive state change notification
   * of the dialog it is realizing.  Also, it subscribes to the deletion
   * of <code>/Dialogs/&lt;TITLE&gt;</code> to detect that the dialog has 
   * been closed.
   */
  private class DesktopModeDialogImplementation
    extends JInternalFrameWrapper
    implements DialogImplementation
  {
    private DialogUtility util;
    private boolean windowVisible = false;
    
    /**
     * Class Constructor
     * 
     * @param title        the unique title of this dialog
     */
    DesktopModeDialogImplementation( String title )
    {
      super( title, true, true, true, true );
      
      util = new DialogUtility( this, title );
      
      setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
      addInternalFrameListener( new InternalFrameAdapter() {
          public void internalFrameClosing( InternalFrameEvent evt )
          {
            util.triggerDispose();
          }
        } );
    }
    
    public void setVisible( boolean b )
    {
      windowVisible = b;
      refreshVisibility();
    }
    
    public void refreshVisibility()
    {
      super.setVisible( windowVisible && userInterfaceVisible );
    }
    
    public void toFront()
    {
      try {
        setIcon(false);
      } catch(java.beans.PropertyVetoException e) {}
      super.toFront();
    }
    
    public void dispose()
    {
      try
      {
        util.dispose();
        super.dispose();
      }
      catch(WindowManager.DialogNotClosableException e)
      {
        // ignore
      }
    }
    
    public void center()
    {
      Rectangle mb = mainWindow.getBounds();
      Rectangle tb = getBounds();
      
      tb.x = (mb.width - tb.width) / 2;
      tb.y = (mb.height - tb.height) / 2;
      
      setBounds(tb);
    }
    
    public void setBounds( int x, int y, int width, int height )
    {
      // fix the bounds to not fall outside of desktop pane
      if( desktopPane.isVisible() && 
          (desktopPane.getWidth() > 0) &&
          (desktopPane.getHeight() > 0) )
      {
        if( x < 0 )
          x = 0;
        
        if( y < 0 )
          y = 0;
        
        if( (x + width) > desktopPane.getWidth() )
          width = desktopPane.getWidth() - x;
        
        if( (y + height) > desktopPane.getHeight() )
          height = desktopPane.getHeight() - y;
      }
      
      super.setBounds( x, y, width, height );
      util.boundsUpdated();
    }
    
    public void fixBounds() { /* XXX */ }
    
    public void addWindowListener( WindowListener l )
    {
      addInternalFrameListener( new WindowListenerWrapper(l) );
    }
    
    public void removeWindowListener( WindowListener l )
    {
      removeInternalFrameListener( new WindowListenerWrapper(l) );
    }
    
    private class WindowListenerWrapper
      implements InternalFrameListener
    {
      private WindowListener l;
      
      WindowListenerWrapper( WindowListener l )
      {
        this.l = l;
      }
      
      public void internalFrameOpened( InternalFrameEvent evt )
      {
        l.windowOpened( makeWindowEvent(evt) );
      }
      
      public void internalFrameClosing( InternalFrameEvent evt )
      {
        l.windowClosing( makeWindowEvent(evt) );
      }
      
      public void internalFrameClosed( InternalFrameEvent evt )
      {
        l.windowClosed( makeWindowEvent(evt) );
      }
      
      public void internalFrameIconified( InternalFrameEvent evt )
      {
        l.windowIconified( makeWindowEvent(evt) );
      }
      
      public void internalFrameDeiconified( InternalFrameEvent evt )
      {
        l.windowDeiconified( makeWindowEvent(evt) );
      }
      
      public void internalFrameActivated( InternalFrameEvent evt )
      {
        l.windowActivated( makeWindowEvent(evt) );
      }
      
      public void internalFrameDeactivated( InternalFrameEvent evt )
      {
        l.windowDeactivated( makeWindowEvent(evt) );
      }
      
      private WindowEvent makeWindowEvent( InternalFrameEvent evt )
      {
        return null; // XXX
      }
      
      public int hashCode()
      {
        return l.hashCode();
      }
      
      public boolean equals( Object obj )
      {
        return (obj instanceof WindowListenerWrapper) && ((WindowListenerWrapper)obj).l.equals(l);
      }
    }
  }
}



/*
 *   Local Variables:
 *   tab-width: 2
 *   indent-tabs-mode: nil
 *   mode: java
 *   c-indentation-style: java
 *   c-basic-offset: 2
 *   eval: (c-set-offset 'substatement-open '0)
 *   eval: (c-set-offset 'case-label '+)
 *   eval: (c-set-offset 'inclass '+)
 *   eval: (c-set-offset 'inline-open '0)
 *   End:
 */
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.