org.squidy.designer.zoom.ContainerShape.java Source code

Java tutorial

Introduction

Here is the source code for org.squidy.designer.zoom.ContainerShape.java

Source

/**
 * Squidy Interaction 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 3 of the License,
 * or (at your option) any later version.
 * 
 * Squidy Interaction 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 Squidy Interaction Library. If not, see
 * <http://www.gnu.org/licenses/>.
 * 
 * 2009 Human-Computer Interaction Group, University of Konstanz.
 * <http://hci.uni-konstanz.de>
 * 
 * Please contact info@squidy-lib.de or visit our website
 * <http://www.squidy-lib.de> for further information.
 */

package org.squidy.designer.zoom;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Stroke;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAttribute;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.mvel2.MVEL;
import org.squidy.Storable;
import org.squidy.database.RemoteUpdatable;
import org.squidy.database.RemoteUpdatablePool;
import org.squidy.database.RemoteUpdateUtil;
import org.squidy.designer.Designer;
import org.squidy.designer.component.button.ImageButton;
import org.squidy.designer.event.ZoomActionEvent;
import org.squidy.designer.event.ZoomActionListener;
import org.squidy.designer.model.PipeShape;
import org.squidy.designer.model.WorkspaceShape;
import org.squidy.designer.shape.VisualShape;
import org.squidy.designer.shape.ZoomShape;
import org.squidy.designer.util.ShapeUtils;
import org.squidy.manager.Manager;
import org.squidy.manager.model.Processable;
import org.squidy.manager.model.Processable.Action;

import edu.umd.cs.piccolo.util.PBounds;
import edu.umd.cs.piccolo.util.PPaintContext;

/**
 * <code>ContainerShape</code>.
 * 
 * <pre>
 * Date: Jul 14, 2009
 * Time: 12:59:46 PM
 * </pre>
 * 
 * 
 * @author
 * Roman Rdle
 * <a href="mailto:Roman.Raedle@uni-konstanz.de">Roman.Raedle@uni-konstanz.de</a>
 * Human-Computer Interaction Group
 * University of Konstanz
 * 
 * @version $Id: ContainerShape.java 772 2011-09-16 15:39:44Z raedle $
 * @since 1.0.0
 */
