Пример #1
0
  public ActionsWithRoutingPolicyTest() {
    mainLayer = new LayerWidget(this);
    addChild(mainLayer);
    LayerWidget connLayer = new LayerWidget(this);
    addChild(connLayer);

    Widget source = createLabel("Source", 50, 200, Color.GREEN);
    Widget target = createLabel("Target", 450, 200, Color.GREEN);

    connection = new ConnectionWidget(this);
    connection.setSourceAnchor(
        AnchorFactory.createDirectionalAnchor(
            source, AnchorFactory.DirectionalAnchorKind.HORIZONTAL));
    connection.setTargetAnchor(
        AnchorFactory.createDirectionalAnchor(
            target, AnchorFactory.DirectionalAnchorKind.HORIZONTAL));
    connection.setTargetAnchorShape(AnchorShape.TRIANGLE_FILLED);
    connection.setPaintControlPoints(true);
    connection.setControlPointShape(PointShape.SQUARE_FILLED_BIG);
    connection.setRouter(RouterFactory.createOrthogonalSearchRouter(mainLayer));
    connection
        .getActions()
        .addAction(
            ActionFactory.createAddRemoveControlPointAction(
                1.0, 5.0, ConnectionWidget.RoutingPolicy.UPDATE_END_POINTS_ONLY));
    connection
        .getActions()
        .addAction(
            ActionFactory.createMoveControlPointAction(
                ActionFactory.createFreeMoveControlPointProvider(),
                ConnectionWidget.RoutingPolicy.UPDATE_END_POINTS_ONLY));
    connLayer.addChild(connection);
  }
Пример #2
0
  public static void main(String[] args) {
    final Scene scene = new Scene();

    LayerWidget layer = new LayerWidget(scene);
    scene.addChild(layer);

    Widget nodeWidget = new Widget(scene);
    nodeWidget.setBorder(BorderFactory.createLineBorder(1, Color.RED));
    nodeWidget.setPreferredLocation(new Point(100, 100));
    layer.addChild(nodeWidget);

    final Widget deferredWidget = new Widget(scene);
    deferredWidget.setLayout(LayoutFactory.createCardLayout(deferredWidget));
    deferredWidget.setBorder(BorderFactory.createLineBorder(1, Color.BLUE));
    nodeWidget.addChild(deferredWidget);

    final Widget label = new LabelWidget(scene, "Click me to add ComponentWidget");
    label.setBorder(BorderFactory.createLineBorder(1, Color.GREEN));
    deferredWidget.addChild(label);
    LayoutFactory.setActiveCard(deferredWidget, label);

    label
        .getActions()
        .addAction(
            ActionFactory.createEditAction(
                new EditProvider() {
                  public void edit(Widget widget) {
                    ComponentWidget component =
                        new ComponentWidget(scene, new JButton("This is the new ComponentWidget"));
                    component.setBorder(BorderFactory.createLineBorder(1, Color.GREEN));
                    deferredWidget.addChild(component);
                    LayoutFactory.setActiveCard(deferredWidget, component);
                  }
                }));

    scene
        .getActions()
        .addAction(
            ActionFactory.createEditAction(
                new EditProvider() {
                  public void edit(Widget widget) {
                    LayoutFactory.setActiveCard(deferredWidget, label);
                  }
                }));

    // to force the boundary
    //        nodeWidget.setPreferredBounds (new Rectangle (0, 0, 70, 30));
    //        nodeWidget.setPreferredSize (new Dimension (70, 30));
    nodeWidget.setLayout(LayoutFactory.createOverlayLayout());
    nodeWidget.setCheckClipping(true);
    //

    SceneSupport.show(scene);
  }
Пример #3
0
  public RuleScene(TwoStateHoverProvider hoverProvider, EditProvider edgeEditProvider) {
    addChild(nodes);
    addChild(connections);
    addChild(interactionLayer);

    this.hoverProvider = hoverProvider;
    hoverAction = ActionFactory.createHoverAction(new Highlighter(hoverProvider));
    editAction = ActionFactory.createEditAction(edgeEditProvider);

    getActions().addAction(hoverAction);
    getActions().addAction(ActionFactory.createPopupMenuAction(new ScenePopupProvider(this)));
    getActions().addAction(ActionFactory.createWheelPanAction());
  }
Пример #4
0
 private Widget createLabel(String text, int x, int y, Color color) {
   LabelWidget label = new LabelWidget(this, text);
   label.setOpaque(true);
   label.setBackground(color);
   label.setBorder(BorderFactory.createLineBorder(5));
   label.setPreferredLocation(new Point(x, y));
   label.getActions().addAction(ActionFactory.createMoveAction());
   mainLayer.addChild(label);
   return label;
 }
  public VisualScene() {
    addChild(backgroundLayer);
    addChild(mainLayer);
    addChild(connectionLayer);
    addChild(interactionLayer);
    addChild(forgroundLayer);

    // set the initial tool
    this.setActiveTool(EDIT);

    getActions().addAction(ActionFactory.createZoomAction());
    getActions().addAction(ActionFactory.createPanAction());
    getActions()
        .addAction(
            hoverAction); // this hover action is needed for port highlights to turn them off(the
    // scene takes over the mosue)
    getActions().addAction(new SceneMouseAction());
    getActions().addAction(ActionFactory.createRectangularSelectAction(this, backgroundLayer));

    getPriorActions().addAction(new KeyEventAction()); // add the scene key event listener
  }
 public void createIntermediateZonePopUp() {
   this.glassPane
       .getScene()
       .getActions()
       .addAction(ActionFactory.createPopupMenuAction(new MyPopupProviderIntermedieZone(this)));
   creaPopUpMappingTaskTreeSource();
   creaPopUpMappingTaskTreeSourceDuplicate();
   creaPopUpMappingTaskTreeSourceDeleteDuplicate();
   creaPopUpMappingTaskTreeTarget();
   creaPopUpMappingTaskTreeTargetDuplicate();
   creaPopUpMappingTaskTreeTargetDeleteDuplicate();
 }
  @Override
  protected Widget attachEdgeWidget(Object e) {
    // create the visual connection
    CustomConnectionWidget connection = (CustomConnectionWidget) e;
    connection.setPaintControlPoints(true);
    connection.setRouter(CustomRouterFactory.createFreeRouter());
    connection.setControlPointShape(FlowControlPointShape.CIRCLE_FILLED_SMALL);

    // Normal Edit Mode actions
    connection
        .createActions(EDGE_CONTROL_MODE)
        .addAction(0, ActionFactory.createAddRemoveControlPointAction());
    connection
        .createActions(EDGE_CONTROL_MODE)
        .addAction(1, ActionFactory.createFreeMoveControlPointAction());
    connection
        .createActions(EDGE_CONTROL_MODE)
        .addAction(2, ActionFactory.createAddRemoveControlPointAction());
    connection
        .createActions(EDGE_CONTROL_MODE)
        .addAction(3, ActionFactory.createFreeMoveControlPointAction());
    connection.createActions(EDGE_CONTROL_MODE).addAction(4, createObjectHoverAction());

    connectionLayer.addChild(connection);

    // create the data connection
    //        Port srcPort = (Port)
    // connection.getSourceAnchor().getRelatedWidget().getParentWidget();
    //        VisualNode src = srcPort.getParentNode();
    //
    //        Port tgtPort = (Port)
    // connection.getTargetAnchor().getRelatedWidget().getParentWidget();
    //        VisualNode tgt = tgtPort.getParentNode();

    //        dataScene.connect(src.getDataNode(), srcPort.getID(), tgt.getDataNode(),
    // tgtPort.getID());

    return connection;
  }
  public void createConnection(Widget sourceWidget, Widget targetWidget) {
    try {
      ConnectionWidget connection = new ConnectionWidget(sourceWidget.getScene());
      connection.setTargetAnchorShape(AnchorShape.TRIANGLE_FILLED);
      connection.setSourceAnchor(AnchorFactory.createRectangularAnchor(sourceWidget));
      connection.setTargetAnchor(AnchorFactory.createRectangularAnchor(targetWidget));
      Stroke stroke = Costanti.BASIC_STROKE;
      connection.setStroke(stroke);
      connection
          .getActions()
          .addAction(
              ActionFactory.createPopupMenuAction(
                  new MyPopupProviderConnectionFunc(
                      sourceWidget.getScene(), mainLayer, caratteristiche)));
      ConnectionInfo connectionInfo = new ConnectionInfo();
      connectionInfo.setTargetWidget(targetWidget);
      connectionInfo.setConnectionWidget(connection);
      caratteristiche.setTargetWidget((VMDPinWidgetTarget) targetWidget);

      creator.createCorrespondenceWithFunction(
          mainLayer, targetWidget, caratteristiche, connectionInfo);

      caratteristiche.setConnectionInfo(connectionInfo);
      connectionLayer.addChild(connection, connectionInfo);
    } catch (ExpressionSyntaxException e) {
      DialogDisplayer.getDefault()
          .notify(
              new NotifyDescriptor.Message(
                  NbBundle.getMessage(Costanti.class, Costanti.SYNTAX_WARNING)
                      + " : "
                      + e.getMessage(),
                  DialogDescriptor.WARNING_MESSAGE));
      // giannisk delete target connection if exception if caught
      deleteTargetConnection(sourceWidget);
    }
  }
