Package net.xoetrope.swing.app

Source Code of net.xoetrope.swing.app.XDockingApp

package net.xoetrope.swing.app;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Toolkit;
import java.net.URL;
import javax.swing.JFrame;
import javax.swing.JMenuBar;

import net.xoetrope.xui.XProject;
import net.xoetrope.swing.SwingWidgetAdapter;

import net.xoetrope.xui.XApplicationContext;
import net.xoetrope.xui.XStartupObject;
import java.awt.Component;
import java.awt.Container;
import java.awt.SystemColor;
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Hashtable;
import javax.swing.JPanel;
import net.xoetrope.swing.docking.XCardPanel;
import net.xoetrope.swing.docking.XDockable;
import net.xoetrope.swing.docking.XDockingPanel;
import net.xoetrope.swing.docking.XDockingSideBar;
import net.xoetrope.xui.PageSupport;
import net.xoetrope.xui.XPage;
import net.xoetrope.xui.XProjectManager;
import net.xoetrope.xui.helper.XTranslator;
import net.xoetrope.xui.style.XStyle;
import net.xoetrope.xui.style.XStyleEx;
import net.xoetrope.xui.style.XStyleManager;
import org.jdesktop.swingx.MultiSplitLayout;
import org.jdesktop.swingx.JXMultiSplitPane;

import org.jdesktop.swingx.painter.Painter;

/**
* <p>A startup class for a desktop/MDI style of application.</p>
* <p>For information on the initial docking layout please see the article
* <a ref="http://today.java.net/pub/a/today/2006/03/23/multi-split-pane.html">
* MultiSplitPane: Splitting Without Nesting</a></p>
* <p>Copyright: Copyright (c) Xoetrope Ltd., 1998-2003<br>
* License:      see license.txt
* @version $Revision: 1.1 $
*/
public class XDockingApp extends JFrame implements XStartupObject
{
  protected XApplicationContext applicationContext;

  protected XCardPanel cardPanel;
  protected JPanel dockingPanel;
  protected JXMultiSplitPane multiSplitPane;
  protected XDockingSideBar leftSidebar;
  protected XDockingSideBar rightSidebar;
  protected XDockingSideBar bottomSidebar;
 
  protected PageSupport northDecoration;

  protected JMenuBar menuBar;
  protected XProject currentProject; 

  protected String defaultLayoutDef =
      "(COLUMN " +
      " (ROW name=top weight=0.7 " +
      "   (LEAF name=left weight=0.1) " +
      "   (LEAF weight=0.8 name=content) " +
      "   (LEAF name=right weight=0.1)" +
      " ) " +
      " (LEAF name=bottom weight=0.3)" +
      ")";
 
  private boolean exclusiveView;

  /**
   * main method to be invoked as an application. This method is invoked as the
   * entry point to the 'Application', it is not used if an Applet is being
   * launched. This method establishes the frame within which the application
   * runs. If overloading this method remeber to call the setup method.
   * @param args the command line arguments
   */
  public static void main( String args[] )
  {
    final String[] theArgs = args;

    //Schedule a job for the event-dispatching thread:
    //creating and showing this application's GUI.
    javax.swing.SwingUtilities.invokeLater( new Runnable()
    {
      public void run()
      {
        createAndShowGUI( theArgs );
      }
    });
  }
 
 
  /**
   * Creates a new instance of XDesktopApp
   * @param args the startup arguments
   */
  public XDockingApp( String[] args )
  {
    super( "XUI" );
    currentProject = XProjectManager.getCurrentProject( this );

    // Setup the docking framework
    dockingPanel = new JPanel();
    dockingPanel.setLayout( new BorderLayout());
   
    // Setup the sidebars
    Container glassPane = (Container)getRootPane().getGlassPane();
    leftSidebar = new XDockingSideBar( glassPane, "west" );
    rightSidebar = new XDockingSideBar( glassPane, "east" );
    bottomSidebar = new XDockingSideBar( glassPane, "south" );

    // Setup the default layout
    MultiSplitLayout.Node modelRoot = MultiSplitLayout.parseModel( defaultLayoutDef );

    multiSplitPane = new JXMultiSplitPane();
    multiSplitPane.setDividerSize( 5 );
    multiSplitPane.getMultiSplitLayout().setModel( modelRoot );
   
    MultiSplitLayout multiSplitLayout = multiSplitPane.getMultiSplitLayout();
    multiSplitLayout.setLayoutMode( MultiSplitLayout.USER_MIN_SIZE_LAYOUT  );
    multiSplitLayout.layoutByWeight( multiSplitPane );

    cardPanel = new XCardPanel( multiSplitPane );

    dockingPanel.add( leftSidebar, BorderLayout.WEST );
    dockingPanel.add( rightSidebar, BorderLayout.EAST );
    dockingPanel.add( bottomSidebar, BorderLayout.SOUTH );
    dockingPanel.add( cardPanel, BorderLayout.CENTER );

    //Set up the GUI.
    setContentPane( dockingPanel );
    SwingWidgetAdapter.getInstance();
    applicationContext = new XApplicationContext( this, "net.xoetrope.swing.app.XDockableFrame", args );
   
    // Style the panel
    XStyleManager sm = currentProject.getStyleManager();
    if ( sm.hasStyle( "dockingApp" )) {
      XStyle dockingStyle = sm.getStyle( "dockingApp" );
      multiSplitPane.setBackground( dockingStyle.getStyleAsColor( XStyle.COLOR_BACK ));
      XStyleEx exStyle = (XStyleEx)dockingStyle;
      int idx = exStyle.getStyleIndex( "padding" );
      if ( idx > 0 ) {
        int padding = new Integer( exStyle.getStyleValue( idx ).toString()).intValue();
          multiSplitPane.setDividerSize( padding );
      }
    }

    // Apply styles to the sidebars
    applyStyles( leftSidebar );
    applyStyles( rightSidebar );
    applyStyles( bottomSidebar );
  }
 
