
it.tidalwave.netbeans.visual.NodeScene Maven / Gradle / Ivy
The newest version!
/***********************************************************************************************************************
*
* OpenBlueSky - NetBeans Platform Enhancements
* Copyright (C) 2006-2012 by Tidalwave s.a.s. (http://www.tidalwave.it)
*
***********************************************************************************************************************
*
* 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.
*
***********************************************************************************************************************
*
* WWW: http://openbluesky.java.net
* SCM: https://bitbucket.org/tidalwave/openbluesky-src
*
**********************************************************************************************************************/
package it.tidalwave.netbeans.visual;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.annotation.concurrent.Immutable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.List;
import java.io.Serializable;
import java.awt.Point;
import java.awt.Rectangle;
import org.openide.util.Parameters;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
import org.openide.explorer.ExplorerManager;
import org.netbeans.api.visual.anchor.AnchorFactory;
import org.netbeans.api.visual.action.ActionFactory;
import org.netbeans.api.visual.action.MoveProvider;
import org.netbeans.api.visual.action.WidgetAction;
import org.netbeans.api.visual.action.WidgetAction.Chain;
import org.netbeans.api.visual.graph.GraphScene;
import org.netbeans.api.visual.widget.ConnectionWidget;
import org.netbeans.api.visual.widget.LayerWidget;
import org.netbeans.api.visual.widget.Scene;
import org.netbeans.api.visual.widget.Widget;
import static org.netbeans.api.visual.model.ObjectSceneEventType.*;
import it.tidalwave.util.logging.Logger;
import it.tidalwave.netbeans.visual.action.DefaultMoveStrategy;
import it.tidalwave.netbeans.visual.impl.ConnectionWidgetAnchorFixer;
import it.tidalwave.netbeans.visual.impl.PopupMenuBridge;
import it.tidalwave.netbeans.visual.impl.SelectionHandler;
import it.tidalwave.netbeans.visual.impl.WidgetMoveProviderAdapter;
/***********************************************************************************************************************
*
* @author Fabrizio Giudici
* @version $Id$
*
**********************************************************************************************************************/
public class NodeScene extends GraphScene implements ExplorerManager.Provider
{
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
@Immutable
public static class DragEvent implements Serializable
{
@Nonnull
private final Node node;
private final Widget widget;
private final Point location;
public DragEvent (final @Nonnull Node node,
final @Nonnull Widget widget,
final @Nonnull Point location)
{
this.node = node;
this.widget = widget;
this.location = location;
}
@Nonnull
public Point getLocation()
{
return location;
}
@Nonnull
public Node getNode()
{
return node;
}
@Nonnull
public Widget getWidget()
{
return widget;
}
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
public static interface DragBehaviour extends Serializable
{
public enum Confirmation
{
CONFIRMED, CANCELLED
}
/***************************************************************************************************************
*
* Invoked when a drag operation is started on a {@link Node}.
*
* @param node the node
*
**************************************************************************************************************/
public void nodeDragStarted (@Nonnull DragEvent dragEvent);
/***************************************************************************************************************
*
* Invoked during a drag operation on a {@link Node}.
*
* @param node the node
* @param location the new location where the node is dragged
*
**************************************************************************************************************/
public void nodeDragged (@Nonnull DragEvent dragEvent);
/***************************************************************************************************************
*
* Invoked when a drag operation is terminated on a {@link Node}.
*
* @param node the node
*
**************************************************************************************************************/
public void nodeDragFinished (@Nonnull DragEvent dragEvent, @Nonnull Confirmation confirmation);
/***************************************************************************************************************
*
* @param node the node
*
**************************************************************************************************************/
@Nonnull
public Confirmation confirmDrag (@Nonnull DragEvent dragEvent);
}
private final static String CLASS = NodeScene.class.getName();
private final static Logger logger = Logger.getLogger(CLASS);
private final LayerWidget mainLayer = new LayerWidget(this);
private final LayerWidget connectionLayer = new LayerWidget(this);
private final IdentityHashMap initialLocationMapByNode = new IdentityHashMap();
private final Scene.SceneListener connectionWidgetAnchorFixer = new ConnectionWidgetAnchorFixer(mainLayer);
private final Node rootNode = new AbstractNode(new Children.Array());
private final WidgetAction selectAction = createSelectAction();
private final DefaultMoveStrategy defaultMoveStrategy = new DefaultMoveStrategy();
private final ExplorerManager explorerManager = new ExplorerManager();
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
public NodeScene()
{
addChild(mainLayer);
addChild(connectionLayer);
setOpaque(false); // or the background won't be visible
getActions().addAction(ActionFactory.createZoomAction());
// Let Widgets slip into negative values withouht expanding the Scene
setMaximumBounds(new Rectangle(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE));
addSceneListener(connectionWidgetAnchorFixer);
addObjectSceneListener(new SelectionHandler(explorerManager), OBJECT_SELECTION_CHANGED, OBJECT_STATE_CHANGED);
explorerManager.setRootContext(rootNode);
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
@Override @Nonnull
public ExplorerManager getExplorerManager()
{
return explorerManager;
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
@Nonnull
public Node getRootNode()
{
return rootNode;
}
/*******************************************************************************************************************
*
* Adds a {@code Node}, placing the related {@link Widget} at the given initial location.
*
* @param node the {@code Node}
* @param initialLocation the initial location
*
******************************************************************************************************************/
public void addNode (@Nonnull Node node, final @Nonnull Point initialLocation)
{
initialLocationMapByNode.put(node, initialLocation);
addNode(node);
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
public void removeAllNodes()
{
logger.fine("removeAllNodes()");
connectionLayer.removeChildren();
mainLayer.removeChildren();
for (final Object object : new ArrayList
© 2015 - 2025 Weber Informatics LLC | Privacy Policy