Пример #9
0
  public GraphSceneImpl() {
    mainLayer = new LayerWidget(this);
    connectionLayer = new LayerWidget(this);
    interactionLayer = new LayerWidget(this);
    addChild(mainLayer);
    addChild(connectionLayer);
    addChild(interactionLayer);

    getActions().addAction(ActionFactory.createZoomAction());
    getActions().addAction(ActionFactory.createWheelPanAction());

    //
    // the Childfactory creates Nodes for selected Objects
    final FakeChildFactory childFactory = new FakeChildFactory();

    // A Root Context Node for the ExplorerManager
    root = new AbstractNode(Children.create(childFactory, false));

    // ExplorerManager will create the Proxy Lookups for multiple selected Nodes
    em = new ExplorerManager();
    em.setRootContext(root);

    final ObjectSelectProvider selectProvider = new ObjectSelectProvider(this);
    final WidgetAction selectAction = ActionFactory.createSelectAction(selectProvider);

    // add drag & drop
    getActions()
        .addAction(
            ActionFactory.createAcceptAction(
                new AcceptProvider() {
                  @Override
                  public ConnectorState isAcceptable(
                      Widget widget, Point point, Transferable transferable) {
                    Image dragImage = getImageFromTransferable(transferable);
                    JComponent view = getView();
                    Graphics2D g2 = (Graphics2D) view.getGraphics();
                    Rectangle visRect = view.getVisibleRect();
                    view.paintImmediately(visRect.x, visRect.y, visRect.width, visRect.height);
                    g2.drawImage(
                        dragImage,
                        AffineTransform.getTranslateInstance(
                            point.getLocation().getX(), point.getLocation().getY()),
                        null);
                    return ConnectorState.ACCEPT;
                  }

                  @Override
                  public void accept(Widget widget, Point point, Transferable transferable) {
                    Image image = getImageFromTransferable(transferable);
                    //                Widget w = addNode("1node x - " + nodeCount++); // adding
                    // nodes dynamically
                    //                System.out.println(image.getHeight(null));
                    int imageReceivedHeight = image.getHeight(null);

                    Widget w = null;
                    ConfigNode cn = null;

                    if (imageReceivedHeight < DIMENTION_ICON_LIMIT) {

                      String key = "L2F" + String.valueOf(dimentionCount++);
                      cn = new ConfigNode(image, key);
                      nodeMap.put(key, cn);
                      w = GraphSceneImpl.this.addNode(cn);
                    } else if (imageReceivedHeight < FEATURE_ICON_LIMIT) {

                      String key = "L1F" + String.valueOf(featureCount++);
                      cn = new ConfigNode(image, key);
                      nodeMap.put(key, cn);
                      w = GraphSceneImpl.this.addNode(cn);
                    } else {

                      String key = "L0F" + String.valueOf(perceptionCount++);
                      cn = new PerceptionConfigNode(image, key);
                      nodeMap.put(key, cn);
                      w = GraphSceneImpl.this.addNode(cn);
                    }

                    //                Widget w = GraphSceneImpl.this.addNode(new ConfigNode(image,
                    // "2"));//

                    w.getActions().addAction(selectAction);

                    w.setPreferredLocation(widget.convertLocalToScene(point));
                  }
                }));

    // Object listener
    addObjectSceneListener(
        new ObjectSceneListener() {
          @Override
          public void objectAdded(ObjectSceneEvent ose, Object o) {
            //                throw new UnsupportedOperationException("Not supported yet.");
          }

          @Override
          public void objectRemoved(ObjectSceneEvent ose, Object o) {
            //                throw new UnsupportedOperationException("Not supported yet.");
          }

          @Override
          public void objectStateChanged(
              ObjectSceneEvent ose, Object o, ObjectState os, ObjectState os1) {
            //                throw new UnsupportedOperationException("Not supported yet.");
          }

          @Override
          public void selectionChanged(
              ObjectSceneEvent event, Set<Object> previousSelection, Set<Object> newSelection) {
            //                throw new UnsupportedOperationException("Not supported yet.");
            childFactory.setKeys(newSelection);
            try {
              em.setSelectedNodes(root.getChildren().getNodes());
            } catch (PropertyVetoException ex) {
              Exceptions.printStackTrace(ex);
            }
          }

          @Override
          public void highlightingChanged(ObjectSceneEvent ose, Set<Object> set, Set<Object> set1) {
            //                throw new UnsupportedOperationException("Not supported yet.");
          }

          @Override
          public void hoverChanged(ObjectSceneEvent ose, Object o, Object o1) {
            //                throw new UnsupportedOperationException("Not supported yet.");
          }

          @Override
          public void focusChanged(ObjectSceneEvent ose, Object o, Object o1) {
            //                throw new UnsupportedOperationException("Not supported yet.");
          }
        },
        ObjectSceneEventType.OBJECT_SELECTION_CHANGED);
  }
Пример #10
0
  @Override
  protected Widget attachNodeWidget(ConfigNode arg) {
    IconNodeWidget widget = new IconNodeWidget(this);
    if (arg.getId().startsWith("L2F")) {
      widget.setImage(ImageUtilities.loadImage("com/weaved/server/configurator/images/d.png"));
    } else if (arg.getId().startsWith("L1F")) {
      widget.setImage(ImageUtilities.loadImage("com/weaved/server/configurator/images/f.png"));
    } else {
      widget.setImage(ImageUtilities.loadImage("com/weaved/server/configurator/images/p.png"));
    }

    widget
        .getActions()
        .addAction(
            ActionFactory.createExtendedConnectAction(connectionLayer, new MyConnectProvider()));

    widget
        .getActions()
        .addAction(
            ActionFactory.createAlignWithMoveAction(
                mainLayer, interactionLayer, ActionFactory.createDefaultAlignWithMoveDecorator()));

    widget
        .getActions()
        .addAction(
            ActionFactory.createPopupMenuAction(
                new PopupMenuProvider() {
                  @Override
                  public JPopupMenu getPopupMenu(final Widget widget, Point localLocation) {
                    JPopupMenu popup = new JPopupMenu();

                    // Properties
                    JMenuItem propsMenu = new JMenuItem("Properties");
                    propsMenu.addActionListener(
                        new ActionListener() {
                          @Override
                          public void actionPerformed(ActionEvent e) {

                            Object object =
                                findObject(
                                    widget); // consider a map "string" => ShapeObj at creation
                            // (drop)
                            ConfigNode node = (ConfigNode) object;

                            if (node.getId().startsWith("L0")) {
                              PerceptionConfigPropNode propNode =
                                  new PerceptionConfigPropNode((PerceptionConfigNode) node);
                              propNode.setDisplayName("Node Settings");
                              propNode.setShortDescription(
                                  "Click on properties to get a small discription about the property");
                              NodeOperation.getDefault().showProperties(propNode);
                            } else {
                              ConfigPropNode propNode = new ConfigPropNode(node);
                              propNode.setDisplayName("Node Settings");
                              propNode.setShortDescription(
                                  "Click on properties to get a small discription about the property");
                              NodeOperation.getDefault().showProperties(propNode);
                            }
                          }
                        });

                    // Delete
                    JMenuItem deleteMenu = new JMenuItem("Delete");
                    deleteMenu.addActionListener(
                        new ActionListener() {
                          @Override
                          public void actionPerformed(ActionEvent e) {

                            ConfigNode cn = (ConfigNode) findObject(widget);

                            List<Widget> connections = connectionLayer.getChildren();

                            for (Widget connection : connections) {
                              ConnectionWidget conn = (ConnectionWidget) connection;

                              if (conn.getSourceAnchor().getRelatedWidget().equals(widget)) {

                                connectionLayer.removeChild(conn);
                                //                                edgeMap.remove(conn);

                              }

                              if (conn.getTargetAnchor().getRelatedWidget().equals(widget)) {

                                connectionLayer.removeChild(conn);
                                //                                edgeMap.remove(conn);
                              }
                            }

                            GraphSceneImpl.this.removeNode(cn);
                            nodeMap.remove(cn.getId());
                          }
                        });

                    popup.add(propsMenu);
                    popup.add(deleteMenu);

                    return popup;
                  }
                }));

    widget.setLabel(arg.getId());
    mainLayer.addChild(widget);
    return widget;
  }
/** @author Jon Rose */
public class VisualScene extends GraphScene {

  public LayerWidget forgroundLayer = new LayerWidget(this);
  public LayerWidget mainLayer = new LayerWidget(this);
  public LayerWidget connectionLayer = new LayerWidget(this);
  public LayerWidget interactionLayer = new LayerWidget(this);
  public LayerWidget backgroundLayer = new LayerWidget(this);
  public static Port currentPort;
  private ArrayList<Widget> inputs = new ArrayList();
  private ArrayList<Widget> outputs = new ArrayList();
  private WidgetAction multiMove = ActionFactory.createMoveAction(null, new MultiMoveProvider());
  private WidgetAction moveAction =
      ActionFactory.createAlignWithMoveAction(mainLayer, interactionLayer, null, false);
  private WidgetAction resizeAction =
      ActionFactory.createAlignWithResizeAction(mainLayer, interactionLayer, null, false);
  private WidgetAction hoverAction = ActionFactory.createHoverAction(new MyHoverProvider(this));
  private UIMouseAction dragAction = new UIMouseAction();
  private SceneMouseAction sceneAction = new SceneMouseAction();
  public static final String EDIT = "editMode";
  public static final String CONNECTION_EDIT_TOOL = "connectionEditTool";
  public static final String USE = "alignMode";
  public static final String EDGE_CONTROL_MODE = "edgeControlMode";
  public static final String MULTI_MOVE = "multiMove";
  private NodeCreator dataNodeCreator;
  private DataScene dataScene = new DataScene(this);
  private boolean over = false;
  private double mouseX;
  private double mouseY;
  private double lastX;
  private double lastY;
  private double xVelocity;
  private double yVelocity;
  private Point lastPointCreatedAt = new Point(400, 400);
  private boolean mouseDragged = false;
  protected ArrayList<Connection> connections = new ArrayList<Connection>();
  private HashMap customRenderer = new HashMap();
  public Trie trie = new Trie();

