graphpanel.java

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

JAVA
624
字号
/*
 Violet - A program for editing UML diagrams.

 Copyright (C) 2002 Cay S. Horstmann (http://horstmann.com)

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program 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 for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package com.horstmann.violet.framework;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Point2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JPanel;
import javax.swing.JOptionPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.ResourceBundle;
import java.util.Set;

/**
 * A panel to draw a graph
 */
public class GraphPanel extends JPanel
{
   /**
    * Constructs a graph.
    * @param aToolBar the tool bar with the node and edge tools
    */
   public GraphPanel(ToolBar aToolBar)
   {
      grid = new Grid();
      gridSize = GRID;
      grid.setGrid((int) gridSize, (int) gridSize);
      zoom = 1;
      toolBar = aToolBar;
      setBackground(Color.WHITE);

      selectedItems = new HashSet();
      
      addMouseListener(new MouseAdapter()
      {
         public void mousePressed(MouseEvent event)
         {
            requestFocus();
            final Point2D mousePoint = new Point2D.Double(event.getX() / zoom,
                  event.getY() / zoom);
            boolean isCtrl = (event.getModifiersEx() & InputEvent.CTRL_DOWN_MASK) != 0; 
            Node n = graph.findNode(mousePoint);
            Edge e = graph.findEdge(mousePoint);
            Object tool = toolBar.getSelectedTool();
            if (event.getClickCount() > 1
                  || (event.getModifiers() & InputEvent.BUTTON1_MASK) == 0)
            // double/right-click
            {
               if (e != null)
               {
                  setSelectedItem(e);
                  editSelected();
               }
               else if (n != null)
               {
                  setSelectedItem(n);
                  editSelected();
               }
               else
               {
                  toolBar.showPopup(GraphPanel.this, mousePoint,
                        new ActionListener()
                        {
                           public void actionPerformed(ActionEvent event)
                           {
                              Object tool = toolBar.getSelectedTool();
                              if (tool instanceof Node)
                              {
                                 Node prototype = (Node) tool;
                                 Node newNode = (Node) prototype.clone();
                                 boolean added = graph.add(newNode, mousePoint);
                                 if (added)
                                 {
                                    setModified(true);
                                    setSelectedItem(newNode);
                                 }
                              }
                           }
                        });
               }
            }
            else if (tool == null) // select
            {
               if (e != null)
               {
                  setSelectedItem(e);
               }
               else if (n != null)
               {
                  if (isCtrl)
                     addSelectedItem(n);
                  else if (!selectedItems.contains(n))
                     setSelectedItem(n);
                  dragMode = DRAG_MOVE;
               }
               else
               {
                  if (!isCtrl)
                     clearSelection();
                  dragMode = DRAG_LASSO;
               }
            }
            else if (tool instanceof Node)
            {
               Node prototype = (Node) tool;
               Node newNode = (Node) prototype.clone();
               boolean added = graph.add(newNode, mousePoint);
               if (added)
               {
                  setModified(true);
                  setSelectedItem(newNode);
                  dragMode = DRAG_MOVE;
               }
               else if (n != null)
               {
                  if (isCtrl)
                     addSelectedItem(n);
                  else if (!selectedItems.contains(n))
                     setSelectedItem(n);
                  dragMode = DRAG_MOVE;
               }
            }
            else if (tool instanceof Edge)
            {
               if (n != null) dragMode = DRAG_RUBBERBAND;
            }

            lastMousePoint = mousePoint;
            mouseDownPoint = mousePoint;
            repaint();
         }

         public void mouseReleased(MouseEvent event)
         {
            Point2D mousePoint = new Point2D.Double(event.getX() / zoom,
                  event.getY() / zoom);
            Object tool = toolBar.getSelectedTool();
            if (dragMode == DRAG_RUBBERBAND)
            {
               Edge prototype = (Edge) tool;
               Edge newEdge = (Edge) prototype.clone();
               if (mousePoint.distance(mouseDownPoint) > CONNECT_THRESHOLD
                     && graph.connect(newEdge, mouseDownPoint, mousePoint))
               {
                  setModified(true);
                  setSelectedItem(newEdge);
               }
            }
            else if (dragMode == DRAG_MOVE)
            {
               graph.layout();
               setModified(true);
            }
            dragMode = DRAG_NONE;

            revalidate();
            repaint();
         }
      });

      addMouseMotionListener(new MouseMotionAdapter()
      {
         public void mouseDragged(MouseEvent event)
         {
            Point2D mousePoint = new Point2D.Double(event.getX() / zoom, 
                  event.getY() / zoom);
            boolean isCtrl = (event.getModifiersEx() & InputEvent.CTRL_DOWN_MASK) != 0; 

            if (dragMode == DRAG_MOVE && lastSelected instanceof Node)
            {               
               Node lastNode = (Node) lastSelected;
               Rectangle2D bounds = lastNode.getBounds();
               double dx = mousePoint.getX() - lastMousePoint.getX();
               double dy = mousePoint.getY() - lastMousePoint.getY();
                            
               // we don't want to drag nodes into negative coordinates
               // particularly with multiple selection, we might never be 
               // able to get them back.
               Iterator iter = selectedItems.iterator();
               while (iter.hasNext())
               {
                  Object selected = iter.next();                 
                  if (selected instanceof Node)
                  {
                     Node n = (Node) selected;
                     bounds.add(n.getBounds());
                  }
               }
               dx = Math.max(dx, -bounds.getX());
               dy = Math.max(dy, -bounds.getY());
               
               iter = selectedItems.iterator();
               while (iter.hasNext())
               {
                  Object selected = iter.next();                 
                  if (selected instanceof Node)
                  {
                     Node n = (Node) selected;
                     n.translate(dx, dy);                           
                  }
               }
               // we don't want continuous layout any more because of multiple selection
               // graph.layout();
            }            
            else if (dragMode == DRAG_LASSO)
            {
               double x1 = mouseDownPoint.getX();
               double y1 = mouseDownPoint.getY();
               double x2 = mousePoint.getX();
               double y2 = mousePoint.getY();
               Rectangle2D.Double lasso = new Rectangle2D.Double(Math.min(x1, x2), 
                     Math.min(y1, y2), Math.abs(x1 - x2) , Math.abs(y1 - y2));
               Iterator iter = graph.getNodes().iterator();
               while (iter.hasNext())
               {
                  Node n = (Node) iter.next();
                  Rectangle2D bounds = n.getBounds();
                  if (!isCtrl && !lasso.contains(n.getBounds())) 
                  {
                     removeSelectedItem(n);
                  }
                  else if (lasso.contains(n.getBounds())) 
                  {
                     addSelectedItem(n);
                  }
               }
            }
            
            lastMousePoint = mousePoint;
            repaint();
         }
      });
   }

   /**
    * Edits the properties of the selected graph element.
    */
   public void editSelected()
   {
      Object edited = lastSelected;
      if (lastSelected == null)
      {
         if (selectedItems.size() == 1)
            edited = selectedItems.iterator().next();
         else
            return;
      }

      PropertySheet sheet = new PropertySheet(edited, this);
      sheet.addChangeListener(new ChangeListener()
      {
         public void stateChanged(ChangeEvent event)
         {
            graph.layout();
            repaint();
         }
      });
      JOptionPane.showInternalMessageDialog(this, sheet, 
            ResourceBundle.getBundle("com.horstmann.violet.framework.EditorStrings").getString("dialog.properties"),            
            JOptionPane.QUESTION_MESSAGE);
      setModified(true);
   }

   /**
    * Removes the selected nodes or edges.
    */
   public void removeSelected()
   {
      Iterator iter = selectedItems.iterator();
      while (iter.hasNext())
      {
         Object selected = iter.next();                 
         if (selected instanceof Node)
         {
            graph.removeNode((Node) selected);
         }
         else if (selected instanceof Edge)
         {

⌨️ 快捷键说明

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