⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 newclassdiagram.java

📁 UML设计测试工具
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * USE - UML based specification environment
 * Copyright (C) 1999-2004 Mark Richters, University of Bremen
 *
 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/* $ProjectHeader: use 2-3-0-release.1 Mon, 12 Sep 2005 20:18:33 +0200 green $ */

package org.tzi.use.gui.views.diagrams.classdiagram;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.swing.JCheckBoxMenuItem;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JSeparator;

import org.tzi.use.graph.DirectedGraphBase;
import org.tzi.use.gui.util.Selection;
import org.tzi.use.gui.views.diagrams.BinaryEdge;
import org.tzi.use.gui.views.diagrams.DiagramView;
import org.tzi.use.gui.views.diagrams.DiamondNode;
import org.tzi.use.gui.views.diagrams.EdgeBase;
import org.tzi.use.gui.views.diagrams.GeneralizationEdge;
import org.tzi.use.gui.views.diagrams.HalfEdge;
import org.tzi.use.gui.views.diagrams.LayoutInfos;
import org.tzi.use.gui.views.diagrams.NodeBase;
import org.tzi.use.gui.views.diagrams.NodeEdge;
import org.tzi.use.gui.views.diagrams.PlaceableNode;
import org.tzi.use.gui.views.diagrams.event.ActionLoadLayout;
import org.tzi.use.gui.views.diagrams.event.ActionSaveLayout;
import org.tzi.use.gui.views.diagrams.event.DiagramMouseHandling;
import org.tzi.use.gui.views.diagrams.event.HideAdministration;
import org.tzi.use.gui.views.diagrams.event.HighlightChangeEvent;
import org.tzi.use.gui.views.diagrams.event.HighlightChangeListener;
import org.tzi.use.uml.mm.MAssociation;
import org.tzi.use.uml.mm.MAssociationClass;
import org.tzi.use.uml.mm.MAssociationEnd;
import org.tzi.use.uml.mm.MClass;
import org.tzi.use.uml.mm.MGeneralization;
import org.tzi.use.uml.mm.MModelElement;
import org.tzi.use.uml.ocl.type.EnumType;

/**
 * A panel drawing UML class diagrams.
 * 
 * @version $ProjectVersion: 2-3-0-release.1 $
 * @author Fabian Gutsche
 */