  public VisualScene() {
    addChild(backgroundLayer);
    addChild(mainLayer);
    addChild(connectionLayer);
    addChild(interactionLayer);
    addChild(forgroundLayer);

    // set the initial tool
    this.setActiveTool(EDIT);

    getActions().addAction(ActionFactory.createZoomAction());
    getActions().addAction(ActionFactory.createPanAction());
    getActions()
        .addAction(
            hoverAction); // this hover action is needed for port highlights to turn them off(the
    // scene takes over the mosue)
    getActions().addAction(new SceneMouseAction());
    getActions().addAction(ActionFactory.createRectangularSelectAction(this, backgroundLayer));

    getPriorActions().addAction(new KeyEventAction()); // add the scene key event listener
  }

  public Trie getTrie() {
    return trie;
  }

  public boolean isMouseDragged() {
    return mouseDragged;
  }

  public void setMouseDragged(boolean mouseDragged) {
    this.mouseDragged = mouseDragged;
  }

  public double getLastX() {
    return lastX;
  }

  public void setLastX(double lastX) {
    this.lastX = lastX;
  }

  public double getLastY() {
    return lastY;
  }

  public void setLastY(double lastY) {
    this.lastY = lastY;
  }

  public double getMouseX() {
    return mouseX;
  }

  public void setMouseX(double mouseX) {
    this.mouseX = mouseX;
  }

  public double getMouseY() {
    return mouseY;
  }

  public void setMouseY(double mouseY) {
    this.mouseY = mouseY;
  }

  public double getxVelocity() {
    return xVelocity;
  }

  public void setxVelocity(double xVelocity) {
    this.xVelocity = xVelocity;
  }

  public double getyVelocity() {
    return yVelocity;
  }

  public void setyVelocity(double yVelocity) {
    this.yVelocity = yVelocity;
  }

  public Point getLastPointCreatedAt() {
    return lastPointCreatedAt;
  }

  public void setLastPointCreatedAt(Point lastPointCreatedAt) {
    this.lastPointCreatedAt = lastPointCreatedAt;
  }

  public void setDataScene(DataScene ds) {
    dataScene = ds;
  }

  public DataScene getDataScene() {
    return dataScene;
  }

  /**
   * Checks whether an object is registered as a node in the graph model.
   *
   * @param object the object; must not be a Widget
   * @return true, if the object is registered as a node
   */
  public LayerWidget getBackgroundLayer() {
    return backgroundLayer;
  }

  public LayerWidget getConnectionLayer() {
    return connectionLayer;
  }

  public LayerWidget getForgroundLayer() {
    return forgroundLayer;
  }

  public LayerWidget getInteractionLayer() {
    return interactionLayer;
  }

  public LayerWidget getMainLayer() {
    return mainLayer;
  }

  public boolean isInput(Object object) {
    return inputs.contains((Widget) object);
  }

  public boolean isOutput(Widget targetWidget) {
    return outputs.contains(targetWidget);
  }

  public void addConnection(ConnectionWidget conn) {
    this.addEdge(conn);
  }

  public void addInputConnection(PortInteractor input) {
    inputs.add(input);
  }

  public void addInputConnection(CustomPortInteractor input) {
    inputs.add(input);
  }

  public void addOutputConnection(PortInteractor output) {
    outputs.add(output);
  }

  public void addOutputConnection(CustomPortInteractor output) {
    outputs.add(output);
  }

  private Widget findOutput(Object sourceNode) {
    int id = outputs.indexOf(sourceNode);
    return outputs.get(id);
  }

  private Widget findInput(Object sourceNode) {
    int id = inputs.indexOf(sourceNode);
    return inputs.get(id);
  }

  public WidgetAction getHoverAction() {
    return hoverAction;
  }

  // not working
  public void deleteSelected() {
    Set objects = getSelectedObjects();
  }

  public void createNode(VisualNode node) {
    mainLayer.addChild(node);
  }

  public VisualScene getVisualScene() {
    return this;
  }

  @Override
  public void paintChildren() {
    super.paintChildren();
  }

  @Override
  protected Widget attachNodeWidget(Object n) {
    Widget widget = (Widget) n;
    widget.setToolTipText("flow node");
    widget.createActions(USE).addAction(0, dragAction);
    widget.createActions(EDIT).addAction(0, createSelectAction());
    widget.createActions(EDIT).addAction(1, multiMove);
    widget.createActions(EDIT).addAction(2, new CustomResizeAction());
    widget.createActions(EDIT).addAction(3, createObjectHoverAction());

    mainLayer.addChild(widget);

    return widget;
  }

  @Override
  protected Widget attachEdgeWidget(Object e) {
    // create the visual connection
    CustomConnectionWidget connection = (CustomConnectionWidget) e;
    connection.setPaintControlPoints(true);
    connection.setRouter(CustomRouterFactory.createFreeRouter());
    connection.setControlPointShape(FlowControlPointShape.CIRCLE_FILLED_SMALL);

    // Normal Edit Mode actions
    connection
        .createActions(EDGE_CONTROL_MODE)
        .addAction(0, ActionFactory.createAddRemoveControlPointAction());
    connection
        .createActions(EDGE_CONTROL_MODE)
        .addAction(1, ActionFactory.createFreeMoveControlPointAction());
    connection
        .createActions(EDGE_CONTROL_MODE)
        .addAction(2, ActionFactory.createAddRemoveControlPointAction());
    connection
        .createActions(EDGE_CONTROL_MODE)
        .addAction(3, ActionFactory.createFreeMoveControlPointAction());
    connection.createActions(EDGE_CONTROL_MODE).addAction(4, createObjectHoverAction());

    connectionLayer.addChild(connection);

    // create the data connection
    //        Port srcPort = (Port)
    // connection.getSourceAnchor().getRelatedWidget().getParentWidget();
    //        VisualNode src = srcPort.getParentNode();
    //
    //        Port tgtPort = (Port)
    // connection.getTargetAnchor().getRelatedWidget().getParentWidget();
    //        VisualNode tgt = tgtPort.getParentNode();

    //        dataScene.connect(src.getDataNode(), srcPort.getID(), tgt.getDataNode(),
    // tgtPort.getID());

    return connection;
  }

  @Override
  protected void attachEdgeSourceAnchor(Object edge, Object sourceNode, Object n1) {
    Widget w = sourceNode != null ? findOutput(sourceNode) : null;
    ((ConnectionWidget) findWidget(edge)).setSourceAnchor(AnchorFactory.createRectangularAnchor(w));
  }

  @Override
  protected void attachEdgeTargetAnchor(Object edge, Object n, Object targetNode) {
    Widget w = targetNode != null ? findInput(targetNode) : null;
    ((ConnectionWidget) findWidget(edge)).setTargetAnchor(AnchorFactory.createRectangularAnchor(w));
  }

  private void connect(VisualNode source, int sourcePort, VisualNode target, int targetPort) {
    CustomConnectionWidget connection = new CustomConnectionWidget(this);
    Widget src = source.getOutputPort(sourcePort);
    Widget tgt = target.getInputPort(targetPort);
    connection.setSourceAnchor(AnchorFactory.createCircularAnchor(src, 2));
    connection.setTargetAnchor(AnchorFactory.createCircularAnchor(tgt, 2));
    addEdge(connection);

    connections.add(new Connection(source, sourcePort, target, targetPort, connection));
  }

  /*
   * for use with CustomBorderPort testing
   */
  private void connect(
      BorderPortTestNode source, int sourcePort, BorderPortTestNode target, int targetPort) {
    CustomConnectionWidget connection = new CustomConnectionWidget(this);
    Widget src = source.getOutputPort(sourcePort);
    Widget tgt = target.getInputPort(targetPort);
    connection.setSourceAnchor(AnchorFactory.createCircularAnchor(src, 2));
    connection.setTargetAnchor(AnchorFactory.createCircularAnchor(tgt, 2));
    addEdge(connection);

    connections.add(new Connection(source, sourcePort, target, targetPort, connection));
  }

  public void connect(CustomPortInteractor source, CustomPortInteractor target) {
    CustomConnectionWidget connection = new CustomConnectionWidget(this);
    connection.setSourceAnchor(AnchorFactory.createCircularAnchor(source, 1));
    connection.setTargetAnchor(AnchorFactory.createCircularAnchor(target, 1));

    // save one for each so that they connections can be accessed in both directions
    connections.add(
        new Connection(
            source.getNode(),
            source.getPortNumber(),
            target.getNode(),
            target.getPortNumber(),
            connection));
    addEdge(connection);
  }

  public void connect(PortInteractor source, PortInteractor target) {
    CustomConnectionWidget connection = new CustomConnectionWidget(this);
    connection.setSourceAnchor(AnchorFactory.createCircularAnchor(source, 1));
    connection.setTargetAnchor(AnchorFactory.createCircularAnchor(target, 1));

    // save one for each so that they connections can be accessed in both directions
    connections.add(
        new Connection(
            source.getNode(),
            source.getPortNumber(),
            target.getNode(),
            target.getPortNumber(),
            connection));
    addEdge(connection);
  }

  public void removeConnections(VisualNode node) {
    Iterator<Connection> i = connections.iterator();
    ArrayList<Connection> toRemove = new ArrayList<Connection>();
    while (i.hasNext()) {
      Connection connection = (Connection) i.next();
      if (connection.getSource() == node || connection.getTarget() == node) {
        toRemove.add(connection);
        this.removeEdge(connection.getConnectionWidget());
      }
    }

    Iterator<Connection> r = toRemove.iterator();
    while (r.hasNext()) {
      Connection removeConnection = r.next();
      connections.remove(removeConnection);
    }
  }