public abstract class ContainerShape<T extends VisualShape<?>, P extends Processable> extends ActionShape<T, P>
        implements RemoteUpdatable {

    /**
     * Generated serial version UID.
     */
    private static final long serialVersionUID = -7529185270166511409L;

    // Logger to log info, error, debug,... messages.
    private static final Log LOG = LogFactory.getLog(ContainerShape.class);

    // #############################################################################
    // BEGIN JAXB
    // #############################################################################

    /**
     * Default constructor required for JAXB.
     */
    public ContainerShape() {
        // empty
    }

    @Override
    public void setId(String id) {
        super.setId(id);

        RemoteUpdatablePool.putRemoteUpdatable(this);
    }

    @XmlAttribute(name = "child-scale")
    private double childScale = 1.0;

    /**
     * @return the childScale
     */
    public double getChildScale() {
        return childScale;
    }

    /**
     * @param childScale the childScale to set
     */
    public void setChildScale(double childScale) {
        this.childScale = childScale;
    }

    @XmlAttribute(name = "grid-visible")
    private boolean gridVisible = true;

    /**
     * @return the gridVisible
     */
    public boolean isGridVisible() {
        return gridVisible;
    }

    /**
     * @param gridVisible the gridVisible to set
     */
    public void setGridVisible(boolean gridVisible) {
        this.gridVisible = gridVisible;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.squidy.designer.zoom.ZoomNavigationObject#afterUnmarshal(javax
     * .xml.bind.Unmarshaller, java.lang.Object)
     */
    public void afterUnmarshal(Unmarshaller unmarshaller, Object parent) {
        super.afterUnmarshal(unmarshaller, parent);
    }

    // #############################################################################
    // END JAXB
    // #############################################################################

    // #############################################################################
    // BEGIN RemoteUpdatable
    // #############################################################################

    /* (non-Javadoc)
     * @see org.squidy.database.RemoteUpdatable#serialize()
     */
    //   @Override
    public String serialize() {

        //      "type=" + containerShape.getProcessable().getClass().getName() +
        //      ",processor=" + containerShape.getProcessable().getId() +
        //      ",shape=" + containerShape.getId() +
        //      ",layoutConstraintId=" + containerShape.getLayoutConstraint().getId() +
        //      ",parent=" + ((ContainerShape<?, ?>) containerShape.getParent()).getId() + 

        return RemoteUpdateUtil.createSerial(
                new String[] { "processorType", "processorId", "layoutConstraint", "parentId" },
                new Object[] { getProcessable().getClass().getName(), getProcessable().getId(),
                        getLayoutConstraint().serialize(), ((ContainerShape<?, ?>) getParent()).getId() });
    }

    /* (non-Javadoc)
     * @see org.squidy.database.RemoteUpdatable#deserialize(java.lang.String)
     */
    //   @Override
    public void deserialize(String serial) {
        RemoteUpdateUtil.applySerial(this, serial);
        String[] keyValues = serial.split(String.valueOf(SERIAL_DELIMITER));

        for (String keyValue : keyValues) {
            String[] kv = keyValue.split(String.valueOf(KEY_VALUE_DELIMITER));
            MVEL.setProperty(this, kv[0], kv[1]);
        }

        throw new UnsupportedOperationException("not yet implemented");
    }

    // #############################################################################
    // END RemoteUpdatable
    // #############################################################################

    // #############################################################################
    // BEGIN Initializable
    // #############################################################################

    //   private JComponentWrapper childScaleComponent;

    /* (non-Javadoc)
     * @see org.squidy.designer.zoom.ActionShape#initialize()
     */
    @Override
    public void initialize() {
        super.initialize();

        //      final JSlider childSizeSpinner = new JSlider(1, 100, (int) (getScale() * 100));
        //      childSizeSpinner.setPaintLabels(true);
        //      childSizeSpinner.setPaintTicks(true);
        //      childSizeSpinner.setPaintTrack(true);
        //      childSizeSpinner.setSnapToTicks(true);
        //      childSizeSpinner.setBackground(Color.WHITE);
        //      childScaleComponent = new JComponentWrapper(childSizeSpinner);
        //      addChild(childScaleComponent);
        ////      childScaleComponent.setScale(0.1);
        //      childScaleComponent.setOffset(1050, 15);
        //      childSizeSpinner.addChangeListener(new ChangeListener() {
        //         
        //         /* (non-Javadoc)
        //          * @see javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent)
        //          */
        //         public void stateChanged(ChangeEvent e) {
        //            Object value = childSizeSpinner.getValue();
        //            
        //            for (Object o : getChildrenReference()) {
        //               if (o instanceof ActionShape<?, ?>) {
        //                  ActionShape<?, ?> node = (ActionShape<?, ?>) o;
        //                  node.setScale(((Integer) value).doubleValue() / 100d);
        //               }
        //            }
        //         }
        //      });
    }

    // #############################################################################
    // END Initializable
    // #############################################################################

    /* (non-Javadoc)
     * @see org.squidy.designer.zoom.ActionShape#initializeLayout()
     */
    @Override
    public void initializeLayout() {
        super.initializeLayout();

        final ImageButton startProcessing = new ImageButton(
                ActionShape.class.getResource("/images/24x24/media_play_green.png"), "Start");
        final ImageButton stopProcessing = new ImageButton(
                ActionShape.class.getResource("/images/24x24/media_stop_red.png"), "Stop");
        stopProcessing.setEnabled(false);

        startProcessing.addZoomActionListener(new ZoomActionListener() {

            /**
             * @param e
             */
            public void actionPerformed(ZoomActionEvent e) {

                new Thread() {

                    /*
                     * (non-Javadoc)
                     * 
                     * @see java.lang.Thread#run()
                     */
                    @Override
                    public void run() {
                        if (!getProcessable().isProcessing()) {
                            startProcessing.setEnabled(false);
                            stopProcessing.setEnabled(true);
                            invalidatePaint();
                            ContainerShape.this.start();
                            ContainerShape.this.doStart();

                            Manager.get().notify(getProcessable(), Action.START);
                        }
                    }
                }.start();
            }
        });

        stopProcessing.addZoomActionListener(new ZoomActionListener() {

            /**
             * @param e
             */
            public void actionPerformed(ZoomActionEvent e) {
                new Thread() {

                    /*
                     * (non-Javadoc)
                     * 
                     * @see java.lang.Thread#run()
                     */
                    @Override
                    public void run() {
                        // if (getProcessable().isProcessing()) {
                        startProcessing.setEnabled(true);
                        stopProcessing.setEnabled(false);
                        invalidatePaint();
                        ContainerShape.this.stop();
                        ContainerShape.this.doStop();
                        // }

                        Manager.get().notify(getProcessable(), Action.STOP);
                    }
                }.start();
            }
        });

        ImageButton delete = new ImageButton(ActionShape.class.getResource("/images/24x24/delete2.png"), "Delete");
        delete.addZoomActionListener(new ZoomActionListener() {

            /*
             * (non-Javadoc)
             * 
             * @see
             * org.squidy.designer.event.ZoomActionListener#actionPerformed
             * (org.squidy.designer.event.ZoomActionEvent)
             */
            public void actionPerformed(ZoomActionEvent e) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Pressed delete on " + getBreadcrumb());
                }

                int option = JOptionPane.showConfirmDialog(Designer.getInstance(),
                        "Would you like to delete " + getTitle() + "?", "Delete?", JOptionPane.OK_CANCEL_OPTION,
                        JOptionPane.QUESTION_MESSAGE,
                        new ImageIcon(ActionShape.class.getResource("/images/delete.png")));

                if (option == JOptionPane.OK_OPTION) {
                    ZoomShape<?> zoomShape = null;
                    if (currentZoomState == ZoomState.ZOOM_IN && getParent() instanceof ZoomShape<?>) {
                        zoomShape = (ZoomShape<?>) getParent();
                    }
                    delete();
                    if (zoomShape != null) {
                        zoomShape.animateToCenterView(e.getCamera());

                        // Set pipe shapes visible and pickable.
                        for (Object child : zoomShape.getChildrenReference()) {
                            if (child instanceof PipeShape) {
                                ShapeUtils.setApparent((PipeShape) child, true);
                            }
                        }
                    }

                    Manager.get().notify(getProcessable(), Action.DELETE);
                }
            }
        });

        ImageButton duplicate = new ImageButton(ActionShape.class.getResource("/images/24x24/copy.png"),
                "Duplicate");
        duplicate.addZoomActionListener(new ZoomActionListener() {

            /*
             * (non-Javadoc)
             * 
             * @see
             * org.squidy.designer.event.ZoomActionListener#actionPerformed
             * (org.squidy.designer.event.ZoomActionEvent)
             */
            public void actionPerformed(ZoomActionEvent e) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Duplicate has been pressed for " + getBreadcrumb());
                }

                Manager.get().notify(getProcessable(), Action.DUPLICATE);
            }
        });
        duplicate.setEnabled(false);

        ImageButton publish = new ImageButton(ActionShape.class.getResource("/images/24x24/export2.png"),
                "Publish");
        publish.addZoomActionListener(new ZoomActionListener() {

            /*
             * (non-Javadoc)
             * 
             * @see
             * org.squidy.designer.event.ZoomActionListener#actionPerformed
             * (org.squidy.designer.event.ZoomActionEvent)
             */
            public void actionPerformed(ZoomActionEvent e) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Publish has been pressed for " + getBreadcrumb());
                }

                Storable storable = ShapeUtils.getObjectInHierarchy(Storable.class, ContainerShape.this);
                if (storable != null) {
                    storable.store();
                }
            }
        });
        publish.setEnabled(false);

        ImageButton update = new ImageButton(ActionShape.class.getResource("/images/24x24/import1.png"), "Update");
        update.addZoomActionListener(new ZoomActionListener() {

            /*
             * (non-Javadoc)
             * 
             * @see
             * org.squidy.designer.event.ZoomActionListener#actionPerformed
             * (org.squidy.designer.event.ZoomActionEvent)
             */
            public void actionPerformed(ZoomActionEvent e) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Update has been pressed for " + getBreadcrumb());
                }
            }
        });
        update.setEnabled(false);

        addPropertyChangeListener(Processable.PROPERTY_PROCESSING, new PropertyChangeListener() {

            /*
            * (non-Javadoc)
            * 
            * 
            * 
            * @seejava.beans.PropertyChangeListener#propertyChange(java.
            * beans. PropertyChangeEvent)
            */
            public void propertyChange(PropertyChangeEvent evt) {
                startProcessing.setEnabled(!(Boolean) evt.getNewValue());
                stopProcessing.setEnabled((Boolean) evt.getNewValue());

                if ((Boolean) evt.getNewValue())
                    doStart();
                else
                    doStop();
            }
        });

        //      addPropertyChangeListener(Processable.PROPERTY_PROCESSING_STOP,
        //            new PropertyChangeListener() {
        //
        //               /*
        //                * (non-Javadoc)
        //                * 
        //                * 
        //                * 
        //                * @seejava.beans.PropertyChangeListener#propertyChange(java.
        //                * beans. PropertyChangeEvent)
        //                */
        //               public void propertyChange(PropertyChangeEvent evt) {
        //                  // startProcessing.setToggleState(ZoomToggle.RELEASED);
        //                  // stopProcessing.setToggleState(ZoomToggle.PRESSED);
        //                  startProcessing.setEnabled(true);
        //                  stopProcessing.setEnabled(false);
        //                  doStop();
        //               }
        //            });

        ShapeUtils.setApparent(startProcessing, false);
        ShapeUtils.setApparent(stopProcessing, false);
        if (!(this instanceof WorkspaceShape)) {
            ShapeUtils.setApparent(delete, false);
            ShapeUtils.setApparent(duplicate, false);
            ShapeUtils.setApparent(publish, false);
            ShapeUtils.setApparent(update, false);
        }

        addAction(startProcessing);
        addAction(stopProcessing);
        if (!(this instanceof WorkspaceShape)) {
            addAction(delete);
            addAction(duplicate);
            addAction(publish);
            addAction(update);
        }
    }

    /* (non-Javadoc)
     * @see edu.umd.cs.piccolo.PNode#setScale(double)
     */
    @Override
    public void setScale(double scale) {
        super.setScale(scale);

        //      if (childScaleComponent != null) {
        //         JSlider scaleSlider = (JSlider) childScaleComponent.getComponent();
        //         scaleSlider.setValue((int) (scale * 100));
        //      }
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.squidy.designer.VisualShape#addVisualShape(org.squidy
     * .designer.VisualShape)
     */
    public void addVisualShape(T child) {
        super.addVisualShape(child);
    }

    /* (non-Javadoc)
     * @see org.squidy.designer.zoom.ActionShape#layoutSemanticsZoomedIn()
     */
    @Override
    protected void layoutSemanticsZoomedIn() {
        super.layoutSemanticsZoomedIn();

        //      ShapeUtils.setApparent(childScaleComponent, true);
    }

    /* (non-Javadoc)
     * @see org.squidy.designer.zoom.ActionShape#layoutSemanticsZoomedOut()
     */
    @Override
    protected void layoutSemanticsZoomedOut() {
        super.layoutSemanticsZoomedOut();

        //      ShapeUtils.setApparent(childScaleComponent, false);
    }

    private static Color ALPHA_GRAY_COLOR = new Color(120, 120, 120, 30);
    private static Stroke GRID_STROKE_THIN = new BasicStroke(1f);
    private static Stroke GRID_STROKE_THICK = new BasicStroke(2f);

    private static int GRIDS = 40;
    private static int GRID_SPACING = 5;

    /* (non-Javadoc)
     * @see org.squidy.designer.zoom.NavigationShape#paintShapeZoomedIn(edu.umd.cs.piccolo.util.PPaintContext)
     */
    @Override
    protected void paintShapeZoomedIn(PPaintContext paintContext) {
        super.paintShapeZoomedIn(paintContext);

        if (gridVisible) {
            Graphics2D g = paintContext.getGraphics();
            PBounds bounds = getBoundsReference();
            double width = bounds.getWidth();
            double height = bounds.getHeight();

            g.setColor(ALPHA_GRAY_COLOR);
            double widthStep = width / (double) GRIDS;
            for (int i = 1; i <= GRIDS; i++) {
                g.setStroke((i % GRID_SPACING == 0) ? GRID_STROKE_THICK : GRID_STROKE_THIN);
                g.drawLine((int) widthStep * i, 0, (int) widthStep * i, (int) height);
            }
            double heightStep = height / (double) GRIDS;
            for (int i = 1; i < GRIDS - 1; i++) {
                g.setStroke((i % GRID_SPACING == 0) ? GRID_STROKE_THICK : GRID_STROKE_THIN);
                g.drawLine(0, (int) heightStep * i, (int) width, (int) heightStep * i);
            }
        }
    }
}