  /**
   * Carry out any post creation styling. This method is called one the
   * application frameowrk has been setup. By default the method sets the
   * colours of the component as the style manager is now available.
   */
  public void applyStyles( XDockingSideBar target )
  {
    Color sidebarBkColor = SystemColor.control;
    Color sidebarTextColor = SystemColor.controlText;
    Color sidebarRolloverTextColor = SystemColor.controlText;
   
    XStyleManager sm = currentProject.getStyleManager();
    if ( sm.hasStyle( "dockingSidebar" )) {
      XStyle xstyle = sm.getStyle( "dockingSidebar" );
      sidebarBkColor = xstyle.getStyleAsColor( XStyle.COLOR_BACK );
      sidebarTextColor = xstyle.getStyleAsColor( XStyle.COLOR_FORE );
     
      xstyle = sm.getStyle( "dockingSidebar/active" );
      sidebarRolloverTextColor = xstyle.getStyleAsColor( XStyle.COLOR_FORE );
    }
    target.applyStyles( sidebarBkColor, sidebarTextColor, sidebarRolloverTextColor );
  }
 
  /**
   * Set a background painter for the empty docking panel
   * @param painter a background painter
   */
  public void setBackgroundPainter( Painter p )
  {
    multiSplitPane.setBackgroundPainter( p );
  }
 
  /**
   * Get the side bar for a particular object
   * @param key the key for looking up the sidebar
   * @return the sidebar
   */
  public XDockingSideBar getSidebar( String key )
  {
    String keyLower = key.toLowerCase();
    if ( keyLower.equals( "south" ) || keyLower.equals( "bottom" ))
      return bottomSidebar;
    else if ( keyLower.equals( "east" ) || keyLower.equals( "right" ))
      return rightSidebar;
    else if ( keyLower.equals( "west" ) || keyLower.equals( "left" ))
      return leftSidebar;
    else
      return null;
  }
 
  /**
   * Set the visibility of the sidebars and toolbars
   * @param state true to make the decorations visible
   */
  public void setDecorationsVisible( boolean state )
  {
    leftSidebar.setVisible( state );
    rightSidebar.setVisible( state );
    bottomSidebar.setVisible( state );
    if ( northDecoration != null )
      ((Component)northDecoration).setVisible( state );
  }
 
  /**
   * <p>Display a window decoration, for example a toolbar.</p>
   * <p>This method only sets
   * the decoration for the NORTH constraint. It is intended for setting a
   * toolbar.</p>
   * @param page the new page
   * @param constraint a value controlling how and where the decoration is
   * displayed, this value is application type specific
   * @return the page being displayed or null if the constraint is not handled
   * @deprecated use addDecoration
   */
  public Object displayDecoration( PageSupport page, String constraint )
  {
    return addDecoration( page, constraint );
  }
 
  /**
   * <p>Display a window decoration, for example a toolbar.</p>
   * <p>This method only sets
   * the decoration for the NORTH constraint. It is intended for setting a
   * toolbar.</p>
   * @param page the new page
   * @param constraint a value controlling how and where the decoration is
   * displayed, this value is application type specific
   * @return the page being displayed or null if the constraint is not handled
   */
  public Object addDecoration( PageSupport page, String constraint )
  {
    String key = constraint.toLowerCase();
    if ( key.equals( "north" ) || key.equals( "top" )) {
      northDecoration = page;
      dockingPanel.add( (Component)page, BorderLayout.NORTH );
      return page;
    }
   
    return null;
  }
 