  public void setDataScene(NodeCreator d) {
    dataNodeCreator = d;
  }

  public void setEditMode() {
    this.setActiveTool(EDIT);
  }

  public void setAlignMode() {
    if (this.getActiveTool().equals(EDIT)) {
      setActiveTool(USE);
      removeHoverActions();
    } else {
      setActiveTool(EDIT);
      getActions().addAction(hoverAction);
    }
    printActiveToolMode();
  }

  private void printActiveToolMode() {
    //       System.out.println(this.getActiveTool());
    //       System.out.println(this.getActions());
  }

  private void routeSelectedEdges() {
    Object[] selectedObjects = this.getSelectedObjects().toArray();
    CustomConnectionWidget conn = new CustomConnectionWidget(this.getScene());
    for (int i = 0; i < selectedObjects.length; i++) {
      if (selectedObjects[i].getClass() == conn.getClass()) {
        CustomConnectionWidget connection = (CustomConnectionWidget) selectedObjects[i];
        connection.setRouter(CustomRouterFactory.createOrthogonalSearchRouter(mainLayer));
      }
    }
  }

  private void unrouteSelectedEdges() {
    Object[] selectedObjects = this.getSelectedObjects().toArray();
    CustomConnectionWidget conn = new CustomConnectionWidget(this.getScene());
    for (int i = 0; i < selectedObjects.length; i++) {
      if (selectedObjects[i].getClass() == conn.getClass()) {
        CustomConnectionWidget connection = (CustomConnectionWidget) selectedObjects[i];
        connection.setRouter(CustomRouterFactory.createDirectRouter());
      }
    }
  }

  public void mouseClicked(Widget widget, WidgetMouseEvent wme) {
    this.setLastX(this.getMouseX());
    this.setLastY(this.getMouseY());
    this.setMouseX(wme.getPoint().getX());
    this.setMouseY(wme.getPoint().getY());
  }

  public void mousePressed(Widget widget, WidgetMouseEvent wme) {
    this.setMouseDragged(true);
    this.setLastX(this.getMouseX());
    this.setLastY(this.getMouseY());
    this.setMouseX(wme.getPoint().getX());
    this.setMouseY(wme.getPoint().getY());
  }

  public void mouseReleased(Widget widget, WidgetMouseEvent wme) {
    this.setMouseDragged(false);
  }

  public void mouseEntered(Widget widget, WidgetMouseEvent wme) {
    this.setLastX(this.getMouseX());
    this.setLastY(this.getMouseY());
    this.setMouseX(wme.getPoint().getX());
    this.setMouseY(wme.getPoint().getY());
  }

  public void mouseExited(Widget widget, WidgetMouseEvent wme) {}

  public void mouseDragged(Widget widget, WidgetMouseEvent wme) {
    this.setLastX(this.getMouseX());
    this.setLastY(this.getMouseY());
    this.setMouseX(wme.getPoint().getX());
    this.setMouseY(wme.getPoint().getY());
    this.setxVelocity(this.getLastX() - this.getMouseX());
    this.setyVelocity(this.getMouseY() - this.getLastY());
  }

  void mouseMoved(Widget widget, WidgetMouseEvent wme) {
    this.setLastX(this.getMouseX());
    this.setLastY(this.getMouseY());
    this.setMouseX(wme.getPoint().getX());
    this.setMouseY(wme.getPoint().getY());
    this.setxVelocity(this.getLastX() - this.getMouseX());
    this.setyVelocity(this.getMouseY() - this.getLastY());
  }

  private void removeHoverActions() {
    this.getActions().removeAction(this.getHoverAction());
    Object[] nodes = this.getNodes().toArray();
    for (int i = 0; i < this.getNodes().size() - 1; i++) {
      VisualNode node = (VisualNode) nodes[i];
      node.removeHoverActions();
      //           System.out.println("hover scene off");
    }
  }

  public ArrayList<Connection> getConnections() {
    return connections;
  }

  private void addEdgeSelectionAction() {
    Collection<ConnectionWidget> edges = this.getEdges();
    for (Iterator i = edges.iterator(); i.hasNext(); ) {
      ConnectionWidget connection = (ConnectionWidget) i.next();
      connection.getActions().addAction(createSelectAction());
    }
  }

  private void removeEdgeSelectionAction() {
    Collection<ConnectionWidget> edges = this.getEdges();
    for (Iterator i = edges.iterator(); i.hasNext(); ) {
      ConnectionWidget connection = (ConnectionWidget) i.next();
      connection.getActions().removeAction(createSelectAction());
    }
  }

  private class MyConnectProvider implements ConnectProvider {

    @Override
    public boolean isSourceWidget(Widget source) {
      return source instanceof IconNodeWidget && source != null ? true : false;
    }

    @Override
    public ConnectorState isTargetWidget(Widget src, Widget trg) {
      return src != trg && trg instanceof IconNodeWidget
          ? ConnectorState.ACCEPT
          : ConnectorState.REJECT;
    }

    @Override
    public boolean hasCustomTargetWidgetResolver(Scene arg0) {
      return false;
    }

    @Override
    public Widget resolveTargetWidget(Scene arg0, Point arg1) {
      return null;
    }

    @Override
    public void createConnection(Widget source, Widget target) {
      ConnectionWidget conn = new ConnectionWidget(VisualScene.this);
      conn.setTargetAnchorShape(AnchorShape.TRIANGLE_FILLED);
      conn.setTargetAnchor(AnchorFactory.createRectangularAnchor(target));
      conn.setSourceAnchor(AnchorFactory.createRectangularAnchor(source));
      conn.getActions().addAction(createObjectHoverAction());
      conn.getActions().addAction(createSelectAction());
      connectionLayer.addChild(conn);
    }
  }

  // multi object moving
  private class MultiMoveProvider implements MoveProvider {

    private HashMap<Widget, Point> originals = new HashMap<Widget, Point>();
    private Point original;

    @Override
    public void movementStarted(Widget widget) {
      Object object = findObject(widget);
      if (isNode(object)) {
        for (Object o : getSelectedObjects()) {
          if (isNode(o)) {
            Widget w = findWidget(o);
            if (w != null) {
              originals.put(w, w.getPreferredLocation());
            }
          }
        }
      } else {
        originals.put(widget, widget.getPreferredLocation());
      }
    }

    @Override
    public void movementFinished(Widget widget) {
      originals.clear();
      original = null;
    }

    @Override
    public Point getOriginalLocation(Widget widget) {
      original = widget.getPreferredLocation();
      return original;
    }

    @Override
    public void setNewLocation(Widget widget, Point location) {
      int dx = location.x - original.x;
      int dy = location.y - original.y;
      for (Map.Entry<Widget, Point> entry : originals.entrySet()) {
        Point point = entry.getValue();
        entry.getKey().setPreferredLocation(new Point(point.x + dx, point.y + dy));
      }
    }
  }

  private final class KeyEventAction extends WidgetAction.Adapter {

    @Override
    public State keyPressed(Widget widget, WidgetKeyEvent event) {
      VisualScene scene = (VisualScene) widget;
      if (event.getKeyCode() == KeyEvent.VK_N) { // type 'n' to create a new object
        BorderPortTestNode node = new BorderPortTestNode(scene.getVisualScene());
        node.setPreferredLocation(new Point((int) scene.getMouseX(), (int) scene.getMouseY()));
        scene.setLastPointCreatedAt(new Point((int) scene.getMouseX(), (int) scene.getMouseY()));
        scene.addNode(node);
      }

      if (event.getKeyCode() == KeyEvent.VK_F) { // type 'f' to create a new object
        //                VisualNode node = new FloatDisplay(scene.getScene(),
        // scene.getDataScene());
        //                node.setPreferredLocation(new Point((int) scene.getMouseX(), (int)
        // scene.getMouseY()));
        //                scene.setLastPointCreatedAt(new Point((int) scene.getMouseX(), (int)
        // scene.getMouseY()));
        //                scene.addNode(node);
      }

      if (event.isAltDown()
          && event.getKeyCode() == KeyEvent.VK_A) { // alt + 'a' for align mode toggle
        scene.setAlignMode();
        scene.removeHoverActions();
      }

      if (event.isAltDown()
          && event.getKeyCode() == KeyEvent.VK_E) { // alt + 'e' for edit/use mode toggle
        scene.setEditMode();
      }

      if (event.isAltDown()
          && event.getKeyCode() == KeyEvent.VK_R) { // alt + 'r' route selected selectedObjects
        scene.routeSelectedEdges();
      }

      if (event.isAltDown() && event.isShiftDown() && event.getKeyCode() == KeyEvent.VK_R) {
        scene.unrouteSelectedEdges();
      }

      //// use arrows to move selected objects

      if (getSelectedObjects().size() > 0) {
        Set array = getSelectedObjects();
        if (event.getKeyCode() == KeyEvent.VK_UP) {
          for (Iterator i = array.iterator(); i.hasNext(); ) {
            try {
              BorderPortTestNode node = (BorderPortTestNode) i.next();
              node.setPreferredLocation(
                  new Point(node.getPreferredLocation().x, node.getPreferredLocation().y - 2));
            } catch (java.lang.ClassCastException e) {
            }
          }
        }

        if (event.getKeyCode() == KeyEvent.VK_DOWN) {
          for (Iterator i = array.iterator(); i.hasNext(); ) {
            try {
              BorderPortTestNode node = (BorderPortTestNode) i.next();
              node.setPreferredLocation(
                  new Point(node.getPreferredLocation().x, node.getPreferredLocation().y + 2));
            } catch (java.lang.ClassCastException e) {
            }
          }
        }

        if (event.getKeyCode() == KeyEvent.VK_LEFT) {
          for (Iterator i = array.iterator(); i.hasNext(); ) {
            try {
              BorderPortTestNode node = (BorderPortTestNode) i.next();
              node.setPreferredLocation(
                  new Point(node.getPreferredLocation().x - 2, node.getPreferredLocation().y));
            } catch (java.lang.ClassCastException e) {
            }
          }
        }

        if (event.getKeyCode() == KeyEvent.VK_RIGHT) {
          for (Iterator i = array.iterator(); i.hasNext(); ) {
            try {
              BorderPortTestNode node = (BorderPortTestNode) i.next();
              node.setPreferredLocation(
                  new Point(node.getPreferredLocation().x + 2, node.getPreferredLocation().y));
            } catch (java.lang.ClassCastException e) {
            }
          }
        }
      }

      if (event.getKeyCode() == KeyEvent.VK_E) {
        widget.getScene().setActiveTool(EDGE_CONTROL_MODE);
        scene.addEdgeSelectionAction();

      } else if (event.getKeyCode() == KeyEvent.VK_DELETE) {
        // need to add object and edge deletion
      }

      return State.REJECTED;
    }