public class NewClassDiagram extends DiagramView 
                             implements HighlightChangeListener {

    private NewClassDiagramView fParent;
    private Map fClassToNodeMap; // (MClass -> ClassNode)
    private Map fEnumToNodeMap; // (EnumType -> EnumNode)
    private Map fBinaryAssocToEdgeMap; // (MAssociation -> BinaryAssocEdge)
    private Map fAssocClassToEdgeMap; // (MAssociationClass -> ClassNode)
    private Map fNaryAssocToDiamondNodeMap; // (MAssociation -> DiamondNode)
    private Map fNaryAssocToHalfEdgeMap; // (MAssociation -> List(HalfEdge))
    private Map fGenToGeneralizationEdge; // (MGeneralization -> GeneralizationEdge)
        
    NewClassDiagram( NewClassDiagramView parent, PrintWriter log ) {
        fOpt = new ClsDiagramOptions();
        fGraph = new DirectedGraphBase();
        fClassToNodeMap = new HashMap();
        fEnumToNodeMap = new HashMap();
        fBinaryAssocToEdgeMap = new HashMap();
        fAssocClassToEdgeMap = new HashMap();
        fNaryAssocToDiamondNodeMap = new HashMap();
        fNaryAssocToHalfEdgeMap = new HashMap();
        fGenToGeneralizationEdge = new HashMap();
        fParent = parent;
        fHiddenNodes = new HashSet();
        fHiddenEdges = new HashSet();
        fNodeSelection = new Selection();
        fEdgeSelection = new Selection();
        setLayout( null );
        setBackground( Color.white );
        fLog = log;
        setPreferredSize( new Dimension( 400, 400 ) );
        
        fLayoutInfos = new LayoutInfos( fBinaryAssocToEdgeMap, 
                                        fClassToNodeMap, 
                                        fNaryAssocToDiamondNodeMap,
                                        fNaryAssocToHalfEdgeMap,
                                        fAssocClassToEdgeMap,
                                        fEnumToNodeMap,
                                        fGenToGeneralizationEdge,
                                        fHiddenNodes, fHiddenEdges,
                                        fOpt, fParent.system(), this );
        
        fHideAdmin = new HideAdministration( fNodeSelection, fGraph, fLayoutInfos );
        
        fActionSaveLayout = new ActionSaveLayout( "USE class diagram layout",
                                                  "clt", fGraph, fLog, fLayoutInfos );
        
        fActionLoadLayout = new ActionLoadLayout( "USE class diagram layout",
                                                  "clt", this, fLog,
                                                  fHideAdmin, fGraph,
                                                  fLayoutInfos );
        
        DiagramMouseHandling mouseHandling = 
            new DiagramMouseHandling( fNodeSelection, fEdgeSelection,
                                      fGraph, fHideAdmin, fHiddenNodes, 
                                      fOpt, this);
        addMouseListener( mouseHandling );
        
        fParent.getModelBrowser().addHighlightChangeListener( this );
        
        addComponentListener( new ComponentAdapter() {
            public void componentResized( ComponentEvent e ) {
                // need a new layouter to adapt to new window size
                fLayouter = null;
            }
        } );
        startLayoutThread();
    }

    /**
     * Displays the selected class of the modelbrowser in the class diagram.
     */
    public void stateChanged( HighlightChangeEvent e ) {
        if ( !fParent.isSelectedView() ) {
            return;
        }
        
        MModelElement elem = e.getModelElement();
        List edges = new ArrayList();
        boolean allEdgesSelected = true;
        
        // elem is an association
        if ( elem != null && elem instanceof MAssociation ) {
            int size = ((MAssociation) elem).associationEnds().size();
            EdgeBase eb = null;
            if ( size == 2 ) {
                    eb = (EdgeBase) fBinaryAssocToEdgeMap.get( (MAssociation) elem );
                if ( elem instanceof MAssociationClass ) {
                    eb = (EdgeBase) fAssocClassToEdgeMap.get( (MAssociationClass) elem );
                }
                edges.add( eb );
            } else {
                List halfEdges = 
                    (List) fNaryAssocToHalfEdgeMap.get( (MAssociation) elem );
                if ( edges != null && halfEdges != null ) {
                    edges.addAll( halfEdges );
                }
                if ( elem instanceof MAssociationClass ) {
                    eb = (EdgeBase) fAssocClassToEdgeMap.get( (MAssociationClass) elem );
                    if ( !edges.contains( eb ) ) {
                        edges.add( eb );
                    }
                }
            }
            
            // check all edges in the list if they are suppose to be selected 
            // or deselected.
            Iterator it = edges.iterator();
            while ( it.hasNext() ) {
                EdgeBase edge = (EdgeBase) it.next();
                if ( edge != null ) {
                    if ( fEdgeSelection.isSelected( edge ) ) {
                        fEdgeSelection.remove( edge );
                        allEdgesSelected = true;
                    } else {
                        fEdgeSelection.add( edge );
                        allEdgesSelected = false;
                    }  
                }    
            }
        }
        
        // elem is a class
        if ( elem != null && elem instanceof MClass ) {
            NodeBase node = (NodeBase) fClassToNodeMap.get( (MClass) elem );
            if ( node != null ) {
                if ( elem instanceof MAssociationClass ) {
                    if ( fNodeSelection.isSelected( node ) && allEdgesSelected ) {
                        fNodeSelection.remove( node );
                    } else {
                        fNodeSelection.add( node );
                    }  
                } else {
                    if ( fNodeSelection.isSelected( node ) ) {
                        fNodeSelection.remove( node );
                    } else {
                        fNodeSelection.add( node );
                    }
                }
            }
        }
                
        repaint();
    }
    
    /**
     * Determinds if the auto layout of the diagram is on or off.
     * @return <code>true</code> if the auto layout is on, otherwise
     * <code>false</code>
     */
    public boolean isDoAutoLayout() {
        return fOpt.isDoAutoLayout();
    }

    /**
     * Draws the diagram.
     */
    public void paintComponent( Graphics g ) {
        synchronized ( fLock ) {
            Font f = Font.getFont( "use.gui.view.objectdiagram", getFont() );
            g.setFont( f );
            drawDiagram( g );
        }
    }

    /**
     * Adds a class to the diagram.
     * 
     * @param cls Class to be added.
     */
    public void addClass( MClass cls ) {
        // Find a random new position. getWidth and getheight return 0
        // if we are called on a new diagram.
        double fNextNodeX = Math.random() * Math.max( 100, getWidth() );
        double fNextNodeY = Math.random() * Math.max( 100, getHeight() );
        ClassNode n = new ClassNode( cls, fOpt );
        n.setPosition( fNextNodeX, fNextNodeY );

        synchronized ( fLock ) {
            fGraph.add( n );
            fClassToNodeMap.put( cls, n );
            fLayouter = null;
        }
    }

    /**
     * Deletes a class from the diagram.
     */
    public void deleteClass( MClass cls ) {
        NodeBase n = (NodeBase) fClassToNodeMap.get( cls );
        if (n == null) {
            if ( fHiddenNodes.contains( cls ) ) {
                fHiddenNodes.remove( cls );
                fLog.println("Deleted class `" + cls.name()
                             + "' from the hidden classes.");
            } else {
                throw new RuntimeException("no node for class `" 
                                           + cls.name() + "' in current state.");
            }
        }

        synchronized ( fLock ) {
            fGraph.remove( n );
            fClassToNodeMap.remove( cls );
            fLayouter = null;
        }
    }
    
    /**
     * Adds an enumeration to the diagram.
     * 
     * @param enumeration Enumeration to be added.
     */
    public void addEnum( EnumType enumeration ) {
        // Find a random new position. getWidth and getheight return 0
        // if we are called on a new diagram.
        double fNextNodeX = Math.random() * Math.max( 100, getWidth() );
        double fNextNodeY = Math.random() * Math.max( 100, getHeight() );
        EnumNode n = new EnumNode( enumeration, fOpt );
        n.setPosition( fNextNodeX, fNextNodeY );

        synchronized ( fLock ) {
            fGraph.add( n );
            fEnumToNodeMap.put( enumeration, n );
            fLayouter = null;
        }
    }

    /**
     * Deletes an enumeration from the diagram.
     */
    public void deleteEnum( EnumType enumeration ) {
        NodeBase n = (NodeBase) fEnumToNodeMap.get( enumeration );
        if (n == null) {
            if ( fHiddenNodes.contains( enumeration ) ) {
                fHiddenNodes.remove( enumeration );
                fLog.println("Deleted enumeration `" + enumeration.name()
                             + "' from the hidden enumerations.");
            } else {
                throw new RuntimeException("no node for enumeration `" 
                                           + enumeration.name() 
                                           + "' in current state.");
            }
        }

        synchronized ( fLock ) {
            fGraph.remove( n );
            fEnumToNodeMap.remove( enumeration );
            fLayouter = null;
        }
    }
    
    /**
     * Adds an association to the diagram.
     */
    public void addAssociation( MAssociation assoc ) {
        String label = assoc.name();
        
        Iterator assocEndIter = assoc.associationEnds().iterator();
        MAssociationEnd assocEnd1 = (MAssociationEnd) assocEndIter.next();
        MAssociationEnd assocEnd2 = (MAssociationEnd) assocEndIter.next();
        MClass cls1 = assocEnd1.cls();
        MClass cls2 = assocEnd2.cls();

⌨️ 快捷键说明

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