Package gov.nasa.arc.mct.gui.housing

Source Code of gov.nasa.arc.mct.gui.housing.MCTContentArea$PopupListener

/*******************************************************************************
* Mission Control Technologies, Copyright (c) 2009-2012, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* The MCT platform is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*
* MCT includes source code licensed under additional open source licenses. See
* the MCT Open Source Licenses file included with this distribution or the About
* MCT Licenses dialog available at runtime from the MCT Help menu for additional
* information.
*******************************************************************************/
/*
* MCTContentArea.java - Aug. 18, 2008.
*
* This code is property of the National Aeronautics and Space Administration
* and was produced for the Mission Control Technologies (MCT) Project.
*
*/
package gov.nasa.arc.mct.gui.housing;

import gov.nasa.arc.mct.components.AbstractComponent;
import gov.nasa.arc.mct.gui.ActionContext;
import gov.nasa.arc.mct.gui.CompositeViewManifestationProvider;
import gov.nasa.arc.mct.gui.ContextAwareButton;
import gov.nasa.arc.mct.gui.SelectionProvider;
import gov.nasa.arc.mct.gui.SettingsButton;
import gov.nasa.arc.mct.gui.View;
import gov.nasa.arc.mct.gui.ViewProvider;
import gov.nasa.arc.mct.gui.actions.RefreshAction;
import gov.nasa.arc.mct.gui.housing.MCTHousing.ControlProvider;
import gov.nasa.arc.mct.gui.impl.ActionContextImpl;
import gov.nasa.arc.mct.gui.menu.MenuFactory;
import gov.nasa.arc.mct.platform.spi.PlatformAccess;
import gov.nasa.arc.mct.services.component.ViewInfo;
import gov.nasa.arc.mct.services.component.ViewType;
import gov.nasa.arc.mct.util.LafColor;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JToggleButton;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;

/**
* Framework for holding the MCT Content Area (often refereed to as "the canvas") including its title bar and
* control panel.
*/

@SuppressWarnings("serial")
public class MCTContentArea extends JPanel implements CompositeViewManifestationProvider, SelectionProvider, ControlProvider {

    public static final String CENTER_PANE_VIEW_CHANGE = "center-pane-view-change";
   
    private MCTHousing parentHousing;
    private final AbstractComponent ownerComponent;
    private CanvasTitleArea titleBar;
    private View ownerComponentCanvasManifestation = null; // The current contained view manifestation.

    private JSplitPane splitPane = null; // hold owner component canvas manifestation and its control area.

    private boolean canvasTitleBarShowing = true;
    private JComponent controlManifestation = null;
    private int dividerSize = 0; // size of split pane's divider.
   
    private final Map<ViewInfo, ViewProvider> housedManifestations = new HashMap<ViewInfo, ViewProvider>();

    private ContextAwareButton refreshButton = new ContextAwareButton(new RefreshAction());
   
    private static final ResourceBundle BUNDLE =
            ResourceBundle.getBundle(
                    MCTStandardHousing.class.getName().substring(0,
                            MCTStandardHousing.class.getName().lastIndexOf("."))+".Bundle");