    @Override
    public State keyReleased(Widget widget, WidgetKeyEvent event) {
      if (widget.getScene().getActiveTool().equals(EDGE_CONTROL_MODE)) {
        widget.getScene().setActiveTool(EDIT);
      }
      //      System.out.println(widget.getScene().getActiveTool());
      return State.REJECTED;
    }
  }

  private static class MyHoverProvider implements TwoStateHoverProvider {

    private Scene scene;

    public MyHoverProvider(Scene scene) {
      this.scene = scene;
    }

    @Override
    public void unsetHovering(Widget widget) {
      if (widget != null) {
        widget.setBackground(scene.getLookFeel().getBackground(ObjectState.createNormal()));
        widget.setForeground(new Color(0, 0, 0, 0));
        CustomPortInteractor port = (CustomPortInteractor) widget;
        port.setOver(false);
      }
    }

    @Override
    public void setHovering(Widget widget) {
      if (widget != null) {
        ObjectState state = ObjectState.createNormal().deriveSelected(true);
        widget.setBackground(scene.getLookFeel().getBackground(state));
        widget.setForeground(Color.yellow);
        CustomPortInteractor port = (CustomPortInteractor) widget;
        port.setOver(true);
      }
    }
  }

  /** @param ugens - an array of IUGenInfo objects sent from overtone/supercollider */
  public void addIUGenInfo(Collection<IUGenInfo> info) {
    if (info != null) {
      for (Iterator i = info.iterator(); i.hasNext(); ) {
        try {
          IUGenInfo ugenInfo = (IUGenInfo) i.next();
          trie.insert(ugenInfo.getName(), ugenInfo);
        } catch (NonUniqueKeyException ex) {
          Exceptions.printStackTrace(ex);
        } catch (BadKeyException ex) {
          Exceptions.printStackTrace(ex);
        }
      }
    }
  }
}
Пример #12
0
/** @author Santhosh Kumar T */
public class RuleScene extends GraphScene<Node, Edge> {
  private final WidgetAction moveAction = ActionFactory.createMoveAction();
  private final WidgetAction nodePopupAction =
      ActionFactory.createPopupMenuAction(new NodePopupProvider(this));
  private final WidgetAction edgePopupAction =
      ActionFactory.createPopupMenuAction(new EdgePopupProvider(this));

  private final WidgetAction hoverAction;
  private final WidgetAction editAction;

  private LayerWidget interactionLayer = new LayerWidget(this);
  private WidgetAction connectAction =
      ActionFactory.createConnectAction(interactionLayer, new NodeConnectProvider());

  private TwoStateHoverProvider hoverProvider;

  public File file;

  public RuleScene(TwoStateHoverProvider hoverProvider, EditProvider edgeEditProvider) {
    addChild(nodes);
    addChild(connections);
    addChild(interactionLayer);

    this.hoverProvider = hoverProvider;
    hoverAction = ActionFactory.createHoverAction(new Highlighter(hoverProvider));
    editAction = ActionFactory.createEditAction(edgeEditProvider);

    getActions().addAction(hoverAction);
    getActions().addAction(ActionFactory.createPopupMenuAction(new ScenePopupProvider(this)));
    getActions().addAction(ActionFactory.createWheelPanAction());
  }

  /*-------------------------------------------------[ Rule ]---------------------------------------------------*/

  private Syntax syntax;
  private Rule rule;
  public final Observable ruleObservable =
      new Observable() {
        @Override
        public void notifyObservers(Object arg) {
          setChanged();
          super.notifyObservers(arg);
        }
      };

  public void setRule(Syntax syntax, Rule rule) {
    this.syntax = syntax;

    if (this.rule != null) {
      for (Node node : getNodes().toArray(new Node[getNodes().size()])) removeNodeWithEdges(node);
    }
    this.rule = rule;
    if (this.rule != null) populate(rule.node);

    layout();
    hoverProvider.unsetHovering(this);
    ruleObservable.notifyObservers(rule);
  }

  public Syntax getSyntax() {
    return syntax;
  }

  public Rule getRule() {
    return rule;
  }

  private void populate(Node node) {
    if (findWidget(node) == null) {
      addNode(node);

      for (Edge edge : node.outgoing) {
        populate(edge.target);
        addEdge(edge);
        setEdgeSource(edge, edge.source);
        setEdgeTarget(edge, edge.target);
      }
    }
  }

  /*-------------------------------------------------[ Layout ]---------------------------------------------------*/

  private final SceneLayout layout =
      LayoutFactory.createSceneGraphLayout(this, new RuleLayout(false));

  public void layout() {
    validate();
    layout.invokeLayoutImmediately();
  }

  public void layout(Object model) {
    findWidget(model).revalidate();
    layout();
  }

  public void refresh() {
    Syntax syntax = this.syntax;
    Rule rule = this.rule;
    setRule(null, null);
    setRule(syntax, rule);
  }

  /*-------------------------------------------------[ Nodes ]---------------------------------------------------*/

  private final LayerWidget nodes = new LayerWidget(this);

  @Override
  protected Widget attachNodeWidget(Node node) {
    NodeWidget widget = new NodeWidget(this);
    widget.setFont(Util.FIXED_WIDTH_FONT);
    widget.highLight(false);

    nodes.addChild(widget);
    //        widget.getActions().addAction(moveAction);
    widget.getActions().addAction(hoverAction);
    widget.getActions().addAction(nodePopupAction);
    widget.getActions().addAction(connectAction);

    return widget;
  }

  /*-------------------------------------------------[ Edges ]---------------------------------------------------*/

  private final LayerWidget connections = new LayerWidget(this);
  private final Router router = new RuleRouter();

  private LabelWidget createEdgeLabel(Edge edge) {
    LabelWidget label = new LabelWidget(this, edge.toString());
    label.setFont(Util.FIXED_WIDTH_FONT);
    label.setBorder(BorderFactory.createEmptyBorder(0, 0, 2, 0));

    label.getActions().addAction(hoverAction);
    label.getActions().addAction(editAction);
    label.getActions().addAction(moveAction);
    label.getActions().addAction(edgePopupAction);
    return label;
  }

  @Override
  protected Widget attachEdgeWidget(Edge edge) {
    EdgeWidget connection = new EdgeWidget(this);
    connection.setStroke(Util.STROKE_2);
    connection.setTargetAnchorShape(AnchorShape.TRIANGLE_FILLED);

    LabelWidget label = createEdgeLabel(edge);
    connection.setConstraint(label, LayoutFactory.ConnectionWidgetLayoutAlignment.TOP_CENTER, 0.5f);

    connection.addChild(label);
    connections.addChild(connection);

    connection.setRouter(router);
    connection.highLight(false);

    connection.getActions().addAction(hoverAction);
    connection.getActions().addAction(editAction);
    connection.getActions().addAction(edgePopupAction);
    return connection;
  }

  @Override
  protected void attachEdgeSourceAnchor(Edge edge, Node oldSource, Node newSource) {
    Widget w = newSource != null ? findWidget(newSource) : null;
    ((ConnectionWidget) findWidget(edge)).setSourceAnchor(AnchorFactory.createRectangularAnchor(w));
  }

  @Override
  protected void attachEdgeTargetAnchor(Edge edge, Node oldTarget, Node newTarget) {
    Widget w = newTarget != null ? findWidget(newTarget) : null;
    ((ConnectionWidget) findWidget(edge)).setTargetAnchor(AnchorFactory.createRectangularAnchor(w));
  }

  /*-------------------------------------------------[ Executing ]---------------------------------------------------*/

  private Widget executionWidget;

  private void executing(Widget widget) {
    if (executionWidget != widget) {
      if (executionWidget != null) {
        ((NBLRWidget) executionWidget).executing(false);
        executionWidget = null;
      }
      if (widget != null) {
        executionWidget = widget;
        ((NBLRWidget) executionWidget).executing(true);
        final Rectangle bounds = Util.bounds(widget);
        SwingUtilities.invokeLater(
            new Runnable() {
              @Override
              public void run() {
                getView().scrollRectToVisible(bounds);
              }
            });
      }
      validate();
    }
  }

  public void executing(Node node) {
    executing(findWidget(node));
  }

  public void executing(Edge edge) {
    executing(findWidget(edge));
  }

  /*-------------------------------------------------[ Antialiasing ]---------------------------------------------------*/

  public void paintChildren() {
    Graphics2D g = getGraphics();
    Object anti = g.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
    Object textAnti = g.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING);
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g.setRenderingHint(
        RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    super.paintChildren();
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, anti);
    g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, textAnti);
  }
}
 public void setNewLocation(Widget widget, Point location) {
   ActionFactory.createDefaultMoveProvider().setNewLocation(widget, location);
 }
 public Point getOriginalLocation(Widget widget) {
   return ActionFactory.createDefaultMoveProvider().getOriginalLocation(widget);
 }