  /**
   * Set the visibility of a border layout's component or so called decoration
   * @param constraint must be "NORTH" to have any effect
   * @param visible the visibility state
   */
  public void setDecorationVisibility( String constraint, boolean visible )
  {
    Component decoration = null;
   
    String key = constraint.toLowerCase();
    if ( key.equals( "north" ) || key.equals( "top" ))
      decoration = (Component)northDecoration;
    else if ( key.equals( "south" ) || key.equals( "bottom" ))
      decoration = bottomSidebar;
    else if ( key.equals( "east" ) || key.equals( "right" ))
      decoration = leftSidebar;
    else if ( key.equals( "west" ) || key.equals( "left" ))
      decoration = rightSidebar;
   
    if ( decoration != null ) {
      decoration.setVisible( visible );
      doLayout();
    }
  }
 
  /**
   * Show one of the content panels as the exclusive content, hiding the
   * sidebars, headers and other decorations
   * @param comp the component to display exclusively in the content area
   * @param state true for an exclusive display, false to restore the normal display
   */
  public void showExclusive( Object comp, boolean state )
  {
    exclusiveView = state;
    setDecorationsVisible( !state );
    XDockable dockable = findDockable( comp );
    if ( dockable != null ) {
      dockable.header.zoomPanel();
     
      // Hide the header panel
      dockable.header.getParent().setVisible( !state );

      Object mo = currentProject.getObject( "MenuBar" );
      XStartupObject startupObject = currentProject.getStartupObject();
      if ( state )
        startupObject.setApplicationMenuBar( null );     
      else 
        startupObject.setApplicationMenuBar( mo );
     
    }

    cardPanel.doLayout();
    multiSplitPane.doLayout();
    repaint();
  }
 
  /**
   * Get the package name for the default widget set
   */
  public String getWidgetClassPackage()
  {
    return XPage.XUI_SWING_PACKAGE;
  }

  /**
   * Get a startup parameter
   * @param param the name of the parameter
   */
  public String getParameter( String param )
  {
    return "";
  }

  /**
   * Get the content pane used by XUI - the container in which pages are
   * displayed
   * @return the page container
   */
  public Object getContentPaneEx()
  {
    return multiSplitPane;
  }
 
  /**
   * Get the parent container/object
   * @return the parent
   */
  public Object getParentObject()
  {
    return super.getParent();
  }

  /**
   * Gets the URL of the document in which this applet is embedded.
   * For example, suppose an applet is contained
   * within the document:
   * <blockquote><pre>
   *    http://java.sun.com/products/jdk/1.2/index.html
   * </pre></blockquote>
   * The document base is:
   * <blockquote><pre>
   *    http://java.sun.com/products/jdk/1.2/index.html
   * </pre></blockquote>
   *
   * @return  the {@link java.net.URL} of the document that contains this
   *          applet.
   * @see     java.applet.Applet#getCodeBase()
   */
  public URL getDocumentBase()
  {
    return null;
  }

  /**
   * Setup frameset. This method is called prior to the addition of any target
   * areas in the framset and prior to the display of any pages. Since this
   * applet does not support configurable framesets, this method ignores the
   * parameter values passed.
   * @param params the framset parameters if any
   * <ul>
   * <li>config - the layout configuration, for example <code>(COLUMN (ROW weight=1.0 left (COLUMN middleTop content middleBottom) right) bottom)</code>
   * </ul>
   */
  public void setupFrameset( Hashtable params )
  {   
    String layout = (String)params.get( "config" );
    if (( layout == null ) || ( layout.length() == 0 ))
      layout = defaultLayoutDef;
   
    MultiSplitLayout.Node modelRoot = MultiSplitLayout.parseModel( layout );
    MultiSplitLayout multiSplitLayout = multiSplitPane.getMultiSplitLayout();
    multiSplitLayout.setModel( modelRoot );
    multiSplitLayout.layoutByWeight( multiSplitPane );
  }
 
  /**
   * Validate and repaint the display
   */
  public void refresh()
  {
    invalidate();
    validate();
    repaint();
  }

  public void setAppTitle( String title )
  {
    XTranslator translator = currentProject.getTranslator();
    setTitle( translator.translate( title ));
  }

  /**
   * Set the application icon
   * @param img the image name
   */
  public void setIcon( Image img )
  {
    setIconImage( img );
  }

  /**
   * Setup the windowing.
   * @param context the owner application context
   * @param currentProject the owner project
   * @param clientWidth the desired width of the application
   * @param clientHeight the desired height of the application
   */
  public void setupWindow( XApplicationContext context, XProject currentProject,
                           int clientWidth, int clientHeight )
  {
    currentProject.setStartupParam( "MainClass", "net.xoetrope.swing.app.XDockingApp" );

    setSize( clientWidth, clientHeight );
    addWindowListener( context );

    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    Dimension frameSize = getSize();
    String center = null;
    try {
      center = currentProject.getStartupParam( "CenterWin" );
    }
    catch ( Exception ex ) {
    }
    if ( ( center != null ) && ( center.compareTo( "true" ) == 0 ) )
      setLocation( ( screenSize.width - frameSize.width ) / 2,
                   ( screenSize.height - frameSize.height ) / 2 );
    setVisible( true );

    currentProject.setApplet( null );
    currentProject.setStartupObject( this );
    currentProject.setAppFrame( this );
    currentProject.setAppWindow( this );
  }