    private final JLabel STALE_LABEL = new JLabel(BUNDLE.getString("view.modified.status.bar.text"));
    private final PropertyChangeListener selectionListener = new PropertyChangeListener() {
        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            firePropertyChange(evt.getPropertyName(), evt.getOldValue(), evt.getNewValue());
        }
    };

    private final PropertyChangeListener objectStaleStateListener = new PropertyChangeListener() {
       
        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            markStale((Boolean)evt.getNewValue());
        }
    };
    public MCTContentArea(MCTHousing parentHousing, AbstractComponent ownerComponent, View initialViewManifestation) {
        super(new BorderLayout());
        STALE_LABEL.setToolTipText(BUNDLE.getString("view.modified.status.bar.tooltip.text"));
        this.parentHousing = parentHousing;
        this.ownerComponent = ownerComponent;
        if (ownerComponentCanvasManifestation == null) {
            AbstractComponent clonedComponent = PlatformAccess.getPlatform().getPersistenceProvider().getComponent(ownerComponent.getComponentId());
            ownerComponentCanvasManifestation = ((initialViewManifestation != null)
                    ? initialViewManifestation
                            : clonedComponent.getViewInfos(ViewType.CENTER).iterator().next().createView(clonedComponent));
        }

        assert ownerComponentCanvasManifestation != null
        setOwnerComponentCanvasManifestation(ownerComponentCanvasManifestation);
        this.revalidate();
        this.parentHousing.setContentArea(this);
               
        refreshButton.setContentAreaFilled(false);
        refreshButton.setText("");
        refreshButton.setBorder(BorderFactory.createEmptyBorder());
        refreshButton.setContext(context);
       
        STALE_LABEL.setForeground(Color.red);
    }

    public MCTContentArea(MCTHousing parentHousing, AbstractComponent ownerComponent) {
        this(parentHousing, ownerComponent, null);
    }

    public MCTContentArea(MCTHousing parentHousing, View initialViewManifestation) {
        this(parentHousing, initialViewManifestation.getManifestedComponent(), initialViewManifestation);
    }
   
    @Override
    public Collection<View> getSelectedManifestations() {
        return ownerComponentCanvasManifestation.getSelectionProvider().getSelectedManifestations();
    }
   
    public void showControl(boolean flag) {  
       if (splitPane != null) {
            if (!flag) {
                splitPane.setDividerLocation(0);
            } else if (controlManifestation.getPreferredSize().getHeight() < 200)  {
                // Small control manifesation. Give it a small percentage of the panes.
                 splitPane.setDividerLocation((int) controlManifestation.getPreferredSize().getHeight());
             } else {
                 splitPane.setDividerLocation(-1);
                 splitPane.setResizeWeight(0.66);
             }
            splitPane.setDividerSize(flag ? dividerSize : 0);
            if (controlManifestation != null) {
               controlManifestation.setVisible(flag);
               titleBar.controlToggle.setSelected(flag);
            }
            revalidate();
       }
    }
   
    @Override
    public boolean isControlShowing() {
        return controlManifestation.isVisible();   
    }

    public void markStale(boolean isStale) {
        MCTStatusArea statusArea = parentHousing.getStatusArea();
        if (statusArea == null)
            return;
        if (isStale)
            statusArea.addToLeft(STALE_LABEL);
        else
            statusArea.removeFromLeft(STALE_LABEL);
    }
   
    private void setupSelectionPropertyChangeListener(View oldManifestation) {
        if (oldManifestation != null) {
            oldManifestation.getSelectionProvider().removeSelectionChangeListener(selectionListener);
        }

        if (ownerComponentCanvasManifestation != null) {
            ownerComponentCanvasManifestation.getSelectionProvider().addSelectionChangeListener(selectionListener);
        }
    }

    public MCTContentArea() {
        super(new BorderLayout());
        ownerComponent = null;
    }

    public boolean isTitleBarShowing() {
        return this.canvasTitleBarShowing;
    }

    public void showCanvasTitle(boolean doShow) {
        canvasTitleBarShowing = doShow;
        if (doShow) {
            add(this.titleBar, BorderLayout.NORTH);
        } else {
            remove(this.titleBar);
            showControl(false);
            titleBar.setTitleAreaVisible(false);
        }
        doLayout();
        validate();
    }

    public JComponent getContentAreaPane() {
        return this.ownerComponentCanvasManifestation;
    }

    public void setParentHousing(MCTHousing parentHousing) {
        this.parentHousing = parentHousing;
        this.refreshButton.setContext(context);
    }
   
    /**
     * Set the owner view manifestation and update the GUI to display it.
     * @param viewManifestation
     */
    public void setOwnerComponentCanvasManifestation(View viewManifestation) {
        if (viewManifestation == null) {
            throw new IllegalArgumentException("viewManifestation argument cannot be null");
        }

        ownerComponentCanvasManifestation.removePropertyChangeListener(View.VIEW_STALE_PROPERTY, objectStaleStateListener);
        markStale(false);
        viewManifestation.addPropertyChangeListener(View.VIEW_STALE_PROPERTY, objectStaleStateListener);
       
        housedManifestations.put(viewManifestation.getInfo(), viewManifestation);

        if (ownerComponentCanvasManifestation != null) {
            // clean out previous manifestation's swing components if there is one.
            removeAll();
            SelectionProvider provider = ownerComponentCanvasManifestation.getSelectionProvider();
            Collection<View> selections = provider.getSelectedManifestations();
            if (!selections.isEmpty()) {
                provider.clearCurrentSelections();
                firePropertyChange(SelectionProvider.SELECTION_CHANGED_PROP, selections, Collections.emptyList());
            }
        }
       
        // setup new manifestation.
        View oldManifestation = ownerComponentCanvasManifestation;
        ownerComponentCanvasManifestation = viewManifestation;
        setupSelectionPropertyChangeListener(oldManifestation);
       
        controlManifestation = ownerComponentCanvasManifestation.getControlManifestation();
       
        // Setup title bar
        titleBar = new CanvasTitleArea(ownerComponentCanvasManifestation.getInfo().getViewName());
   
        // Setup scroll pane.
        JScrollPane scrollPane = new JScrollPane(ownerComponentCanvasManifestation, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);

        // Stop scroll bars responding to arrow keys
        scrollPane.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("LEFT"), "doNothing");
        scrollPane.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("RIGHT"), "doNothing");
        scrollPane.getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke("LEFT"), "doNothing");
        scrollPane.getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
                .put(KeyStroke.getKeyStroke("RIGHT"), "doNothing");

        // Attach control manifestation.
        if (controlManifestation != null) {
            controlManifestation.setAlignmentX(Component.LEFT_ALIGNMENT);
            // use a split pane to separate control manifestation from canvas manifestation.
            splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, controlManifestation, scrollPane);         
            splitPane.setOneTouchExpandable(true);
            splitPane.setContinuousLayout(true);
            splitPane.setBorder(null);
            dividerSize = splitPane.getDividerSize();
            showControl(false);   // default is that formatting control is not visible.
            showCanvasTitle(canvasTitleBarShowing);
            add(splitPane);
            instrumentNames(splitPane);
        } else {
            // Just add the canvas as we there is no control manifestation.
            splitPane = null;
            showCanvasTitle(canvasTitleBarShowing);
            add(scrollPane);
        }
      
        this.refreshButton.setContext(context);
       
        revalidate()
    }

    private void instrumentNames(JSplitPane pane) {
        pane.setName("contentAreaSplitPane");
    }

    @Override
    public void addSelectionChangeListener(PropertyChangeListener listener) {
        addPropertyChangeListener(SelectionProvider.SELECTION_CHANGED_PROP, listener);
    }

    @Override
    public void removeSelectionChangeListener(PropertyChangeListener listener) {
        removePropertyChangeListener(SelectionProvider.SELECTION_CHANGED_PROP, listener);
    }
   
    @Override
    public void clearCurrentSelections() {
        ownerComponentCanvasManifestation.getSelectionProvider().clearCurrentSelections();
    }

    public AbstractComponent getOwnerComponent() {
        return this.ownerComponent;
    }

    @Override
    public View getHousedViewManifestation() {
        return this.ownerComponentCanvasManifestation;
    }
   
    @Override
    public Collection<ViewProvider> getHousedManifestationProviders() {
        return this.housedManifestations.values();
    }
   
    /**
     * Determines whether the content area is empty or not. The initial algorithm will look
     * at the current manifestation and determine whether the swing hierarchy contains any other
     * MCTViewManifestations. This is not optimal as this relies on the current structure of
     * a canvas view. In the future this method may change to invoke a more specific method on the
     * view manifestation.
     * @return true if the the content area is empty, false otherwise.
     */
    public boolean isAreaEmpty() {
        View manifestation = getHousedViewManifestation();
        return manifestation == null ||
               !containsMCTViewManifestation(manifestation);
    }
   
    public boolean expandFullContentArea() {
        return getHousedViewManifestation().getInfo().shouldExpandCenterPaneInWindow() || !isAreaEmpty();
       
    }

    private boolean containsMCTViewManifestation(Container parent) {
        for (Component c:parent.getComponents()) {
            if (c instanceof View) {
                return true;
            }
            if (c instanceof Container &&
                containsMCTViewManifestation(Container.class.cast(c))) {
                return true;
            }
        }
        return false;
    }
   
    void clearHousedManifestations() {
        housedManifestations.clear();
    }
   
    private class CanvasTitleArea extends JPanel {
        private final Color BACKGROUND_COLOR = LafColor.WINDOW_BORDER.darker();
        private final Color FOREGROUND_COLOR = LafColor.WINDOW.brighter();
        private static final int HORIZONTAL_SPACING = 5;
        private final JLabel title;

        private JToggleButton controlToggle = new SettingsButton();
   
        /**
         * Inform the title area that it has been hidden and that it
         * should update its visual state appropriately.
         */
        public void setTitleAreaVisible(boolean state){
            if (controlToggle!=null) {
                if (controlToggle.isSelected() != state) {
                    controlToggle.doClick();
                }
            }
        }
       
        public CanvasTitleArea (String text) {
            setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
            setBackground(BACKGROUND_COLOR);

            controlToggle.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    showControl(controlToggle.isSelected());
                }               
            });
           
            title = new JLabel(text);
            title.setForeground(FOREGROUND_COLOR);
            add(Box.createHorizontalStrut(HORIZONTAL_SPACING));
            add(title);
            add(Box.createHorizontalStrut(HORIZONTAL_SPACING));

            // Only enable control toggle if control manifestation not null.
            controlToggle.setEnabled(controlManifestation != null);
            add(Box.createHorizontalGlue());
            add(refreshButton);
            add(controlToggle);
           
            // Add popup listener to title bar.     
            MouseListener popupListener = new PopupListener();
            this.addMouseListener(popupListener);

            instrumentNamesInCanvasTitle(title);
        }

        private void instrumentNamesInCanvasTitle(JLabel title) {
            this.setName("canvasTitleArea");
            title.setName("title");
            controlToggle.setName("settingsToggle");
        }
    }

    class PopupListener extends MouseAdapter {
        // Variables used by unit test.
        boolean testMode = false;
        boolean popupActivated = false;

        @Override
        public void mousePressed(MouseEvent e) {
            processPopUpListenerEvent(e, true);
        }

        /**
         * Respond to mouse event in the canvas area by either showing a popup menu if appropriate
         * or noting that items are no longer selected.
         * @param e the event.
         * @param mousePressed state of the mouse button.
         */
        private void processPopUpListenerEvent(MouseEvent e, boolean mousePressed) {
            if (e.isPopupTrigger()) {
                ActionContextImpl context = new ActionContextImpl();
                context.setTargetComponent(ownerComponentCanvasManifestation.getManifestedComponent());
                context.setTargetHousing((MCTHousing) SwingUtilities.getAncestorOfClass(MCTAbstractHousing.class,
                        ownerComponentCanvasManifestation));
                JPopupMenu popup = MenuFactory.createViewPopupMenu(context);
                assert popup != null;
                if (!testMode) {
                    popup.show(e.getComponent(), e.getX(), e.getY());
                } else {
                    popupActivated = true;
                }
            }
        }
       
        // Test methods only to be utilized by unit tests.
        void setTestMode() {
            testMode = true;
            popupActivated = false;
        }

        boolean popupActivated() {
            return popupActivated;
       
    }

    @Override
    public boolean setHousedViewManifestation(ViewInfo viewInfo) {
        View newView = viewInfo.createView(ownerComponent);
        setOwnerComponentCanvasManifestation(newView);
        return true;
    }

    // Used to provide a context for buttons
    private ActionContext context = new ActionContextImpl() {
        @Override
        public View getWindowManifestation() {
            return parentHousing.getHousedViewManifestation();
        }           
    };
   

}
TOP

Related Classes of gov.nasa.arc.mct.gui.housing.MCTContentArea$PopupListener

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.