Пример #15
0
/**
 * Lumayan
 *
 * @author RAPID02
 */
public class LayoutScene extends DesktopScene
    implements SceneObserverCookie, CalibratedScene, ProjectPathDependant {

  public static final String TO_PAGE = "toPage";
  public static final String TO_HEIGHT = "toHeight";
  public static final String TO_FIT = "toFit";
  public static final String TO_WIDTH = "toWidth";

  private LayoutViewElement multiview;
  private LayerController layerController;

  public LayerController getLayerController() {
    return layerController;
  }

  public LayoutScene(LayoutViewElement mve, LayoutDataObject obj) {
    super();

    this.dataObject = obj;

    multiview = mve;
    this.projectPath =
        FileOwnerQuery.getOwner(obj.getPrimaryFile()).getProjectDirectory().getPath();
    this.lSystem = LayoutParser.parse(obj);
    //        addSaveAsCapable();

    LayoutDocument ld = lSystem.getDocument();
    ld.addPropertyChangeListener(new DocumentDPIChangeListener());

    // paper layer
    this.paperWidget = new PaperWidget(this, ld);
    // add paper biar bisa diedit2
    ic.add(ld);
    paperLayer.addChild(paperWidget);

    layerController = LayerFactory.createLayer(this, lSystem.getLayers());
    // init em listener
    ExplorerManager em = layerController.getExplorerManager();
    em.addPropertyChangeListener(new NodeSelectionListener());
    // main layer, where sublayout widgets will be added
    mainLayer = layerController.getRootWidget();
    addChild(mainLayer);

    // selection layer, directly above the main layer
    selectionLayer = new LayerWidget(this);
    selectionWrapperWidget = new SelectionWrapperWidget(this);
    selectionLayer.addChild(selectionWrapperWidget);
    addChild(selectionLayer);

    //        getPriorActions().addAction(new KeySwitchToolAction());
    // scene's actions, applied to all selected widgets
    // key move tool, always available
    getActions().addAction(KEY_MOVE_ACTION);
    // move tool
    createActions(FREE_MOVE_TOOL).addAction(MOVE_ACTION);
    createActions(ON_AXIS_MOVE_TOOL).addAction(ON_AXIS_MOVE_ACTION);
    setActiveTool(FREE_MOVE_TOOL);
    // rotate on outside of selectedwrapper border
    createActions(SelectionWrapperWidget.TRANSFORM_TOOL).addAction(ROTATE_ACTION);
    // mirror selected layer, only on transform mode
    createActions(SelectionWrapperWidget.TRANSFORM_TOOL).addAction(MIRROR_ACTION);
    // show popup under right click to show layers under cursor
    getActions().addAction(SELECT_ACTION);
    getPriorActions().addAction(SCROLL_MODIFIER_ACTION);
    initLookup();

    createView();
  }
  // ============================LAYERS================================

  /**
   * a layer that represents the desk surface where the paper is laid. This layer is required when
   * displaying paperWidget in a specific ZoomLevel. For example, when using "To Height" ZoomLevel,
   * the vertical scrollbar is placed in the middle instead of not shown at all. This layer contains
   * "dummy widget"s that represent the corners of the desktop.
   */
  private DesktopLayer desktopLayer;

  /** The working paper */
  private PaperWidget paperWidget;

  /** Main Layer where SubLayout is laid down. */
  private LayerWidget mainLayer;

  /** Selection layer to visualize the rectangle that contains all selected widget */
  private LayerWidget selectionLayer;

  private SelectionWrapperWidget selectionWrapperWidget;

  // ===========================DATA STRUCTURE============================
  /** Active, editable LayoutLSystem that can then be written to file on saving */
  private final LayoutLSystem lSystem;

  public LayoutLSystem getlSystem() {
    return lSystem;
  }

  /** Data Object that is associated with the file from which ls is loaded. */
  private LayoutDataObject dataObject;

  /** Path to project. Should be finalized on construction. */
  private final String projectPath;

  @Override
  public String getProjectPath() {
    return projectPath;
  }

  // ============================LOOKUP===================================
  private FormProxyLookup lookup;
  /** A content that contains all selected SubLayouts */
  private InstanceContent icForSelectedSubLayoutOnCanvas = new InstanceContent();

  private void initLookup() {
    Lookup explorerLookup; // lookup for EpxlorerManager
    Lookup plainContentLookup; // general util using ic
    Lookup dataObjectLookup; // to make sure DO is in lookup WHEN no node selected
    if (lookup == null) {
      lookup = new FormProxyLookup();

      explorerLookup = null;

      // general utility content
      // add itself (for satellite view)
      ic.add(this);
      // add calibrated zoom
      ic.add(new FixCenterCalibratedZoom(0.1));
      ic.add(new FixCenterCalibratedZoom(0.25));
      ic.add(new FixCenterCalibratedZoom(0.5));
      ic.add(new FixCenterCalibratedZoom(0.75));
      ic.add(new FixCenterCalibratedZoom(1));
      ic.add(new FixCenterCalibratedZoom(2));
      ic.add(new FixCenterCalibratedZoom(4));
      ic.add(new FixCenterCalibratedZoom(8));
      ic.add(new FixCenterCalibratedZoom(16));
      plainContentLookup = new AbstractLookup(ic);

      dataObjectLookup = null;
    } else {
      Lookup[] lookups = lookup.getSubLookups();
      explorerLookup = lookups[0];
      plainContentLookup = lookups[1];
      dataObjectLookup = lookups[2];
    }
    if (dataObjectLookup == null) {
      dataObjectLookup = dataObject.getNodeDelegate().getLookup();
    }
    if (explorerLookup == null) {
      ActionMap map = new ActionMap();
      explorerLookup = ExplorerUtils.createLookup(layerController.getExplorerManager(), map);
    }
    lookup.setSubLookups(new Lookup[] {explorerLookup, plainContentLookup, dataObjectLookup});
  }

  public Scene getOffscreenScene() {
    ImmutableLayoutScene offscreen = new ImmutableLayoutScene(dataObject, lSystem);
    return offscreen;
  }

  private static class FormProxyLookup extends ProxyLookup {

    FormProxyLookup() {
      super();
    }

    Lookup[] getSubLookups() {
      return getLookups();
    }

    void setSubLookups(Lookup[] lookups) {
      setLookups(lookups);
    }
  }

  private boolean settingLookup;

  private void switchNodeInLookup(boolean includeDataNodeLookup) {
    if (settingLookup) {
      return;
    }
    Lookup[] lookups = lookup.getSubLookups();
    int index = lookups.length - 1;
    boolean dataNodeLookup = (lookups[index] != Lookup.EMPTY);
    if (includeDataNodeLookup != dataNodeLookup) {
      lookups[index] =
          includeDataNodeLookup ? dataObject.getNodeDelegate().getLookup() : Lookup.EMPTY;
      try {
        settingLookup = true; // avoid re-entrant call
        lookup.setSubLookups(lookups);
      } finally {
        settingLookup = false;
      }
    }
  }

  @Override
  public Lookup getLookup() {
    return lookup;
  }

  // =========================VIEWING ACTIONS================================
  /**
   * Single selection, using right button click on scene. It will show popup containing layers under
   * mouse cursor.
   */
  private final WidgetAction SELECT_ACTION =
      ActionFactory.createPopupMenuAction(
          new PopupMenuProvider() {
            public JPopupMenu getPopupMenu(Widget widget, Point p) {
              // tes dulu
              // cari ada berapa slw contains p
              List<SubLayoutWidget> hit = new ArrayList<>();
              for (Object o : getObjects()) {
                Widget w = findWidget(o);
                if (w instanceof SubLayoutWidget && w.isHitAt(w.convertSceneToLocal(p))) {
                  SubLayoutWidget slw = (SubLayoutWidget) w;
                  hit.add(slw);
                }
              }
              JPopupMenu popup = new JPopupMenu();
              if (!hit.isEmpty()) {
                // sort slw
                Collections.sort(
                    hit,
                    new Comparator<SubLayoutWidget>() {
                      List<Widget> getParentWidgets(Widget w) {
                        ArrayList<Widget> ret = new ArrayList<>();
                        Widget wi = w;
                        ret.add(w); // add this
                        while (wi.getParentWidget() != mainLayer) {
                          ret.add(wi);
                          wi = wi.getParentWidget();
                        }
                        // reverse so that the oldest ancestor is placed first
                        Collections.reverse(ret);
                        return ret;
                      }

                      @Override
                      public int compare(SubLayoutWidget o1, SubLayoutWidget o2) {
                        List<Widget> l1 = getParentWidgets(o1);
                        List<Widget> l2 = getParentWidgets(o2);
                        int lvl = 0;
                        Widget w1 = l1.get(lvl);
                        Widget w2 = l2.get(lvl);
                        while (w1 == w2) {
                          lvl++;
                          w1 = l1.get(lvl);
                          w2 = l2.get(lvl);
                        }
                        // get the first branch lineage
                        // compare them
                        Widget p = w1.getParentWidget();
                        int r = 0;
                        for (Widget c : p.getChildren()) {
                          if (c == w1) {
                            r = 1;
                            break;
                          } else if (c == w2) {
                            r = -1;
                            break;
                          }
                        }
                        return r;
                      }
                    });
                for (SubLayoutWidget slw : hit) {
                  popup.add(new SLWMenuItem(slw));
                }
              }
              return popup;
            }
          });
  //
  //    public final void suggestSelectedLayer(SubLayoutLayer s) {
  //        suggestSelectedLayer(s, false);
  //    }
  //
  //    public final void suggestSelectedLayer(SubLayoutLayer s, boolean invert) {
  //        if (s == null) {
  //            if (!invert) {
  //                icForSelectedSubLayoutOnCanvas.set(Collections.EMPTY_LIST, null);
  //            }
  //        } else {
  //            HashSet<Object> objects = new HashSet<>(getSelectedObjects());
  //            if (invert) {
  //                //cek apakah sudah ada di selected
  //                if (objects.contains(s)) {
  //                    System.err.println("invert, sudah ada");
  //                    objects.remove(s);
  //                    icForSelectedSubLayoutOnCanvas.remove(s);
  //                } else {
  //                    System.err.println("invert, belum ada");
  //                    objects.add(s);
  //                    icForSelectedSubLayoutOnCanvas.add(s);
  //                }
  //                if (objects.isEmpty()) {
  //                    System.err.println("invert, jadi kosong");
  //                    //kasih default ke ic
  //
  // icForSelectedSubLayoutOnCanvas.set(Collections.singleton(SubLayout.getDefault()), null);
  //                }
  //            } else {
  //                //cek apakah sudah ada di selected
  //                if (!objects.contains(s)) {
  //                    System.err.println("bukan invert, belum ada");
  //                    icForSelectedSubLayoutOnCanvas.set(Collections.singleton(s), null);
  //                }
  //            }
  //        }
  //    }
  // ======================LIBRARY ACTIONS================================
  /** Assigning image from library palette with drag n drop gesture */
  private final WidgetAction LIB_ACTION =
      ActionFactory.createAcceptAction(new AssignLibActionOnSLW(this));

  public WidgetAction getLibAction() {
    return LIB_ACTION;
  }

  // ======================STRUCTURAL ACTIONS================================
  public static final String FREE_MOVE_TOOL = "freemove";
  private final String ON_AXIS_MOVE_TOOL = "onaxismove";

  /**
   * Move action, to move all selected SubLayoutWidgets. Using CTRL modifier, the displacement will
   * be limited on one axis (x/y).
   */
  private final WidgetAction MOVE_ACTION = new MoveSelectedLayerAction(this, false);

  private final WidgetAction KEY_MOVE_ACTION = new KeyMoveAction(this);
  private final WidgetAction ON_AXIS_MOVE_ACTION = new MoveSelectedLayerAction(this, true);

  /**
   * Mirror action. All selected layer will be mirrored such that these layer will be the reflection
   * of the original layer. The reflection will be done against a vertical line that vertically
   * bisects the bounding box of all selected layer.
   */
  private final WidgetAction MIRROR_ACTION = new MirrorSelectedLayerAction(this);
  /**
   * Rotate action. Rotates all selected SubLayoutWidgets. The rotation center is located at the
   * center of the selected widgets. Using modifier, the rotation will be done in 15-degrees
   * increment.
   */
  private final WidgetAction ROTATE_ACTION =
      new RotateMouseAction(new SelectedLayerRotateProvider(this));

  /**
   * Just like 3D, scrolling mouse wheel while holding modifier key (A, W, E) will change the angle,
   * width and length of selected layer, respectively.
   */
  private final WidgetAction SCROLL_MODIFIER_ACTION = new ScrollAction(this);

  @Override
  public void changeBackgroundColor(Color newColor) {
    LayoutDocument doc = lSystem.getDocument();
    Color old = lSystem.getDocument().getBackground();
    ChangeBackgroundUndoableEdit edit = new ChangeBackgroundUndoableEdit(doc, old, newColor);
    GlobalUndoManager.getManager().undoableEditHappened(new UndoableEditEvent(doc, edit));
    lSystem.getDocument().setBackground(newColor);
    addSavable();
  }

  @Override
  public Color getBackgroundColor() {
    return lSystem.getDocument().getBackground();
  }

  @Override
  protected Rectangle getWorkingRectangle(boolean withPaper) {
    Rectangle working = null;
    if (withPaper) {
      working = paperWidget.getPreferredBounds();
    }
    for (Object o : getObjects()) {
      Widget w = findWidget(o);
      if (w instanceof SubLayoutWidget) {
        Point wLoc = w.getPreferredLocation();
        Rectangle wRect = w.getBounds();
        if (wRect != null) {
          wRect.translate(wLoc.x, wLoc.y);
          if (working == null) {
            working = wRect;
          }
          working.add(wRect);
        }
      }
    }
    return working;
  }

  public void addSavable() {
    if (!dataObject.isModified()) {
      dataObject
          .getLookup()
          .lookup(InstanceContent.class)
          .add(new SceneSavable(lSystem, dataObject));
      //            ic.add(saverr);
      dataObject.setModified(true);
    }
  }

  public void requestActive() {
    multiview.requestActive();
    getView().requestFocusInWindow();
  }

  public void updateSelectionWrapper() {
    selectionWrapperWidget.revalidate();
    validate();
  }

  public void setAutoSelect(boolean autoSelect) {
    System.err.println("autoselect: " + autoSelect);
  }

  public void setTransformMode() {
    setActiveTool(SelectionWrapperWidget.TRANSFORM_TOOL);
    selectionWrapperWidget.activateTransform();
    requestActive();
  }

  public void setMoveMode() {

    setActiveTool(LayoutScene.FREE_MOVE_TOOL);
    selectionWrapperWidget.deactivateTransform();
    requestActive();
  }

  public void showRemarks(boolean show) {
    selectionWrapperWidget.setVisible(show);
    paperWidget.drawShadow = show;
    paperWidget.revalidate(true);
    for (Object o : getObjects()) {
      Widget w = findWidget(o);
      if (w instanceof SubLayoutWidget) {
        SubLayoutWidget slw = (SubLayoutWidget) w;
        slw.showEmptySquares(show);
      }
    }
  }

  /** When set to false, will hide all except those widgets representing layers. */
  @Override
  public void setWorkplaceVisible(boolean show) {
    paperWidget.setVisible(show);
    selectionWrapperWidget.setVisible(show);
    for (Object o : getObjects()) {
      Widget w = findWidget(o);
      if (w instanceof SubLayoutWidget) {
        SubLayoutWidget slw = (SubLayoutWidget) w;
        slw.showEmptySquares(show);
      }
    }
    validate();
  }

  /**
   * Zoom factor that considering current DPI. For example on 96 dpi screen, a 4x4 inch layout in 96
   * dpi displayed in 100% (actual) zoom will be as large as 4x4 inch layout in 192 dpi in 50%
   * (actual zoom). From user POV, both layout should be displayed in 100%, which is 4x4 inch.
   *
   * @return
   */
  @Override
  public double getCalibratedZoomFactor() {
    double actualZoom = getZoomFactor();
    int screenDPI = Toolkit.getDefaultToolkit().getScreenResolution();
    int layoutDPI = getlSystem().getDocument().getDPI();
    return actualZoom * layoutDPI / screenDPI;
  }

  @Override
  public void setCalibratedZoomFactor(double d) {
    int screenDPI = Toolkit.getDefaultToolkit().getScreenResolution();
    int layoutDPI = getlSystem().getDocument().getDPI();
    setCenteredZoomFactor(d * screenDPI / layoutDPI);
  }

  @Override
  protected CanvasWidget getCanvasWidget() {
    return paperWidget;
  }

  /**
   * Return the rectangle currently occupied by selectionWrapperWidget
   *
   * @return
   */
  public Rectangle getSelectedRectangle() {
    return selectionWrapperWidget.getPreferredBounds();
  }

  @NbBundle.Messages({"EXC_NavCannotBeNull=Please open Navigator panel before selecting layer."})
  private class SLWMenuItem extends JMenuItem {

    public SLWMenuItem(SubLayoutWidget slw) {
      super(slw.getLayername());
      addActionListener(
          new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
              LayoutLayer selected = (LayoutLayer) findObject(slw);
              // check whether navigator has already been opened
              Node n = selected.getNodeDelegate();
              if (n == null) {
                DialogDisplayer.getDefault()
                    .notify(
                        new NotifyDescriptor.Message(
                            Bundle.EXC_NavCannotBeNull(), NotifyDescriptor.INFORMATION_MESSAGE));
              } else {
                try {
                  layerController.getExplorerManager().setSelectedNodes(new Node[] {n});
                } catch (PropertyVetoException ex) {
                  Exceptions.printStackTrace(ex);
                }
              }
            }
          });
    }
  }

  ///////////////////////////////// LOOKUP/////////////////////////////////////
  private class FixCenterCalibratedZoom extends StrategicZoom {

    private final double zoomMultiplier;

    public FixCenterCalibratedZoom(double z) {
      zoomMultiplier = z;
    }

    @Override
    public String getDisplayName() {
      return String.valueOf((int) Math.floor(zoomMultiplier * 100)) + "%";
    }

    @Override
    public void zoom() {
      setCalibratedZoomFactor(zoomMultiplier);
    }
  }

  private class ChangeBackgroundUndoableEdit extends AbstractUndoableEdit {

    LayoutDocument d;
    Color o, n;

    public ChangeBackgroundUndoableEdit(LayoutDocument d, Color o, Color n) {
      this.d = d;
      this.n = n;
      this.o = o;
    }

    @Override
    public String getPresentationName() {
      return "Change Layout Background";
    }

    @Override
    public void redo() throws CannotRedoException {
      super.redo();
      d.setBackground(n);
      addSavable();
      validate();
    }

    @Override
    public void undo() throws CannotUndoException {
      super.undo();
      d.setBackground(o);
      addSavable();
      validate();
    }
  }

  private static final class KeyMoveAction extends WidgetAction.Adapter {

    private LayoutScene scene;

    private KeyMoveAction(LayoutScene aThis) {
      this.scene = aThis;
    }

    /**
     * TODO : Make it undoable?
     *
     * @param widget
     * @param event
     * @return
     */
    @Override
    public WidgetAction.State keyPressed(Widget widget, WidgetAction.WidgetKeyEvent event) {
      if (event.getKeyCode() == KeyEvent.VK_UP) {
        for (Object o : scene.getSelectedObjects()) {
          if (o instanceof SubLayoutLayer) {
            SubLayoutLayer sll = (SubLayoutLayer) o;
            sll.setY(sll.getY() - 1);
          }
        }
        return WidgetAction.State
            .CONSUMED; // set it as consumed, so it won't bubble to trigger scrolling
      } else if (event.getKeyCode() == KeyEvent.VK_DOWN) {
        for (Object o : scene.getSelectedObjects()) {
          if (o instanceof SubLayoutLayer) {
            SubLayoutLayer sll = (SubLayoutLayer) o;
            sll.setY(sll.getY() + 1);
          }
        }
        return WidgetAction.State
            .CONSUMED; // set it as consumed, so it won't bubble to trigger scrolling
      } else if (event.getKeyCode() == KeyEvent.VK_RIGHT) {
        for (Object o : scene.getSelectedObjects()) {
          if (o instanceof SubLayoutLayer) {
            SubLayoutLayer sll = (SubLayoutLayer) o;
            sll.setX(sll.getX() + 1);
          }
        }
        return WidgetAction.State
            .CONSUMED; // set it as consumed, so it won't bubble to trigger scrolling
      } else if (event.getKeyCode() == KeyEvent.VK_LEFT) {
        for (Object o : scene.getSelectedObjects()) {
          if (o instanceof SubLayoutLayer) {
            SubLayoutLayer sll = (SubLayoutLayer) o;
            sll.setX(sll.getX() - 1);
          }
        }
        return WidgetAction.State
            .CONSUMED; // set it as consumed, so it won't bubble to trigger scrolling
      }
      return super.keyPressed(widget, event);
    }
  }

  /**
   * Not used. Conflicting with Shift/Ctrl gesture on selecting multiple layer on navigator panel.
   */
  private final class KeySwitchToolAction extends WidgetAction.Adapter {

    @Override
    public WidgetAction.State keyPressed(Widget widget, WidgetAction.WidgetKeyEvent event) {
      if (event.getKeyCode() == KeyEvent.VK_CONTROL) {
        switch (getActiveTool()) {
          case FREE_MOVE_TOOL:
            setActiveTool(ON_AXIS_MOVE_TOOL);
            break;
          case SelectionWrapperWidget.TRANSFORM_TOOL:
            setActiveTool(SelectionWrapperWidget.ROTATE_DISCREET_TOOL);
            break;
        }
      } else if (event.getKeyCode() == KeyEvent.VK_SHIFT) {
        if (getActiveTool().equals(SelectionWrapperWidget.TRANSFORM_TOOL)) {
          setActiveTool(SelectionWrapperWidget.RESIZE_FROM_CENTER_TOOL);
        }
      }
      return WidgetAction.State.REJECTED;
    }

    @Override
    public WidgetAction.State keyReleased(Widget widget, WidgetAction.WidgetKeyEvent event) {
      if (event.getKeyCode() == KeyEvent.VK_CONTROL) {
        switch (getActiveTool()) {
          case ON_AXIS_MOVE_TOOL:
            setActiveTool(FREE_MOVE_TOOL);
            break;
          case SelectionWrapperWidget.ROTATE_DISCREET_TOOL:
            setActiveTool(SelectionWrapperWidget.TRANSFORM_TOOL);
            break;
        }
      } else if (event.getKeyCode() == KeyEvent.VK_SHIFT) {
        if (getActiveTool().equals(SelectionWrapperWidget.RESIZE_FROM_CENTER_TOOL)) {
          setActiveTool(SelectionWrapperWidget.TRANSFORM_TOOL);
        }
      }
      return WidgetAction.State.REJECTED;
    }
  }

  private class NodeSelectionListener implements PropertyChangeListener {

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
      if (ExplorerManager.PROP_SELECTED_NODES.equals(evt.getPropertyName())) {
        Node[] selectedNodes = layerController.getExplorerManager().getSelectedNodes();
        // if no form node, select data node (of FormDataObject) in lookup
        switchNodeInLookup(selectedNodes.length == 0 && dataObject.isValid());
      }
    }
  }

  private class DocumentDPIChangeListener implements PropertyChangeListener {

    /**
     * Update location, width & height of every sublayout, based on DPI.
     *
     * @param evt
     */
    @Override
    public void propertyChange(PropertyChangeEvent evt) {
      String type = evt.getPropertyName();
      switch (type) {
        case LayoutDocument.DPI_PROP:
          int oldDPI = (int) evt.getOldValue();
          int newDPI = (int) evt.getNewValue();
          for (Object o : getObjects()) {
            if (o instanceof SubLayoutLayer) {
              SubLayoutLayer sll = (SubLayoutLayer) o;
              sll.setLength(newDPI * sll.getLength() / oldDPI);
              sll.setWidth(newDPI * sll.getWidth() / oldDPI);
              Point p = sll.getLocation();
              sll.setLocation(new Point(p.x * newDPI / oldDPI, p.y * newDPI / oldDPI));
            }
          }
          break;
        case LayoutDocument.WIDTH_PROP:
        case LayoutDocument.HEIGHT_PROP:
          Point2D newMidPoint =
              new Point2D.Double(paperWidget.getWidth() / 2, paperWidget.getHeight() / 2);
          Point2D oldMidPoint =
              new Point2D.Double(paperWidget.getWidth() / 2, paperWidget.getHeight() / 2);
          Amount<Length> oldValue = (Amount<Length>) evt.getOldValue();
          // convert to pixel
          double oldDoubleValue =
              DocumentPaper.getLengthInPixel(oldValue, getlSystem().getDocument().getDPI());
          switch (evt.getPropertyName()) {
            case LayoutDocument.HEIGHT_PROP:
              oldMidPoint = new Point2D.Double(paperWidget.getWidth() / 2, oldDoubleValue / 2);
              break;
            case LayoutDocument.WIDTH_PROP:
              oldMidPoint = new Point2D.Double(oldDoubleValue / 2, paperWidget.getHeight() / 2);
              break;
          }
          int x_translate = (int) (newMidPoint.getX() - oldMidPoint.getX());
          int y_translate = (int) (newMidPoint.getY() - oldMidPoint.getY());
          Point oldWidgetLoc;
          for (Object o : getObjects()) {
            if (o instanceof SubLayoutLayer) {
              SubLayoutLayer sll = (SubLayoutLayer) o;
              oldWidgetLoc = sll.getLocation();
              oldWidgetLoc.translate(x_translate, y_translate);
              sll.setLocation(oldWidgetLoc);
            }
          }
          addSavable();
      }
    }
  }
}
Пример #16
0
  public ProxyAnchorExpandTest() {
    setBackground(Color.LIGHT_GRAY);

    // layer for widgets
    LayerWidget mainLayer = new LayerWidget(this);
    addChild(mainLayer);
    // layer for connections
    LayerWidget connLayer = new LayerWidget(this);
    addChild(connLayer);

    // outer widget
    Widget outerWidget = new Widget(this);
    outerWidget.setOpaque(true);
    outerWidget.setBackground(Color.WHITE);
    outerWidget.setBorder(BorderFactory.createLineBorder(10));
    outerWidget.setPreferredLocation(new Point(100, 100));
    outerWidget.setLayout(
        LayoutFactory.createVerticalFlowLayout(LayoutFactory.SerialAlignment.CENTER, 4));

    outerWidget.addChild(
        new LabelWidget(
            this, "The anchor switches based on a state in StateModel used by ProxyAnchor."));
    outerWidget.addChild(
        new LabelWidget(this, "ConnectionWidget has the same anchors assigned all the time."));

    // inner widget
    LabelWidget innerWidget = new LabelWidget(this, "Internal frame");
    innerWidget.setBorder(BorderFactory.createLineBorder());
    outerWidget.addChild(innerWidget);

    mainLayer.addChild(outerWidget);

    // the target widget
    Widget targetWidget =
        new LabelWidget(this, "Click here to switch the state in StateModel/anchor.");
    targetWidget.setOpaque(true);
    targetWidget.setBackground(Color.WHITE);
    targetWidget.setBorder(BorderFactory.createLineBorder(10));
    targetWidget.setPreferredLocation(new Point(450, 300));
    mainLayer.addChild(targetWidget);

    // an action for switching a state of a StateModel used by the ProxyAnchor to determinate an
    // active anchor
    WidgetAction switchAction = ActionFactory.createSelectAction(new SwitchProvider());
    targetWidget.getActions().addAction(switchAction);

    Anchor outerAnchor = AnchorFactory.createRectangularAnchor(outerWidget);
    Anchor innerAnchor = AnchorFactory.createRectangularAnchor(innerWidget);

    // a proxy anchor which acts like an one of the specified anchors.
    // The active anchor is defined by a state in the StateModel
    Anchor proxyAnchor = AnchorFactory.createProxyAnchor(model, outerAnchor, innerAnchor);

    // the connection widget
    ConnectionWidget conn = new ConnectionWidget(this);
    conn.setTargetAnchorShape(AnchorShape.TRIANGLE_FILLED);
    connLayer.addChild(conn);

    // the proxy anchor is used as a source
    conn.setSourceAnchor(proxyAnchor);
    // the target anchor is assigned to the targetWidget widget
    conn.setTargetAnchor(AnchorFactory.createRectangularAnchor(targetWidget));
  }