graphpanel.java

来自「用java实现UML建模,由高手编写..适合有一定能力的java程序员学习」· Java 代码 · 共 624 行 · 第 1/2 页

JAVA
624
字号
            graph.removeEdge((Edge) selected);
         }
      }
      if (selectedItems.size() > 0) setModified(true);
      repaint();
   }

   /**
    * Set the graph in the panel
    * @param aGraph the graph to be displayed and edited
    */
   public void setGraph(Graph aGraph)
   {
      graph = aGraph;
      setModified(false);
      revalidate();
      repaint();
   }

   public void paintComponent(Graphics g)
   {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g;
      g2.scale(zoom, zoom);
      Rectangle2D bounds = getBounds();
      Rectangle2D graphBounds = graph.getBounds(g2);
      if (!hideGrid) grid.draw(g2, new Rectangle2D.Double(0, 0, 
            Math.max(bounds.getMaxX() / zoom, graphBounds.getMaxX()), 
            Math.max(bounds.getMaxY() / zoom, graphBounds.getMaxY())));
      graph.draw(g2, grid);

      Iterator iter = selectedItems.iterator();
      Set toBeRemoved = new HashSet();
      while (iter.hasNext())
      {
         Object selected = iter.next();                 
      
         if (!graph.getNodes().contains(selected)
               && !graph.getEdges().contains(selected)) 
         {
            toBeRemoved.add(selected);
         }
         else if (selected instanceof Node)
         {
            Rectangle2D grabberBounds = ((Node) selected).getBounds();
            drawGrabber(g2, grabberBounds.getMinX(), grabberBounds.getMinY());
            drawGrabber(g2, grabberBounds.getMinX(), grabberBounds.getMaxY());
            drawGrabber(g2, grabberBounds.getMaxX(), grabberBounds.getMinY());
            drawGrabber(g2, grabberBounds.getMaxX(), grabberBounds.getMaxY());
         }
         else if (selected instanceof Edge)
         {
            Line2D line = ((Edge) selected).getConnectionPoints();
            drawGrabber(g2, line.getX1(), line.getY1());
            drawGrabber(g2, line.getX2(), line.getY2());
         }
      }

      iter = toBeRemoved.iterator();
      while (iter.hasNext())      
         removeSelectedItem(iter.next());                 
      
      if (dragMode == DRAG_RUBBERBAND)
      {
         Color oldColor = g2.getColor();
         g2.setColor(PURPLE);
         g2.draw(new Line2D.Double(mouseDownPoint, lastMousePoint));
         g2.setColor(oldColor);
      }      
      else if (dragMode == DRAG_LASSO)
      {
         Color oldColor = g2.getColor();
         g2.setColor(PURPLE);
         double x1 = mouseDownPoint.getX();
         double y1 = mouseDownPoint.getY();
         double x2 = lastMousePoint.getX();
         double y2 = lastMousePoint.getY();
         Rectangle2D.Double lasso = new Rectangle2D.Double(Math.min(x1, x2), 
               Math.min(y1, y2), Math.abs(x1 - x2) , Math.abs(y1 - y2));
         g2.draw(lasso);
         g2.setColor(oldColor);
      }      
   }

   /**
    * Draws a single "grabber", a filled square
    * @param g2 the graphics context
    * @param x the x coordinate of the center of the grabber
    * @param y the y coordinate of the center of the grabber
    */
   public static void drawGrabber(Graphics2D g2, double x, double y)
   {
      final int SIZE = 5;
      Color oldColor = g2.getColor();
      g2.setColor(PURPLE);
      g2.fill(new Rectangle2D.Double(x - SIZE / 2, y - SIZE / 2, SIZE, SIZE));
      g2.setColor(oldColor);
   }

   public Dimension getPreferredSize()
   {
      Rectangle2D bounds = graph.getBounds((Graphics2D) getGraphics());
      return new Dimension((int) (zoom * bounds.getMaxX()),
            (int) (zoom * bounds.getMaxY()));
   }

   /**
    * Changes the zoom of this panel. The zoom is 1 by default and is multiplied
    * by sqrt(2) for each positive stem or divided by sqrt(2) for each negative
    * step.
    * @param steps the number of steps by which to change the zoom. A positive
    * value zooms in, a negative value zooms out.
    */
   public void changeZoom(int steps)
   {
      final double FACTOR = Math.sqrt(2);
      for (int i = 1; i <= steps; i++)
         zoom *= FACTOR;
      for (int i = 1; i <= -steps; i++)
         zoom /= FACTOR;
      revalidate();
      repaint();
   }

   /**
    * Changes the grid size of this panel. The zoom is 10 by default and is
    * multiplied by sqrt(2) for each positive stem or divided by sqrt(2) for
    * each negative step.
    * @param steps the number of steps by which to change the zoom. A positive
    * value zooms in, a negative value zooms out.
    */
   public void changeGridSize(int steps)
   {
      final double FACTOR = Math.sqrt(2);
      for (int i = 1; i <= steps; i++)
         gridSize *= FACTOR;
      for (int i = 1; i <= -steps; i++)
         gridSize /= FACTOR;
      grid.setGrid((int) gridSize, (int) gridSize);
      graph.layout();
      repaint();
   }

   public void selectNext(int n)
   {
      ArrayList selectables = new ArrayList();
      selectables.addAll(graph.getNodes());
      selectables.addAll(graph.getEdges());
      if (selectables.size() == 0) return;
      java.util.Collections.sort(selectables, new java.util.Comparator()
      {
         public int compare(Object obj1, Object obj2)
         {
            double x1;
            double y1;
            if (obj1 instanceof Node)
            {
               Rectangle2D bounds = ((Node) obj1).getBounds();
               x1 = bounds.getX();
               y1 = bounds.getY();
            }
            else
            {
               Point2D start = ((Edge) obj1).getConnectionPoints().getP1();
               x1 = start.getX();
               y1 = start.getY();
            }
            double x2;
            double y2;
            if (obj2 instanceof Node)
            {
               Rectangle2D bounds = ((Node) obj2).getBounds();
               x2 = bounds.getX();
               y2 = bounds.getY();
            }
            else
            {
               Point2D start = ((Edge) obj2).getConnectionPoints().getP1();
               x2 = start.getX();
               y2 = start.getY();
            }
            if (y1 < y2) return -1;
            if (y1 > y2) return 1;
            if (x1 < x2) return -1;
            if (x1 > x2) return 1;
            return 0;
         }
      });
      int index;
      if (lastSelected == null) index = 0;
      else index = selectables.indexOf(lastSelected) + n;
      while (index < 0)
         index += selectables.size();
      index %= selectables.size();
      setSelectedItem(selectables.get(index));
      repaint();
   }

   /**
    * Checks whether this graph has been modified since it was last saved.
    * @return true if the graph has been modified
    */
   public boolean isModified()
   {
      return modified;
   }

   /**
    * Sets or resets the modified flag for this graph
    * @param newValue true to indicate that the graph has been modified
    */
   public void setModified(boolean newValue)
   {
      modified = newValue;

      if (frame == null)
      {
         Component parent = this;
         do
         {
            parent = parent.getParent();
         }
         while (parent != null && !(parent instanceof GraphFrame));
         if (parent != null) frame = (GraphFrame) parent;
      }
      if (frame != null)
      {
         String title = frame.getFileName();
         if (title != null)
         {
            if (modified)
            {
               if (!frame.getTitle().endsWith("*")) frame.setTitle(title + "*");
            }
            else frame.setTitle(title);
         }
      }
   }

   private void addSelectedItem(Object obj)
   {
      lastSelected = obj;      
      selectedItems.add(obj);
   }
   
   private void removeSelectedItem(Object obj)
   {
      if (obj == lastSelected)
         lastSelected = null;
      selectedItems.remove(obj);
   }
   
   private void setSelectedItem(Object obj)
   {
      selectedItems.clear();
      lastSelected = obj;
      if (obj != null) selectedItems.add(obj);
   }
   
   private void clearSelection()
   {
      selectedItems.clear();
      lastSelected = null;
   }
   
   /**
    * Sets the value of the hideGrid property
    * @param newValue true if the grid is being hidden
    */
   public void setHideGrid(boolean newValue)
   {
      hideGrid = newValue;
      repaint();
   }

   /**
    * Gets the value of the hideGrid property
    * @return true if the grid is being hidden
    */
   public boolean getHideGrid()
   {
      return hideGrid;
   }

   private Graph graph;
   private Grid grid;
   private GraphFrame frame;
   private ToolBar toolBar;

   private double zoom;
   private double gridSize;
   private boolean hideGrid;
   private boolean modified;

   private Object lastSelected;
   private Set selectedItems;

   private Point2D lastMousePoint;
   private Point2D mouseDownPoint;   
   private int dragMode;
      
   private static final int DRAG_NONE = 0;
   private static final int DRAG_MOVE = 1;
   private static final int DRAG_RUBBERBAND = 2;
   private static final int DRAG_LASSO = 3;
   
   private static final int GRID = 10;

   private static final int CONNECT_THRESHOLD = 8;

   private static final Color PURPLE = new Color(0.7f, 0.4f, 0.7f);
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?