// UML Model Transformation Tool (UMT)
// Copyright (C) 2003, 2004, 2005 SINTEF
// Authors: jon.oldevik at sintef.no | roy.gronmo at sintef.no | tor.neple at sintef.no | fredrik.vraalsen at sintef.no
// Webpage: http://umt.sourceforge.net
// Deloped in the projects: ACEGIS (EU project - IST-2002-37724),
// CAFE (EUREKA/ITEA - ip00004), FAMILIES (ITEA project ip02009)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation; either version 2.1
// 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser 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 org.sintef.umt.hutntree;
/**
* @author Jon Oldevik, (jon.oldevik@sintef.no)
* @copyright (c) SINTEF 2002 (www.sintef.no)
*
*/
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.io.StringWriter;
import java.util.*;
import javax.swing.tree.*;
import org.sintef.umt.propertyeditor.PropertyGroup;
import org.sintef.umt.propertyeditor.PropertyManager;
import org.sintef.umt.umtmain.UMTMain;
import org.w3c.dom.*;
import java.util.Hashtable;
public class HutnTreeView extends JTree implements TreeSelectionListener, Runnable
{
private HutnModelListener _modellistener;
protected final String _actionsfile = org.sintef.umt.umtmain.UMTMain.config_dir + "actions.xml";
protected PropertyManager _actionPropertyMgr;
protected volatile boolean _isLoading, _indicator, _isTransforming;
protected int _loadingCount = 0;
private int tmp_x, tmp_y;
protected Hashtable _elements;
protected boolean _hasmodelelements = false;
protected UMTMain _umtmain;
public HutnTreeView (HutnModelListener listener)
{
super ();
_modellistener = listener;
setShowsRootHandles (true);
setRootVisible(false);
setScrollsOnExpand(true);
addTreeSelectionListener (this);
_actionPropertyMgr = new PropertyManager (_actionsfile);
ToolTipManager ttmanager = ToolTipManager.sharedInstance ();
ttmanager.registerComponent(this);
_elements = new Hashtable ();
HutnTreeMouseAdapter htma = new HutnTreeMouseAdapter ();
addMouseListener (htma);
init ();
}
/**
* Clears all children from the tree
*
*/
public void clear () {
((DefaultMutableTreeNode)getModel().getRoot()).removeAllChildren();
((DefaultTreeModel)getModel()).reload();
}
protected void init () {
setModel (new HutnTreeModel ("root"));
setCellRenderer (new HutnTreeCellRenderer (this));
}
public void setUMTMain (UMTMain umtmain) {
_umtmain = umtmain;
}
public String getNameForID (String id) {
return (String) _elements.get(id);
}
protected void addNameWithID (String name, String id) {
if (name != null && id != null)
_elements.put(id, name);
}
protected void removeNameWithID (String id) {
_elements.remove(id);
}
public synchronized String getTreeBuffer () {
StringWriter writer = new StringWriter ();
return writer.toString();
}
public boolean hasModelElements () {
return _hasmodelelements;
}
/**
* Appends modelelements to already existing structure...
* @param modelelements
*/
public void addModelElements (Collection modelelements) {
_hasmodelelements = true;
_elements.clear();
clear();
Iterator elements = modelelements.iterator ();
DefaultMutableTreeNode root = (DefaultMutableTreeNode)((HutnTreeModel)getModel()).getRoot();
DefaultMutableTreeNode datatypechild = new DefaultMutableTreeNode ("Datatypes");
boolean has_datatypes = false;
while (elements.hasNext()) {
Object obj = elements.next();
Node element = (Node)obj;
if (element.getNodeType() == Node.ELEMENT_NODE) {
addModelElement (element, (DefaultMutableTreeNode)root);
}
}
TreeNode[] path = root.getPath();
// TreePath treepath = new TreePath (path);
// makeVisible(treepath);
root.setAllowsChildren(true);
for (int i = 0; i < root.getChildCount (); i++) {
TreeNode child = root.getChildAt(i);
path = ((DefaultMutableTreeNode)child).getPath();
makeVisible (new TreePath (path));
}
}
public Element getModelRoot () {
DefaultMutableTreeNode root = (DefaultMutableTreeNode)((HutnTreeModel)getModel()).getRoot();
if (root.getChildCount() > 0) {
DefaultMutableTreeNode child = (DefaultMutableTreeNode)((DefaultMutableTreeNode) root.getFirstChild());
Object userobject = child.getUserObject();
if (userobject instanceof Element) {
return (Element)userobject;
}
}
return null;
}
/*
public void setModelElements (Collection modelelements)
{
_hasmodelelements = true;
_elements.clear();
addModelElements (modelelements);
}
*/
public DefaultMutableTreeNode addModelElement (Object modelelement, DefaultMutableTreeNode treeparent){
Element e = (Element) modelelement;
String name = e.getAttribute("name"); String id = e.getAttribute("id");
addNameWithID(name, id);
NodeList children = e.getChildNodes ();
DefaultMutableTreeNode treechild = null;
if (e.getParentNode().getNodeType() == Node.DOCUMENT_NODE && (name.equals(""))) {
treechild = treeparent;
} else {
treechild = new DefaultMutableTreeNode (e);
treeparent.add (treechild);
}
for (int i = 0; i < children.getLength(); i++){
Node n = children.item(i);
if (n.getNodeType () == org.w3c.dom.Node.ELEMENT_NODE && !n.getNodeName().equalsIgnoreCase("datatype") && !n.getNodeName().equalsIgnoreCase("uses")) {
if (!(n.getNodeName().equalsIgnoreCase("taggedValue"))) /* SKIP TAGS FOR NOW */
addModelElement (n, treechild);
}
}
/*
* Adds datatypes to a package in a separate 'folder'
* */
if (e.getNodeName().equalsIgnoreCase("package")) {
NodeList childnodes = e.getChildNodes();
int count = 0;
DefaultMutableTreeNode datatypechild = new DefaultMutableTreeNode ("Datatypes");
for (int i = 0; i < childnodes.getLength(); i++) {
Node childnode = childnodes.item(i);
if (childnode.getNodeType () == org.w3c.dom.Node.ELEMENT_NODE && childnode.getNodeName().equalsIgnoreCase("datatype")) {
addNameWithID(((Element)childnode).getAttribute("name"), ((Element)childnode).getAttribute("id"));
datatypechild.add(new DefaultMutableTreeNode(childnode));
count++;
}
}
if (count > 0) {
treechild.add(datatypechild);
}
DefaultMutableTreeNode useschild = new DefaultMutableTreeNode ("uses");
for (int i = 0; i < childnodes.getLength(); i++) {
Node childnode = childnodes.item(i);
if (childnode.getNodeType () == org.w3c.dom.Node.ELEMENT_NODE && childnode.getNodeName().equalsIgnoreCase("uses")) {
useschild.add(new DefaultMutableTreeNode(childnode));
count++;
}
}
if (count > 0) {
treechild.add(useschild);
}
}
return treechild;
}
public void valueChanged (TreeSelectionEvent tse){
// TreePath path = tse.getPath ();
try{
// userobj = ((DefaultMutableTreeNode)node).getUserObject ();
// System.out.println (userobj.getClass().getName ());
} catch (Exception ex){
System.out.println (ex);
}
// System.out.println ("Selected");
}
public void setLoading (boolean loading) {
_isLoading = loading;
if (_isLoading) {
Thread loadingThread = new Thread(this);
loadingThread.start();
_isLoading = loading;
}
}
public void setTransforming (boolean transforming) {
_isTransforming = transforming;
if(_isTransforming) {
Thread transformThread = new Thread (this, "transformation");
transformThread.start();
}
}
public void paintComponent (Graphics g) {
super.paintComponent (g);
if (_isLoading || _isTransforming) {
if (_loadingCount == 4) _loadingCount = 0;
ImageIcon image = new ImageIcon (UMTMain.img_dir + "loading" + ++_loadingCount + ".gif");
g.drawImage(image.getImage(), 50,150, null);
}
}
/*
* OLD Painter
public void paintComponent (Graphics g) {
super.paintComponent (g);
// System.out.println ("repaint " + _isLoading + " " + _indicator);
if (_isLoading && _indicator) {
g.setColor(Color.blue);
g.setFont(new Font("Sans Serif", Font.ITALIC, 16));
g.drawString("loading model", 50,150);
} else if (_isTransforming && _indicator) {
g.setColor(Color.blue);
g.setFont(new Font("Sans Serif", Font.BOLD, 18));
g.drawString("Transforming ....", 50, 150);
}
paintSelection (g);
_indicator = !_indicator;
}
*/
private void paintSelection (Graphics g) {
TreePath selPath = getSelectionPath();
if (tmp_x > 0 && tmp_y > 0) {
if (selPath != null) {
Object path = selPath.getLastPathComponent ();
Object userobj = ((DefaultMutableTreeNode)path).getUserObject ();
if (userobj instanceof Element) {
Element e = (Element) userobj;
String nodename = e.getNodeName ();
String name = e.getAttribute ("name");
String stereotype = e.getAttribute ("stereoType");
String superclass = e.getAttribute ("superClass");
DefaultMutableTreeNode p;
/* if (superclass != null && !superclass.equals("")) {
g.drawLine(tmp_x, tmp_y, tmp_x + 50, tmp_y);
}
*/
}
}
}
}
public void run () {
while (_isLoading || _isTransforming) {
try {
Thread.sleep(120);
repaint ();
} catch (Exception ex) {
}
}
this._umtmain.repaint();
}
protected class HutnTreeModel extends DefaultTreeModel
{
public HutnTreeModel (String rootTitle)
{
super (new DefaultMutableTreeNode (rootTitle));
}
}
private class HutnTreeMouseAdapter extends MouseAdapter implements ActionListener {
public HutnTreeMouseAdapter (){
}
public void mouseClicked (MouseEvent me){
TreePath selPath = HutnTreeView.this.getPathForLocation(me.getX(), me.getY());
tmp_x = me.getX(); tmp_y = me.getY();
if (selPath != null){
HutnTreeView.this.setSelectionPath(selPath);
Object path = selPath.getLastPathComponent ();
Object userobj = ((DefaultMutableTreeNode)path).getUserObject ();
repaint ();
if (userobj instanceof Node)
_modellistener.viewChanged ("", (Node)userobj);
if (me.isMetaDown ()){
if (userobj instanceof Element){
Element e = (Element)userobj;
// raise appropriate menu
String nodename = e.getNodeName ();
String stereotype = e.getAttribute ("stereoType");
raiseMenuForNode (nodename, stereotype, me.getX(), me.getY());
} else {
// default action
}
} else if (me.getClickCount() == 2) {
}
}
}
private void raiseMenuForNode (String nodename, String stereotype, int posx, int posy){
JPopupMenu pop = new JPopupMenu ();
if (stereotype == null) stereotype = "";
_actionPropertyMgr.reload();
Iterator groups = _actionPropertyMgr.getSubgroupsForStereotypedItem (nodename, stereotype);
while (groups.hasNext()) {
PropertyGroup group = (PropertyGroup)groups.next();
Map props = group.getProperties();
JMenu menu = new JMenu (group.getName());
pop.add (menu);
for (Iterator it = props.keySet().iterator ();it.hasNext ();){
String name = (String) it.next ();
String value = ((String[]) props.get(name))[0];
// System.out.println ("property: " + name + "=" + value);
JMenuItem item = new JMenuItem (name);
item.setActionCommand (!value.equals("")?value:name);
item.addActionListener (this);
menu.add (item);
}
// Add Transformations to menu
}
TreePath path = getSelectionPath ();
Object node = path.getLastPathComponent ();
Element context = (Element)((DefaultMutableTreeNode)node).getUserObject ();
JMenu transformations = new JMenu ("Transformations");
transformations.setMnemonic('T');
pop.add(transformations);
_umtmain.setTransformationItemsForMenu(transformations, context, "forward");
pop.show (HutnTreeView.this, posx, posy);
}
public void actionPerformed (ActionEvent ae){
((JMenuItem)ae.getSource()).getParent().setVisible (false);
String action = ae.getActionCommand ();
try {
TreePath path = getSelectionPath ();
Object node = path.getLastPathComponent ();
Element userobj = (Element)((DefaultMutableTreeNode)node).getUserObject ();
// String name = userobj.getAttribute ("name");
// String stereotype = userobj.getAttribute("stereoType");
// System.out.println ("Action on node: " + action + " - " + stereotype + " " + name);
int pindex = action.indexOf ("=");
String property, value;
if (pindex > 0) {
property = action.substring(0, pindex);
value = action.substring(pindex + 1, action.length());
} else {
property = action;
value = "true";
}
userobj.setAttribute (property, value);
revalidate ();
repaint ();
} catch (Exception ex) {
ex.printStackTrace ();
}
}
}
}