Package simtools.ui

Source Code of simtools.ui.DesktopCardPanel

/* ==============================================
* Simtools : The tools library used in JSynoptic
* ==============================================
*
* Project Info:  http://jsynoptic.sourceforge.net/index.html
*
* This library is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation;
* either version 2.1 of the License, or (at your option) any later version.
*
* This library 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* (C) Copyright 1999-2003, by :
*     Corporate:
*         Astrium SAS
*         EADS CRC
*     Individual:
*         Claude Cazenave
*     Nicolas Brodu
*
*
* $Id: DesktopCardPanel.java,v 1.16 2009/01/19 16:35:31 ogor Exp $
*
* Changes
* -------
* 25-Sep-2003 : Initial public release (NB);
* 18-mai-2005 : External desktop mode
*
*/

package simtools.ui;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.ResourceBundle;
import java.util.Stack;
import java.util.Vector;

import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JSeparator;
import javax.swing.JTabbedPane;
import javax.swing.JViewport;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import simtools.util.ListenerManager;

/**
* This class manages a list of swing components inside either internal frames
* (one per component) on a desktop or a single panel which displays only the
* selected component. Component selection is performed through a tab pane which
* displays components names using Component.getName(). The selected component
* is inside a frame which is at the top of the desktop when desktop mode is
* used. The selected component is displayed inside a panel under the tab pane
* when the single panel mode is used. A maximize action on one of the frame of
* the desktop leads to the single panel mode with the selected component Using
* the menu provided by the getMenu fonction, one can switch to the desktop pane
* by clicking on the cascade item This menu displays also all the available
* components and menu items to select components one after each other.
*
* @author Claude Cazenave
*
* @version 1.0 1999
*/
public class DesktopCardPanel extends JPanel implements ChangeListener,
        MouseListener, ActionListener {



    //
    // members
    //
    /** resources */
    protected static MenuResourceBundle _resources;
    static {
        try {
            _resources = (MenuResourceBundle) ResourceBundle.getBundle(
                    "simtools.ui.resources.DesktopCardPanelResource",
                    CustomizedLocale.get());
        } catch (Exception e) {
            System.err.println("Can't load DesktopCardPanel resources");
            System.exit(0);
        }
    }

    /** constant for the card display mode */
    public static final int CARD_MODE = 0;

    /** constant for the desktop display mode */
    public static final int DESKTOP_MODE = 1;

    /** constant for the external frame display mode */
    public static final int EXTERNAL_MODE = 2;
   
    /** the scrolling mode as defined in JViewPort */
    public static int SCROLLING_MODE=JViewport.BLIT_SCROLL_MODE;

    /** current layout mode */
    private int _currentMode = -1;

    /** tab panel for components names and selection */
    private JTabbedPane _namesPane;

    /** list of components */
    protected Vector _components;

    /** true if scrollable pane and frames are required */
    private boolean _scrollable;

    /** true if the inner frame can be closed */
    private boolean _closable;

    /** Selection menu */
    private JMenu _menu;

    /** Next menu item */
    private JMenuItem _miNext;

    /** Previous menu item */
    private JMenuItem _miPrevious;

    /** Cascade menu item */
    private JMenuItem _miCascade;

    /** Close All menu item */
    private JMenuItem _miCloseAll;

    /** Maximize menu item */
    private JMenuItem _miMaximize;

    /** External menu item */
    private JMenuItem _miExternal;

    /** button group to manage components menu items */
    private ButtonGroup _bgComponents;

   
    /** backward sheet button*/
    private JButton _bBackward;

    /** forward sheet button*/
    private JButton _bForward;

    /**
     * popup menu to be displayed when the right mouse is clicked above a card
     * item
     */
    protected JPopupMenu _cardPopup;

    /** a list of listener on component selection changes */
    private ListenerManager _listeners = new ListenerManager();

    protected DesktopCardPanelMode _desktopCardPanelMode;

   
    /**
     * Two stacks to manage previous and next sheet actions.
     * Contains pointers to existing sheets.
     */
    protected Stack backwardStack, forwardStack;
    //
    // public methods
    //

    /**
     * Creates a new DesktopCardPanel The single pane mode is selected The list
     * of components is empty
     *
     * @param scrollable
     *            true if scrollable pane and frames are required
     */
    public DesktopCardPanel(boolean scrollable) {
        this(scrollable, true);
    }

    /**
     * Creates a new DesktopCardPanel The single pane mode is selected The list
     * of components is empty
     *
     * @param scrollable
     *            true if scrollable pane and frames are required
     * @param closable
     *            true if inner frames created will be closable
     */
    public DesktopCardPanel(boolean scrollable, boolean closable) {
        super(new BorderLayout());

        backwardStack = new Stack();
        forwardStack = new Stack();
       
        _scrollable = scrollable;
        _closable = closable;

        createCardPopupMenu();
        _namesPane = new JTabbedPane();
        _namesPane.addChangeListener(this);
        _namesPane.addMouseListener(this);
        add(BorderLayout.NORTH, _namesPane);

        _components = new Vector();

        _miNext = null;
        _miPrevious = null;
        _miCascade = null;
        _miCloseAll = null;
        _miMaximize = null;
        _bgComponents = null;
        _bForward = null;
        _bBackward= null;

        setMode(CARD_MODE);

      
    }

    /**
     *
     * @return true if inner frames created will be closable
     */
    public boolean is_closable() {
        return this._closable;
    }
   
    /**
     *
     * @return true if  pane and frames are scrollable
     */
    public boolean is_scrollable() {
        return this._scrollable;
    }
    protected void createCardPopupMenu() {
        _cardPopup = new CardPopupMenu();
    }

    /**
     * @deprecated use setMode(int mode) instead
     *           
     *  Changes desktop mode
     *
     * @param state
     *            true if desktop is selected
     */
    public void setDesktopState(boolean state) {
        setMode(state ? DESKTOP_MODE : CARD_MODE);
    }

    /**
     * set the desktop display mode
     *
     * @param mode CARD_MODE, DESKTOP_MODE or EXTERNAL_MODE
     */
    public void setMode(int mode) {
        if (_currentMode == mode) {
            return;
        }
        _currentMode = mode;
        switch (mode) {
        case CARD_MODE:
            setDesktopCardPanelMode(new CardMode(this));
            break;
        case DESKTOP_MODE:
            setDesktopCardPanelMode(new DesktopMode(this));
            break;
        case EXTERNAL_MODE:
            setDesktopCardPanelMode(new ExternalMode(this));
            break;
        }

    }

    /**
     * set the implementation of the _desktopCardPanelMode wich handles the
     * display of the desktop components
     *
     * @param newMode the new implementation of DesktopCardPanelMode
     */
    protected void setDesktopCardPanelMode(DesktopCardPanelMode newMode) {
        if (_desktopCardPanelMode != null) {
            Container contentPane = _desktopCardPanelMode.getContentPane();
            if (contentPane != null) {
                remove(contentPane);
            }
        }
        Container newContentPane = newMode.getContentPane();
        if (newContentPane != null) {
            add(BorderLayout.CENTER, newContentPane);
        }
        validate();
        for (int i = 0; i < _components.size(); i++) {
            JComponent d = (JComponent) _components.elementAt(i);
            _desktopCardPanelMode.removeComponent(d);
            newMode.addComponent(d);
        }

        _desktopCardPanelMode = newMode;

        selectComponent(getSelectedComponent());

        if (_miCascade != null) {
            _miCascade.setEnabled(_currentMode != DESKTOP_MODE);
        }
        if (_miMaximize != null) {
            _miMaximize.setEnabled(_currentMode != CARD_MODE);
        }
        if (_miExternal != null) {
            _miExternal.setEnabled(_currentMode != EXTERNAL_MODE);
        }
        validate();
        repaint();
    }

    /**
     * Gets desktop current mode
     *
     * @return the current mode
     */
   
    public int getMode() {
        return this._currentMode;
    }
    /**
     * @deprecated use get mode instead
     *
     * Gets desktop mode
     *
     * @return true if desktop is selected
     */
    public boolean getDesktopState() {
        return _currentMode == DESKTOP_MODE;
    }

    /**
     * Gets the index of a component
     *
     * @param d
     *            the component
     * @return the component index or -1 if it doesn't exist
     */
    public int indexOfComponent(JComponent d) {
        for (int i = 0; i < _components.size(); i++) {
            JComponent c = (JComponent) _components.elementAt(i);
            if (c == d) {
                return i;
            }
        }
        return -1;
    }

    /**
     * Gets an iterator on the component list
     *
     * @return the iterator
     */
    public Iterator getComponentIterator() {
        return _components.iterator();
    }

    public JComponent getComponentAt(int index) {
        return (JComponent) _components.elementAt(index);
    }
    /**
     * returns the ComponentContainer that contains the specified component
     * @param d the component
     *
     * @return the container
     */
    public Container getContainer(JComponent d) {
        return this._desktopCardPanelMode.getContainer(d);
    }
    /**
     * Adds a component
     *
     * @param d
     *            the component
     */
    public void addComponent(JComponent d) {
        _components.addElement(d);
        JPanel dummy = new JPanel(new PanelsPaneLayout(this));
        _namesPane.addTab(d.getName(), dummy);
        _desktopCardPanelMode.addComponent(d);
        setComponentsMenuItems();
        selectComponent(d);
        repaint();
    }

    /**
     * Updates the name of a component
     *
     * @param d
     *            the component
     */
    public void updateComponentName(JComponent d) {
        int index = _components.indexOf(d);
        if (index < 0) {
            return;
        }
        _namesPane.setTitleAt(index, d.getName());

        _desktopCardPanelMode.updateComponentName(d);

        setComponentsMenuItems();

        // update menu if required
        if (_bgComponents != null) {
            Enumeration e = _bgComponents.getElements();
            while (e.hasMoreElements()) {
                ComponentRadioButton crb = (ComponentRadioButton) e
                        .nextElement();
                if (d == crb._component) {
                    if (!crb.isSelected()) {
                        crb.setSelected(true);
                    }
                    break;
                }
            }
        }
        repaint();
    }

    /**
     * Removes a component
     *
     * @param d
     *            the component
     */
    public void removeComponent(JComponent d) {
        int index = _components.indexOf(d);
        if (index < 0) {
            return;
        }

       
        _namesPane.removeTabAt(index);
        _components.removeElementAt(index);

        _desktopCardPanelMode.removeComponent(d);

        // Remove from forwardStack and backwardStack
        while (forwardStack.contains(d)){
            forwardStack.remove(forwardStack.indexOf(d));
        }
        while (backwardStack.contains(d)){
            backwardStack.remove(backwardStack.indexOf(d));
        }
       
        setComponentsMenuItems();

        // new selection is previous component if any
        if (_components.isEmpty()) {
            selectComponent(null);
        } else {
            if (index >= _components.size()) {
                selectComponent((JComponent) _components.lastElement());
            } else {
                selectComponent((JComponent) _components.elementAt(index));
            }
        }
     
        repaint();
    }

    /**
     * Removes all components
     */
    public void removeAllComponents() {
      Object[] components = _components.toArray();
       for (int i = 0; i < components.length; i++){
         JComponent d = (JComponent) components[i];
         removeComponent(d);
       }
        repaint();
    }
   
    /**
     * Removes all components
     */
    public void removeOtherComponents(JComponent jc) {
      Object[] components = _components.toArray();
      for (int i = 0; i < components.length; i++){
        JComponent d = (JComponent) components[i];
        if (!d.equals(jc))
          removeComponent(d);
      }

      repaint();
    }
   
   
    /**
     *  Save all components.
     */
    public void saveAllComponents() {
     
    }

    /**
     * Gets selected component
     *
     * @return the component or null if none
     */
    public JComponent getSelectedComponent() {
        int index = _namesPane.getSelectedIndex();
        if ((index < 0) || (index > _components.size())) {
            return null;
        }
        return (JComponent) _components.elementAt(index);
    }

    /**
     * Gets selected component index
     *
     * @return -1 if none
     */
    public int getSelectedIndex() {
        int index = _namesPane.getSelectedIndex();
        if ((index < 0) || (index > _components.size())) {
            return -1;
        }
        return index;
    }
   
    /**
     * Selects a component
     *
     * @param d the component
     */
    public void selectComponent(JComponent d) {
        _desktopCardPanelMode.selectComponent(d);
  
        // update tab pane
        for (int i = 0; i < _components.size(); i++) {
            if (d == _components.elementAt(i)) {
                if (_namesPane.getSelectedIndex() != i) {
                    _namesPane.setSelectedIndex(i);
                }
                break;
            }
        }
        // update menu if required
        if (_bgComponents != null) {
            Enumeration e = _bgComponents.getElements();
            while (e.hasMoreElements()) {
                ComponentRadioButton crb = (ComponentRadioButton) e
                        .nextElement();
                if (d == crb._component) {
                    if (!crb.isSelected()) {
                        crb.setSelected(true);
                    }
                    break;
                }
            }
        }
        // propagate component selection to listeners
        synchronized (_listeners) {
            int n = _listeners.size(); // only one call outside loop
            for (int i = 0; i < n; ++i) {
                DesktopCardPanelListener dcpl = (DesktopCardPanelListener) _listeners
                        .get(i);
                if (dcpl != null)
                    dcpl.componentSelected(d);
            }
        }
        // Update backward and foreward buttons
        if (_bForward!=null)
          _bForward.setEnabled(!forwardStack.isEmpty());

        if (_bBackward!=null)
          _bBackward.setEnabled(backwardStack.size()>=2);
       
        repaint();
    }
   
    /**
     * Adds a new Listener on component selection
     */
    public void addListener(DesktopCardPanelListener dcpl) {
        _listeners.add(dcpl);
    }

    /**
     * Removes a Listener on component selection
     */
    public void removeListener(DesktopCardPanelListener dcpl) {
        _listeners.remove(dcpl);
    }

    /**
     * Removes all Listeners on component selection
     */
    public void removeAllListeners() {
        _listeners.clear();
    }
   
    /**
     * @return the previous sheet button
     */
    public JButton createPreviousButton(){
      _bBackward = _resources.getBox("prev", this);
      return _bBackward;
    }
   
    /**
     * @return the next sheet button
     */
    public JButton createNextButton(){
      _bForward = _resources.getBox("next", this);
      return _bForward;
    }
 
    /**
     * Creates a menu to switch between components Each component is displayed
     * in the menu using toString()
     *
     * @param the
     *            menu name
     * @return a new menu or null is one already created
     */
    public JMenu createMenu(String name) {
        return createMenu(name, true);
    }

    /**
     * Creates a menu to switch between components Each component is displayed
     * in the menu using toString()
     *
     * @param name
     *            the menu name
     * @param enableCloseAll
     *            a boolean indicating if the 'Close all' menu item is showed
     * @return a new menu or null is one already created
     */
    public JMenu createMenu(String name, boolean enableCloseAll) {
        if (_menu != null) {
            return null;
        }
        if (name != null) {
            _menu = new JMenu(name);
            _menu.setMnemonic(name.charAt(0));
        } else {
            _menu = _resources.getMenu("windows");
        }

        _menu.add(_miNext = _resources.getItem("next", this));
        _menu.add(_miPrevious = _resources.getItem("previous", this));

        _menu.add(new JSeparator());

        _menu.add(_miMaximize = _resources.getItem("maximize", this));
        if (_currentMode == CARD_MODE) {
            _miMaximize.setEnabled(false);
        }

        _menu.add(_miCascade = _resources.getItem("cascade", this));
        if (_currentMode == DESKTOP_MODE) {
            _miCascade.setEnabled(false);
        }

        _menu.add(_miExternal = _resources.getItem("external", this));
        if (_currentMode == EXTERNAL_MODE) {
            _miCascade.setEnabled(false);
        }

        _menu.add(new JSeparator());

        if (enableCloseAll) {
            _menu.add(_miCloseAll = _resources.getItem("closeAll", this));
            _menu.add(new JSeparator());
        }

        _bgComponents = new ButtonGroup();
        setComponentsMenuItems();

        return _menu;
    }

    /**
     * Constructs the menu to navigate between components
     */
    private void setComponentsMenuItems() {
        if (_bgComponents == null) {
            return;
        }

        // remove all items
        Enumeration e = _bgComponents.getElements();
        while (e.hasMoreElements()) {
            JMenuItem mi = (JMenuItem) e.nextElement();
            _menu.remove(mi);
        }
        _bgComponents = new ButtonGroup();

        // add new ones
        for (int i = 0; i < _components.size(); i++) {
            ComponentRadioButton crb = new ComponentRadioButton(
                    (JComponent) _components.elementAt(i));
            _menu.add(crb);
            _bgComponents.add(crb);
        }
    }

    //
    //   MouseListener interface
    //
    public void mouseClicked(MouseEvent e) {
    }

    public void mouseEntered(MouseEvent e) {
    }

    public void mouseExited(MouseEvent e) {
    }

    public void mousePressed(MouseEvent e) {
        if ((e.getModifiers() & MouseEvent.BUTTON3_MASK) == MouseEvent.BUTTON3_MASK) {
            if (_cardPopup != null) {
                _cardPopup.show(this, e.getX(), e.getY());
            }
        }
    }

    public void mouseReleased(MouseEvent e) {
    }

    // Action listener interface
    //
    public void actionPerformed(ActionEvent e) {
        if ((e.getSource() == _miNext) || (e.getSource() == _miPrevious)) {
         
          // TODO
            int index = _namesPane.getSelectedIndex();
            int s = _components.size();
            if (s == 0) {
                return;
            }
            if (e.getSource() == _miNext){
                index++;
                if (index >= s) {
                    index = 0;
                }
            } else {
                index--;
                if (index < 0) {
                    index = s - 1;
                }
            }
            selectComponent((JComponent) _components.elementAt(index));
           
        } else if (e.getSource() == _bForward){
          next();
        } else if (e.getSource() == _bBackward){
          back();
        } else if (e.getSource() == _miCascade) {
            setMode(DESKTOP_MODE);
        } else if (e.getSource() == _miCloseAll) {
            removeAllComponents();
        } else if (e.getSource() == _miMaximize) {
            setMode(CARD_MODE);
        } else if (e.getSource() == _miExternal) {
            setMode(EXTERNAL_MODE);
        }
    }
      
    protected void back(){
      if (backwardStack.size()>=2){
        forwardStack.push((JComponent)backwardStack.pop());
        JComponent prevComp = (JComponent)backwardStack.pop();
        selectComponent(prevComp);
      }
    }
 
  protected void next(){
    if (!forwardStack.isEmpty()){
      JComponent nextComp = (JComponent)forwardStack.pop();
      //backwardStack.push(nextComp);
      selectComponent(nextComp);
    }
  }
 
    //
    // Change listener interface
    //
    public void stateChanged(ChangeEvent e) {
        int index = _namesPane.getSelectedIndex();
        if ((index < 0) || (index > _components.size())) {
            return;
        }
        JComponent d = (JComponent) _components.elementAt(index);
        backwardStack.push(d);
        selectComponent(d);
    }

    /**
     * The radio button to choose a component in the menu
     */
    public class ComponentRadioButton extends JRadioButtonMenuItem implements
            ActionListener {

        /** the component */
        JComponent _component;

        /**
         * Constructs a new RadioButton for the given component
         *
         * @param component
         *            the linked component
         */
        public ComponentRadioButton(JComponent component) {
            super();
            _component = component;
            setText(_component.getName());
            addActionListener(this);
        }

        //
        // Action listener interface
        //
        public void actionPerformed(ActionEvent e) {
            if (isSelected()) {
                selectComponent(_component);
             
            }
        }
    }

    /**
     * The Layout for the panel which holds the component panels
     */
    public class PanelsPaneLayout implements LayoutManager {
        private JComponent _mirrored;

        /**
         * Creates a layout which size fit the size of a mirrored component
         *
         * @param mirrored
         *            the mirrored component
         */
        PanelsPaneLayout(JComponent mirrored) {
            _mirrored = mirrored;
        }

        /**
         * Adds the specified component to the layout. Not used by this class.
         *
         * @param name
         *            the name of the component
         * @param comp
         *            the component to be added
         */
        public void addLayoutComponent(String name, Component comp) {
        }

        /**
         * Removes the specified component from the layout. Not used by this
         * class.
         *
         * @param comp
         *            the component to remove
         */
        public void removeLayoutComponent(Component comp) {
        }

        /**
         * Returns the preferred dimensions for this layout
         *
         * @param target
         *            the component which needs to be laid out
         * @return the preferred dimensions to lay out
         */
        public Dimension preferredLayoutSize(Container target) {
            if (_mirrored != null) {
                int w = _mirrored.getSize().width;
                return new Dimension(w, 0);
            }
            if (target.getComponentCount() == 0) {
                return new Dimension(0, 0);
            }
            return target.getSize();
        }

        /**
         * Returns the minimum dimensions for this layout
         *
         * @param target
         *            the component which needs to be laid out
         * @return the minimum dimensions to lay out
         */
        public Dimension minimumLayoutSize(Container target) {
            if (target.getComponentCount() == 0) {
                return new Dimension(0, 0);
            }
            return target.getComponent(0).getMinimumSize();
        }

        /**
         * Lays out the container. This method reshape to its container size the
         * component it holds
         *
         * @param target
         *            the specified component being laid out.
         * @see Container
         * @see java.awt.Container#doLayout
         */
        public void layoutContainer(Container target) {
            if (target.getComponentCount() == 0) {
                return;
            }
            Component c = target.getComponent(0);
            Dimension d = target.getSize();
            c.setSize(d.width, d.height);
            c.setLocation(0, 0);
        }
    }

    /**
     * A popup menu to be displayed when a card is selected
     */
    public class CardPopupMenu extends JPopupMenu implements ActionListener {

        protected JMenuItem _miClose, _miCloseOther, _miCloseAll;

        /**
         * Constructs a new CardPopupMenu instance
         */
        public CardPopupMenu() {
            super();
            add(_miClose = _resources.getItem("closeCard", this));
            add(_miCloseOther = _resources.getItem("closeOther", this));
            add(_miCloseAll = _resources.getItem("closeAll", this));
        }

       
        //
        //   ActionListener interface
        //
        public void actionPerformed(ActionEvent e) {
            if (e.getSource() == _miClose)
                removeComponent(getSelectedComponent());
        }
    }
}
TOP

Related Classes of simtools.ui.DesktopCardPanel

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.