  /**
   * Get the menubar, setting it up if it is not already added to the
   * application frame
   * @return the menu bar
   */
  public Object getApplicationMenuBar()
  {
    if ( menuBar == null )
      menuBar = getJMenuBar();
    return menuBar;
  }

  /**
    * Set the menubar
    * @param mb the menubar
    */
  public void setApplicationMenuBar( Object mb )
  {
    setJMenuBar( (JMenuBar)mb );
  }

  /**
   * Create the GUI and show it.  For thread safety,
   * this method should be invoked from the
   * event-dispatching thread.
   */
  private static void createAndShowGUI( String[] args )
  {
    //Make sure we have nice window decorations.... but this causes a problem
    // with the Windows LAF in JDK 1.5 at least - Luan
    //JFrame.setDefaultLookAndFeelDecorated( true );

    //Create and set up the window.
    XDockingApp frame = new XDockingApp( args );
//    frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    frame.setDefaultCloseOperation( JFrame.DO_NOTHING_ON_CLOSE );

    //Display the window.
    frame.setVisible( true );
  }

  /**
   * Save the layout
   */
  public void saveLayout( OutputStream os )
  {
    // Save the MultiSplitPane attributes
    try  {
      XMLEncoder e =  new XMLEncoder( new BufferedOutputStream( os ));
      MultiSplitLayout.Node model = multiSplitPane.getMultiSplitLayout().getModel();
      e.writeObject( model );
      e.close();
    }
    catch (Exception e) {}
  }
 
  /**
   * Attempt to restore the docking layout
   */  
  public void loadLayout( InputStream is )
  {
    MultiSplitLayout multiSplitLayout = multiSplitPane.getMultiSplitLayout();
    try {
      XMLDecoder d = new XMLDecoder(new BufferedInputStream( is ));
      MultiSplitLayout.Node model = (MultiSplitLayout.Node)( d.readObject());
      multiSplitLayout.setModel( model );
      multiSplitLayout.setFloatingDividers( false );
      d.close();

      // trick is used to restore the size of the example window
      multiSplitPane.setPreferredSize( model.getBounds().getSize());
     
      dockHiddenChildren();
    }
    catch (Exception exc) {
      MultiSplitLayout.Node model = MultiSplitLayout.parseModel( defaultLayoutDef );
      multiSplitLayout.setModel( model );
    }
  }

  /**
   * Restore the normal page views, as in the case of the docking layout where
   * panels may be zoomed or minimized. This method is called prior to the
   * display of a new page.
   */
  public void restoreViews()
  {
    if ( !exclusiveView )
      cardPanel.restoreViews();
  }
 
  /**
   * Find the dockable object that wraps a particular component
   * @param content the content that is wrapped by the XDockable
   * @return the XDockable instance or null if the component was not found
   */
  public XDockable findDockable( Object content )
  {
    MultiSplitLayout multiSplitLayout = multiSplitPane.getMultiSplitLayout();
    int numChildren = multiSplitPane.getComponentCount();
    for ( int i = 0; i < numChildren; i++ ) {
      Component comp = multiSplitPane.getComponent( i );
      if ( comp instanceof XDockableFrame ) {
        XDockable dockable = ((XDockableFrame)comp).findDockable( content );
        if ( dockable != null )
          return dockable;
      }
    }
   
    XDockable dockable = cardPanel.getDockable();
    if ( dockable != null ) {
      if (( dockable.content == content ) || ( dockable.dockedContainer == content ) || ( dockable.header == content ))
        return dockable;
    }
   
    return null;
  }
 
  /**
   * Dock any children that have been restored.
   */
  private void dockHiddenChildren()
  {
    MultiSplitLayout multiSplitLayout = multiSplitPane.getMultiSplitLayout();
    int numChildren = multiSplitPane.getComponentCount();
    for ( int i = 0; i < numChildren; i++ ) {
      Component comp = multiSplitPane.getComponent( i );
      if ( comp instanceof XDockingPanel ) {
        MultiSplitLayout.Node node = multiSplitLayout.getNodeForComponent( comp );
        if ( !node.isVisible())
          ((XDockingPanel)comp).dock();
      }
    }
  }
}
TOP

Related Classes of net.xoetrope.swing.app.XDockingApp

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.