alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (DiagramScene.java)

This example Java source code file (DiagramScene.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

action, awt, blockwidget, border_size, diagramscene, diagramviewmodel, event, figure, figurewidget, gui, hashmap, hashset, layerwidget, list, point, rectangle, set, swing, undo, util

The DiagramScene.java Java example source code

/*
 * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code 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 General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */
package com.sun.hotspot.igv.view;

import com.sun.hotspot.igv.view.widgets.BlockWidget;
import com.sun.hotspot.igv.view.widgets.LineWidget;
import com.sun.hotspot.igv.util.DoubleClickAction;
import com.sun.hotspot.igv.data.InputBlock;
import com.sun.hotspot.igv.data.InputNode;
import com.sun.hotspot.igv.graph.Connection;
import com.sun.hotspot.igv.graph.Diagram;
import com.sun.hotspot.igv.graph.Figure;
import com.sun.hotspot.igv.graph.InputSlot;
import com.sun.hotspot.igv.graph.OutputSlot;
import com.sun.hotspot.igv.graph.Slot;
import com.sun.hotspot.igv.hierarchicallayout.HierarchicalClusterLayoutManager;
import com.sun.hotspot.igv.hierarchicallayout.OldHierarchicalLayoutManager;
import com.sun.hotspot.igv.hierarchicallayout.HierarchicalLayoutManager;
import com.sun.hotspot.igv.view.widgets.FigureWidget;
import com.sun.hotspot.igv.view.widgets.InputSlotWidget;
import com.sun.hotspot.igv.view.widgets.OutputSlotWidget;
import com.sun.hotspot.igv.view.widgets.SlotWidget;
import com.sun.hotspot.igv.layout.LayoutGraph;
import com.sun.hotspot.igv.data.services.Scheduler;
import com.sun.hotspot.igv.data.ChangedListener;
import com.sun.hotspot.igv.graph.Block;
import com.sun.hotspot.igv.util.ColorIcon;
import com.sun.hotspot.igv.util.ExtendedSelectAction;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.UndoableEditEvent;
import javax.swing.undo.AbstractUndoableEdit;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;
import org.netbeans.api.visual.action.ActionFactory;
import org.netbeans.api.visual.action.PopupMenuProvider;
import org.netbeans.api.visual.action.RectangularSelectDecorator;
import org.netbeans.api.visual.action.RectangularSelectProvider;
import org.netbeans.api.visual.action.SelectProvider;
import org.netbeans.api.visual.action.WidgetAction;
import org.netbeans.api.visual.animator.SceneAnimator;
import org.netbeans.api.visual.layout.LayoutFactory;
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 org.netbeans.api.visual.widget.LabelWidget;
import org.openide.awt.UndoRedo;
import org.openide.util.Lookup;
import org.openide.util.lookup.AbstractLookup;
import org.openide.util.lookup.InstanceContent;

/**
 *
 * @author Thomas Wuerthinger
 */
public class DiagramScene extends Scene implements ChangedListener<DiagramViewModel> {

    private HashMap<Figure, FigureWidget> figureWidgets;
    private HashMap<Slot, SlotWidget> slotWidgets;
    private HashMap<Connection, ConnectionWidget> connectionWidgets;
    private HashMap<InputBlock, BlockWidget> blockWidgets;
    private Widget hoverWidget;
    private WidgetAction hoverAction;
    private List<FigureWidget> selectedWidgets;
    private Lookup lookup;
    private InstanceContent content;
    private Action[] actions;
    private LayerWidget connectionLayer;
    private JScrollPane scrollPane;
    private UndoRedo.Manager undoRedoManager;
    private LayerWidget mainLayer;
    private LayerWidget slotLayer;
    private LayerWidget blockLayer;
    private double realZoomFactor;
    private BoundedZoomAction zoomAction;
    private WidgetAction panAction;
    private Widget topLeft;
    private Widget bottomRight;
    private LayerWidget startLayer;
    private LabelWidget startLabel;
    private DiagramViewModel model;
    private DiagramViewModel modelCopy;
    public static final int AFTER = 1;
    public static final int BEFORE = 1;
    public static final float ALPHA = 0.4f;
    public static final int GRID_SIZE = 30;
    public static final int BORDER_SIZE = 20;
    public static final int UNDOREDO_LIMIT = 100;
    public static final int SCROLL_UNIT_INCREMENT = 80;
    public static final int SCROLL_BLOCK_INCREMENT = 400;
    public static final float ZOOM_MAX_FACTOR = 3.0f;
    public static final float ZOOM_MIN_FACTOR = 0.0f;//0.15f;
    public static final float ZOOM_INCREMENT = 1.5f;
    public static final int SLOT_OFFSET = 6;
    public static final int ANIMATION_LIMIT = 40;
    private PopupMenuProvider popupMenuProvider = new PopupMenuProvider() {

        public JPopupMenu getPopupMenu(Widget widget, Point localLocation) {
            return DiagramScene.this.createPopupMenu();
        }
    };
    private RectangularSelectDecorator rectangularSelectDecorator = new RectangularSelectDecorator() {

        public Widget createSelectionWidget() {
            Widget widget = new Widget(DiagramScene.this);
            widget.setBorder(BorderFactory.createLineBorder(Color.black, 2));
            widget.setForeground(Color.red);
            return widget;
        }
    };
    private RectangularSelectProvider rectangularSelectProvider = new RectangularSelectProvider() {

        public void performSelection(Rectangle rectangle) {
            if (rectangle.width < 0) {
                rectangle.x += rectangle.width;
                rectangle.width *= -1;
            }

            if (rectangle.height < 0) {
                rectangle.y += rectangle.height;
                rectangle.height *= -1;
            }

            boolean updated = false;
            for (Figure f : getModel().getDiagramToView().getFigures()) {
                FigureWidget w = figureWidgets.get(f);
                Rectangle r = new Rectangle(w.getBounds());
                r.setLocation(w.getLocation());
                if (r.intersects(rectangle)) {
                    if (!selectedWidgets.contains(w)) {
                        addToSelection(w);
                        updated = true;
                    }
                } else {
                    if (selectedWidgets.contains(w)) {
                        selectedWidgets.remove(w);
                        content.remove(w.getNode());
                        w.setState(w.getState().deriveSelected(false));
                        updated = true;
                    }
                }
            }

            if (updated) {
                selectionUpdated();
            }
        }
    };
    private SelectProvider selectProvider = new SelectProvider() {

        public boolean isAimingAllowed(Widget widget, Point point, boolean b) {
            return false;
        }

        public boolean isSelectionAllowed(Widget widget, Point point, boolean b) {
            return widget instanceof FigureWidget || widget == DiagramScene.this;
        }

        public void select(Widget w, Point point, boolean change) {

            boolean updated = false;

            if (w == DiagramScene.this) {
                if (DiagramScene.this.selectedWidgets.size() != 0) {
                    clearSelection();
                    selectionUpdated();
                }
                return;
            }

            FigureWidget widget = (FigureWidget) w;


            if (change) {
                if (widget.getState().isSelected()) {
                    assert selectedWidgets.contains(widget);
                    widget.setState(widget.getState().deriveSelected(false));
                    selectedWidgets.remove(widget);
                    content.remove(widget.getNode());
                    updated = true;
                } else {
                    assert !selectedWidgets.contains(widget);
                    addToSelection(widget);
                    updated = true;
                    assert widget.getState().isSelected();
                }
            } else {

                if (widget.getState().isSelected()) {
                    assert selectedWidgets.contains(widget);
                } else {

                    assert !selectedWidgets.contains(widget);
                    clearSelection();
                    addToSelection(widget);
                    updated = true;
                    assert widget.getState().isSelected();
                }
            }

            if (updated) {
                selectionUpdated();
            }

        }
    };

    private FigureWidget getFigureWidget(Figure f) {
        return figureWidgets.get(f);
    }
    private FocusListener focusListener = new FocusListener() {

        public void focusGained(FocusEvent e) {
            DiagramScene.this.getView().requestFocus();
        }

        public void focusLost(FocusEvent e) {
        }
    };
    private MouseWheelListener mouseWheelListener = new MouseWheelListener() {

        public void mouseWheelMoved(MouseWheelEvent e) {
            DiagramScene.this.zoomAction.mouseWheelMoved(DiagramScene.this, new WidgetAction.WidgetMouseWheelEvent(0, e));
            DiagramScene.this.validate();
        }
    };
    private MouseListener mouseListener = new MouseListener() {

        public void mouseClicked(MouseEvent e) {
            DiagramScene.this.panAction.mouseClicked(DiagramScene.this, new WidgetAction.WidgetMouseEvent(0, e));
        }

        public void mousePressed(MouseEvent e) {
            DiagramScene.this.panAction.mousePressed(DiagramScene.this, new WidgetAction.WidgetMouseEvent(0, e));
        }

        public void mouseReleased(MouseEvent e) {
            DiagramScene.this.panAction.mouseReleased(DiagramScene.this, new WidgetAction.WidgetMouseEvent(0, e));
        }

        public void mouseEntered(MouseEvent e) {
            DiagramScene.this.panAction.mouseEntered(DiagramScene.this, new WidgetAction.WidgetMouseEvent(0, e));
        }

        public void mouseExited(MouseEvent e) {
            DiagramScene.this.panAction.mouseExited(DiagramScene.this, new WidgetAction.WidgetMouseEvent(0, e));
        }
    };
    private MouseMotionListener mouseMotionListener = new MouseMotionListener() {

        public void mouseDragged(MouseEvent e) {
            DiagramScene.this.panAction.mouseDragged(DiagramScene.this, new WidgetAction.WidgetMouseEvent(0, e));
        }

        public void mouseMoved(MouseEvent e) {
        }
    };
    private ScrollChangeListener scrollChangeListener = new ScrollChangeListener();

    private class ScrollChangeListener implements ChangeListener {

        private Map<Widget, Point> relativePositions = new HashMap();
        private Point oldPosition;

        public void register(Widget w, Point p) {
            relativePositions.put(w, p);
        }

        public void unregister(Widget w) {
            relativePositions.remove(w);
        }

        public void stateChanged(ChangeEvent e) {
            Point p = DiagramScene.this.getScrollPane().getViewport().getViewPosition();
            if (oldPosition == null || !p.equals(oldPosition)) {
                for (Widget w : relativePositions.keySet()) {
                    Point curPoint = relativePositions.get(w);
                    Point newPoint = new Point(p.x + curPoint.x, p.y + curPoint.y);
                    w.setPreferredLocation(newPoint);
                    DiagramScene.this.validate();
                }
                oldPosition = p;
            }
        }
    }

    public Point getScrollPosition() {
        return getScrollPane().getViewport().getViewPosition();
    }

    public void setScrollPosition(Point p) {
        getScrollPane().getViewport().setViewPosition(p);
    }

    public DiagramScene(Action[] actions, DiagramViewModel model) {
        this.actions = actions;
        selectedWidgets = new ArrayList<FigureWidget>();
        content = new InstanceContent();
        lookup = new AbstractLookup(content);
        this.setCheckClipping(true);
        this.getInputBindings().setZoomActionModifiers(0);

        JComponent comp = this.createView();
        comp.setDoubleBuffered(true);
        comp.setBackground(Color.WHITE);
        comp.setOpaque(true);

        this.setBackground(Color.WHITE);
        this.setOpaque(true);
        scrollPane = new JScrollPane(comp);
        scrollPane.setBackground(Color.WHITE);
        scrollPane.getVerticalScrollBar().setUnitIncrement(SCROLL_UNIT_INCREMENT);
        scrollPane.getVerticalScrollBar().setBlockIncrement(SCROLL_BLOCK_INCREMENT);
        scrollPane.getHorizontalScrollBar().setUnitIncrement(SCROLL_UNIT_INCREMENT);
        scrollPane.getHorizontalScrollBar().setBlockIncrement(SCROLL_BLOCK_INCREMENT);
        scrollPane.getViewport().addChangeListener(scrollChangeListener);
        hoverAction = this.createWidgetHoverAction();

        blockLayer = new LayerWidget(this);
        this.addChild(blockLayer);

        startLayer = new LayerWidget(this);
        this.addChild(startLayer);
        // TODO: String startLabelString = "Loading graph with " + originalDiagram.getFigures().size() + " figures and " + originalDiagram.getConnections().size() + " connections...";
        String startLabelString = "";
        LabelWidget w = new LabelWidget(this, startLabelString);
        scrollChangeListener.register(w, new Point(10, 10));
        w.setAlignment(LabelWidget.Alignment.CENTER);
        startLabel = w;
        startLayer.addChild(w);

        mainLayer = new LayerWidget(this);
        this.addChild(mainLayer);

        topLeft = new Widget(this);
        topLeft.setPreferredLocation(new Point(-BORDER_SIZE, -BORDER_SIZE));
        this.addChild(topLeft);


        bottomRight = new Widget(this);
        bottomRight.setPreferredLocation(new Point(-BORDER_SIZE, -BORDER_SIZE));
        this.addChild(bottomRight);

        slotLayer = new LayerWidget(this);
        this.addChild(slotLayer);

        connectionLayer = new LayerWidget(this);
        this.addChild(connectionLayer);

        LayerWidget selectionLayer = new LayerWidget(this);
        this.addChild(selectionLayer);

        this.setLayout(LayoutFactory.createAbsoluteLayout());

        this.getActions().addAction(hoverAction);
        zoomAction = new BoundedZoomAction(1.1, false);
        zoomAction.setMaxFactor(ZOOM_MAX_FACTOR);
        zoomAction.setMinFactor(ZOOM_MIN_FACTOR);
        this.getActions().addAction(ActionFactory.createMouseCenteredZoomAction(1.1));
        panAction = new ExtendedPanAction();
        this.getActions().addAction(panAction);
        this.getActions().addAction(ActionFactory.createPopupMenuAction(popupMenuProvider));

        LayerWidget selectLayer = new LayerWidget(this);
        this.addChild(selectLayer);
        this.getActions().addAction(ActionFactory.createRectangularSelectAction(rectangularSelectDecorator, selectLayer, rectangularSelectProvider));

        blockWidgets = new HashMap<InputBlock, BlockWidget>();

        boolean b = this.getUndoRedoEnabled();
        this.setUndoRedoEnabled(false);
        this.setNewModel(model);
        this.setUndoRedoEnabled(b);
    }

    private void selectionUpdated() {
        getModel().setSelectedNodes(this.getSelectedNodes());
        addUndo();
    }

    public DiagramViewModel getModel() {
        return model;
    }

    public void setRealZoomFactor(double d) {
        this.realZoomFactor = d;
    }

    public double getRealZoomFactor() {
        if (realZoomFactor == 0.0) {
            return getZoomFactor();
        } else {
            return realZoomFactor;
        }
    }

    public JScrollPane getScrollPane() {
        return scrollPane;
    }

    public boolean isAllVisible() {
        return getModel().getHiddenNodes().size() == 0;
    }

    public Action createGotoAction(final Figure f) {
        final DiagramScene diagramScene = this;
        Action a = new AbstractAction() {

            public void actionPerformed(ActionEvent e) {
                diagramScene.gotoFigure(f);
            }
        };

        a.setEnabled(true);
        a.putValue(Action.SMALL_ICON, new ColorIcon(f.getColor()));
        String name = f.getLines()[0];

        name += " (";

        if (f.getCluster() != null) {
            name += "B" + f.getCluster().toString();
        }
        if (!this.getFigureWidget(f).isVisible()) {
            if (f.getCluster() != null) {
                name += ", ";
            }
            name += "hidden";
        }
        name += ")";
        a.putValue(Action.NAME, name);
        return a;
    }

    public void setNewModel(DiagramViewModel model) {
        if (this.model != null) {
            this.model.getDiagramChangedEvent().removeListener(this);
            this.model.getViewPropertiesChangedEvent().removeListener(this);
        }
        this.model = model;

        if (this.model == null) {
            this.modelCopy = null;
        } else {
            this.modelCopy = this.model.copy();
        }

        model.getDiagramChangedEvent().addListener(this);
        model.getViewPropertiesChangedEvent().addListener(this);

        update();
    }

    private void update() {

        /*if (startLabel != null) {
        // Animate fade-out
        final LabelWidget labelWidget = this.startLabel;
        labelWidget.setVisible(true);
        RequestProcessor.getDefault().post(new Runnable() {
        public void run() {
        final int Sleep = 200;
        final int Progress = 10;
        for (int i = 0; i < 255 / Progress + 1; i++) {
        try {
        SwingUtilities.invokeAndWait(new Runnable() {
        public void run() {
        Color c = labelWidget.getForeground();
        int v = c.getRed();
        v += Progress;
        if (v > 255) {
        v = 255;
        }
        labelWidget.setForeground(new Color(v, v, v, 255 - v));
        labelWidget.getScene().validate();
        }
        });
        } catch (InterruptedException ex) {
        } catch (InvocationTargetException ex) {
        }
        try {
        Thread.sleep(Sleep);
        } catch (InterruptedException ex) {
        }
        }
        labelWidget.setVisible(false);
        DiagramScene.this.scrollChangeListener.unregister(labelWidget);
        }
        }, 1000);
        startLabel = null;
        }*/

        slotLayer.removeChildren();
        mainLayer.removeChildren();
        blockLayer.removeChildren();

        blockWidgets.clear();
        figureWidgets = new HashMap<Figure, FigureWidget>();
        slotWidgets = new HashMap<Slot, SlotWidget>();
        connectionWidgets = new HashMap<Connection, ConnectionWidget>();

        WidgetAction selectAction = new ExtendedSelectAction(selectProvider);
        Diagram d = getModel().getDiagramToView();

        if (getModel().getShowBlocks()) {
            Scheduler s = Lookup.getDefault().lookup(Scheduler.class);
            Collection<InputBlock> newBlocks = new ArrayList(s.schedule(d.getGraph()));
            d.schedule(newBlocks);
        }

        for (Figure f : d.getFigures()) {
            FigureWidget w = new FigureWidget(f, this, mainLayer);
            w.getActions().addAction(selectAction);
            w.getActions().addAction(hoverAction);
            w.getActions().addAction(ActionFactory.createPopupMenuAction(w));
            w.getActions().addAction(new DoubleClickAction(w));
            w.setVisible(false);

            figureWidgets.put(f, w);

            for (InputSlot s : f.getInputSlots()) {
                SlotWidget sw = new InputSlotWidget(s, this, slotLayer, w);
                slotWidgets.put(s, sw);
                sw.getActions().addAction(selectAction);
            }

            for (OutputSlot s : f.getOutputSlots()) {
                SlotWidget sw = new OutputSlotWidget(s, this, slotLayer, w);
                slotWidgets.put(s, sw);
                sw.getActions().addAction(selectAction);
            }
        }

        if (getModel().getShowBlocks()) {
            for (InputBlock bn : d.getGraph().getBlocks()) {
                BlockWidget w = new BlockWidget(this, d, bn);
                w.setVisible(false);
                blockWidgets.put(bn, w);
                blockLayer.addChild(w);
            }
        }

        this.smallUpdate(true);

    }

    private void smallUpdate(boolean relayout) {

        this.updateHiddenNodes(model.getHiddenNodes(), relayout);
        boolean b = this.getUndoRedoEnabled();
        this.setUndoRedoEnabled(false);
        this.setSelection(getModel().getSelectedNodes());
        this.setUndoRedoEnabled(b);
        this.validate();
    }

    private boolean isVisible(Connection c) {
        FigureWidget w1 = figureWidgets.get(c.getInputSlot().getFigure());
        FigureWidget w2 = figureWidgets.get(c.getOutputSlot().getFigure());

        if (w1.isVisible() && w2.isVisible()) {
            return true;
        }

        return false;
    }

    private void relayout(Set<Widget> oldVisibleWidgets) {

        Diagram diagram = getModel().getDiagramToView();

        HashSet<Figure> figures = new HashSet
(); for (Figure f : diagram.getFigures()) { FigureWidget w = figureWidgets.get(f); if (w.isVisible()) { figures.add(f); } } HashSet<Connection> edges = new HashSet(); for (Connection c : diagram.getConnections()) { if (isVisible(c)) { edges.add(c); } } if (getModel().getShowBlocks()) { HierarchicalClusterLayoutManager m = new HierarchicalClusterLayoutManager(OldHierarchicalLayoutManager.Combine.SAME_OUTPUTS); HierarchicalLayoutManager manager = new HierarchicalLayoutManager(HierarchicalLayoutManager.Combine.SAME_OUTPUTS); manager.setMaxLayerLength(9); manager.setMinLayerDifference(3); m.setManager(manager); m.setSubManager(new HierarchicalLayoutManager(HierarchicalLayoutManager.Combine.SAME_OUTPUTS)); m.doLayout(new LayoutGraph(edges, figures)); } else { HierarchicalLayoutManager manager = new HierarchicalLayoutManager(HierarchicalLayoutManager.Combine.SAME_OUTPUTS); manager.setMaxLayerLength(10); manager.doLayout(new LayoutGraph(edges, figures)); } int maxX = -BORDER_SIZE; int maxY = -BORDER_SIZE; for (Figure f : diagram.getFigures()) { FigureWidget w = figureWidgets.get(f); if (w.isVisible()) { Point p = f.getPosition(); Dimension d = f.getSize(); maxX = Math.max(maxX, p.x + d.width); maxY = Math.max(maxY, p.y + d.height); } } for (Connection c : diagram.getConnections()) { List<Point> points = c.getControlPoints(); FigureWidget w1 = figureWidgets.get((Figure) c.getTo().getVertex()); FigureWidget w2 = figureWidgets.get((Figure) c.getFrom().getVertex()); if (w1.isVisible() && w2.isVisible()) { for (Point p : points) { if (p != null) { maxX = Math.max(maxX, p.x); maxY = Math.max(maxY, p.y); } } } } if (getModel().getShowBlocks()) { for (Block b : diagram.getBlocks()) { BlockWidget w = blockWidgets.get(b.getInputBlock()); if (w != null && w.isVisible()) { Rectangle r = b.getBounds(); maxX = Math.max(maxX, r.x + r.width); maxY = Math.max(maxY, r.y + r.height); } } } bottomRight.setPreferredLocation(new Point(maxX + BORDER_SIZE, maxY + BORDER_SIZE)); int offx = 0; int offy = 0; int curWidth = maxX + 2 * BORDER_SIZE; int curHeight = maxY + 2 * BORDER_SIZE; Rectangle bounds = this.getScrollPane().getBounds(); if (curWidth < bounds.width) { offx = (bounds.width - curWidth) / 2; } if (curHeight < bounds.height) { offy = (bounds.height - curHeight) / 2; } final int offx2 = offx; final int offy2 = offy; SceneAnimator animator = this.getSceneAnimator(); connectionLayer.removeChildren(); int visibleFigureCount = 0; for (Figure f : diagram.getFigures()) { if (figureWidgets.get(f).isVisible()) { visibleFigureCount++; } } for (Figure f : diagram.getFigures()) { for (OutputSlot s : f.getOutputSlots()) { SceneAnimator anim = animator; if (visibleFigureCount > ANIMATION_LIMIT) { anim = null; } processOutputSlot(s, s.getConnections(), 0, null, null, offx2, offy2, anim); } } for (Figure f : diagram.getFigures()) { FigureWidget w = figureWidgets.get(f); if (w.isVisible()) { Point p = f.getPosition(); Point p2 = new Point(p.x + offx2, p.y + offy2); Rectangle r = new Rectangle(p.x + offx2, p.y + offy2, f.getSize().width, f.getSize().height); if (oldVisibleWidgets.contains(w)) { if (visibleFigureCount > ANIMATION_LIMIT) { w.setPreferredLocation(p2); } else { animator.animatePreferredLocation(w, p2); } } else { w.setPreferredLocation(p2); } } } if (getModel().getShowBlocks()) { for (Block b : diagram.getBlocks()) { BlockWidget w = blockWidgets.get(b.getInputBlock()); if (w != null && w.isVisible()) { Point location = new Point(b.getBounds().x + offx2, b.getBounds().y + offy2); Rectangle r = new Rectangle(location.x, location.y, b.getBounds().width, b.getBounds().height); if (oldVisibleWidgets.contains(w)) { if (visibleFigureCount > ANIMATION_LIMIT) { w.setPreferredBounds(r); } else { animator.animatePreferredBounds(w, r); } } else { w.setPreferredBounds(r); } } } } } private final Point specialNullPoint = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE); private void processOutputSlot(OutputSlot s, List<Connection> connections, int controlPointIndex, Point lastPoint, LineWidget predecessor, int offx, int offy, SceneAnimator animator) { Map<Point, List pointMap = new HashMap>(); for (Connection c : connections) { if (!isVisible(c)) { continue; } List<Point> controlPoints = c.getControlPoints(); if (controlPointIndex >= controlPoints.size()) { continue; } Point cur = controlPoints.get(controlPointIndex); if (cur == null) { cur = specialNullPoint; } else if (controlPointIndex == 0 && !s.getShowName()) { cur = new Point(cur.x, cur.y - SLOT_OFFSET); } else if (controlPointIndex == controlPoints.size() - 1 && !c.getInputSlot().getShowName()) { cur = new Point(cur.x, cur.y + SLOT_OFFSET); } if (pointMap.containsKey(cur)) { pointMap.get(cur).add(c); } else { List<Connection> newList = new ArrayList(2); newList.add(c); pointMap.put(cur, newList); } } for (Point p : pointMap.keySet()) { List<Connection> connectionList = pointMap.get(p); boolean isBold = false; boolean isDashed = true; for (Connection c : connectionList) { if (c.getStyle() == Connection.ConnectionStyle.BOLD) { isBold = true; } if (c.getStyle() != Connection.ConnectionStyle.DASHED) { isDashed = false; } } LineWidget newPredecessor = predecessor; if (p == specialNullPoint) { } else if (lastPoint == specialNullPoint) { } else if (lastPoint != null) { Point p1 = new Point(lastPoint.x + offx, lastPoint.y + offy); Point p2 = new Point(p.x + offx, p.y + offy); LineWidget w = new LineWidget(this, s, connectionList, p1, p2, predecessor, animator, isBold, isDashed); newPredecessor = w; connectionLayer.addChild(w); w.getActions().addAction(hoverAction); } processOutputSlot(s, connectionList, controlPointIndex + 1, p, newPredecessor, offx, offy, animator); } } private void clearSelection() { if (selectedWidgets.size() == 0) { return; } for (FigureWidget w : selectedWidgets) { assert w.getState().isSelected(); w.setState(w.getState().deriveSelected(false)); content.remove(w.getNode()); } selectedWidgets.clear(); } public Lookup getLookup() { return lookup; } public void gotoFigures(final List<Figure> figures) { Rectangle overall = null; showFigures(figures); for (Figure f : figures) { FigureWidget fw = getFigureWidget(f); if (fw != null) { Rectangle r = fw.getBounds(); Point p = fw.getLocation(); Rectangle r2 = new Rectangle(p.x, p.y, r.width, r.height); if (overall == null) { overall = r2; } else { overall = overall.union(r2); } } } if (overall != null) { centerRectangle(overall); } } private Point calcCenter(Rectangle r) { Point center = new Point((int) r.getCenterX(), (int) r.getCenterY()); center.x -= getScrollPane().getViewport().getViewRect().width / 2; center.y -= getScrollPane().getViewport().getViewRect().height / 2; // Ensure to be within area center.x = Math.max(0, center.x); center.x = Math.min(getScrollPane().getViewport().getViewSize().width - getScrollPane().getViewport().getViewRect().width, center.x); center.y = Math.max(0, center.y); center.y = Math.min(getScrollPane().getViewport().getViewSize().height - getScrollPane().getViewport().getViewRect().height, center.y); return center; } private void centerRectangle(Rectangle r) { if (getScrollPane().getViewport().getViewRect().width == 0 || getScrollPane().getViewport().getViewRect().height == 0) { return; } Rectangle r2 = new Rectangle(r.x, r.y, r.width, r.height); r2 = convertSceneToView(r2); double factorX = (double) r2.width / (double) getScrollPane().getViewport().getViewRect().width; double factorY = (double) r2.height / (double) getScrollPane().getViewport().getViewRect().height; double factor = Math.max(factorX, factorY); if (factor >= 1.0) { Point p = getScrollPane().getViewport().getViewPosition(); setZoomFactor(getZoomFactor() / factor); r2.x /= factor; r2.y /= factor; r2.width /= factor; r2.height /= factor; getScrollPane().getViewport().setViewPosition(calcCenter(r2)); } else { getScrollPane().getViewport().setViewPosition(calcCenter(r2)); } } private void addToSelection(Figure f) { FigureWidget w = getFigureWidget(f); addToSelection(w); } private void addToSelection(FigureWidget w) { assert !selectedWidgets.contains(w); selectedWidgets.add(w); content.add(w.getNode()); w.setState(w.getState().deriveSelected(true)); } private void setSelection(Set<Integer> nodes) { clearSelection(); for (Figure f : getModel().getDiagramToView().getFigures()) { if (doesIntersect(f.getSource().getSourceNodesAsSet(), nodes)) { addToSelection(f); } } selectionUpdated(); this.validate(); } public void setSelection(Collection<Figure> list) { clearSelection(); for (Figure f : list) { addToSelection(f); } selectionUpdated(); this.validate(); } public Set<Figure> getSelectedFigures() { Set<Figure> result = new HashSet
(); for (Widget w : selectedWidgets) { if (w instanceof FigureWidget) { FigureWidget fw = (FigureWidget) w; if (fw.getState().isSelected()) { result.add(fw.getFigure()); } } } return result; } public Set<Integer> getSelectedNodes() { Set<Integer> result = new HashSet(); for (Widget w : selectedWidgets) { if (w instanceof FigureWidget) { FigureWidget fw = (FigureWidget) w; if (fw.getState().isSelected()) { result.addAll(fw.getFigure().getSource().getSourceNodesAsSet()); } } } return result; } private UndoRedo.Manager getUndoRedoManager() { if (undoRedoManager == null) { undoRedoManager = new UndoRedo.Manager(); undoRedoManager.setLimit(UNDOREDO_LIMIT); } return undoRedoManager; } public UndoRedo getUndoRedo() { return getUndoRedoManager(); } private boolean isVisible(Figure f) { for (Integer n : f.getSource().getSourceNodesAsSet()) { if (getModel().getHiddenNodes().contains(n)) { return false; } } return true; } private boolean doesIntersect(Set s1, Set s2) { if (s1.size() > s2.size()) { Set tmp = s1; s1 = s2; s2 = tmp; } for (Object o : s1) { if (s2.contains(o)) { return true; } } return false; } public void showNot(final Set<Integer> nodes) { updateHiddenNodes(nodes, true); } public void showOnly(final Set<Integer> nodes) { HashSet<Integer> allNodes = new HashSet(getModel().getGraphToView().getGroup().getAllNodes()); allNodes.removeAll(nodes); updateHiddenNodes(allNodes, true); } private void updateHiddenNodes(Set<Integer> newHiddenNodes, boolean doRelayout) { Set<InputBlock> visibleBlocks = new HashSet(); Diagram diagram = getModel().getDiagramToView(); assert diagram != null; Set<Widget> oldVisibleWidgets = new HashSet(); for (Figure f : diagram.getFigures()) { FigureWidget w = figureWidgets.get(f); if (w.isVisible()) { oldVisibleWidgets.add(w); } } if (getModel().getShowBlocks()) { for (InputBlock b : diagram.getGraph().getBlocks()) { BlockWidget w = blockWidgets.get(b); if (w.isVisible()) { oldVisibleWidgets.add(w); } } } for (Figure f : diagram.getFigures()) { boolean hiddenAfter = doesIntersect(f.getSource().getSourceNodesAsSet(), newHiddenNodes); FigureWidget w = this.figureWidgets.get(f); w.setBoundary(false); if (!hiddenAfter) { // Figure is shown w.setVisible(true); for (InputNode n : f.getSource().getSourceNodes()) { visibleBlocks.add(diagram.getGraph().getBlock(n)); } } else { // Figure is hidden w.setVisible(false); } } if (getModel().getShowNodeHull()) { List<FigureWidget> boundaries = new ArrayList(); for (Figure f : diagram.getFigures()) { FigureWidget w = this.figureWidgets.get(f); if (!w.isVisible()) { Set<Figure> set = new HashSet
(f.getPredecessorSet()); set.addAll(f.getSuccessorSet()); boolean b = false; for (Figure neighbor : set) { FigureWidget neighborWidget = figureWidgets.get(neighbor); if (neighborWidget.isVisible()) { b = true; break; } } if (b) { w.setBoundary(true); for (InputNode n : f.getSource().getSourceNodes()) { visibleBlocks.add(diagram.getGraph().getBlock(n)); } boundaries.add(w); } } } for (FigureWidget w : boundaries) { if (w.isBoundary()) { w.setVisible(true); } } } if (getModel().getShowBlocks()) { for (InputBlock b : diagram.getGraph().getBlocks()) { boolean visibleAfter = visibleBlocks.contains(b); BlockWidget w = blockWidgets.get(b); if (visibleAfter) { // Block must be shown w.setVisible(true); } else { // Block must be hidden w.setVisible(false); } } } getModel().setHiddenNodes(newHiddenNodes); if (doRelayout) { relayout(oldVisibleWidgets); } this.validate(); addUndo(); } private void showFigures(Collection<Figure> f) { HashSet<Integer> newHiddenNodes = new HashSet(getModel().getHiddenNodes()); for (Figure fig : f) { newHiddenNodes.removeAll(fig.getSource().getSourceNodesAsSet()); } updateHiddenNodes(newHiddenNodes, true); } private void showFigure(Figure f) { HashSet<Integer> newHiddenNodes = new HashSet(getModel().getHiddenNodes()); newHiddenNodes.removeAll(f.getSource().getSourceNodesAsSet()); updateHiddenNodes(newHiddenNodes, true); } public void showAll(final Collection<Figure> f) { showFigures(f); } public void show(final Figure f) { showFigure(f); } public void gotoFigure(final Figure f) { if (!isVisible(f)) { showFigure(f); } FigureWidget fw = getFigureWidget(f); if (fw != null) { Rectangle r = fw.getBounds(); Point p = fw.getLocation(); centerRectangle(new Rectangle(p.x, p.y, r.width, r.height)); // Select figure clearSelection(); addToSelection(fw); selectionUpdated(); } } public JPopupMenu createPopupMenu() { JPopupMenu menu = new JPopupMenu(); for (Action a : actions) { if (a == null) { menu.addSeparator(); } else { menu.add(a); } } return menu; } private static class DiagramUndoRedo extends AbstractUndoableEdit implements ChangedListener<DiagramViewModel> { private DiagramViewModel oldModel; private DiagramViewModel newModel; private Point oldScrollPosition; private DiagramScene scene; public DiagramUndoRedo(DiagramScene scene, Point oldScrollPosition, DiagramViewModel oldModel, DiagramViewModel newModel) { assert oldModel != null; assert newModel != null; this.oldModel = oldModel; this.newModel = newModel; this.scene = scene; this.oldScrollPosition = oldScrollPosition; } @Override public void redo() throws CannotRedoException { super.redo(); boolean b = scene.getUndoRedoEnabled(); scene.setUndoRedoEnabled(false); scene.getModel().getViewChangedEvent().addListener(this); scene.getModel().setData(newModel); scene.getModel().getViewChangedEvent().removeListener(this); scene.setUndoRedoEnabled(b); } @Override public void undo() throws CannotUndoException { super.undo(); boolean b = scene.getUndoRedoEnabled(); scene.setUndoRedoEnabled(false); scene.getModel().getViewChangedEvent().addListener(this); scene.getModel().setData(oldModel); scene.getModel().getViewChangedEvent().removeListener(this); SwingUtilities.invokeLater(new Runnable() { public void run() { scene.setScrollPosition(oldScrollPosition); } }); scene.setUndoRedoEnabled(b); } public void changed(DiagramViewModel source) { scene.getModel().getViewChangedEvent().removeListener(this); if (oldModel.getSelectedNodes().equals(newModel.getHiddenNodes())) { scene.smallUpdate(false); } else { scene.smallUpdate(true); } } } private boolean undoRedoEnabled = true; public void setUndoRedoEnabled(boolean b) { this.undoRedoEnabled = b; } public boolean getUndoRedoEnabled() { return undoRedoEnabled; } public void changed(DiagramViewModel source) { assert source == model : "Receive only changed event from current model!"; assert source != null; update(); } private void addUndo() { DiagramViewModel newModelCopy = model.copy(); if (undoRedoEnabled) { this.getUndoRedoManager().undoableEditHappened(new UndoableEditEvent(this, new DiagramUndoRedo(this, this.getScrollPosition(), modelCopy, newModelCopy))); } this.modelCopy = newModelCopy; } }

Other Java examples (source code examples)

Here is a short list of links related to this Java DiagramScene.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.