//Copyright (c)2005 Holobloc Inc.
//Contributed to the OOONEIDA FBench project under the Common Public License.
//Copyright (c) 2007 University of Auckland
//Contributed to the FBench extension of the OOONEIDA Workbench project under the Common Public License
package fbench.graph;
import java.awt.Color;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import fbench.dom.events.ElementSelectionEvent;
import fbench.graph.popup.ContextMenu;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.events.Event;
import org.w3c.dom.events.MutationEvent;
/**
* A panel for displaying an Element of the DOM Tree of an IEC 61499 XML
* LibraryElement as a directed graph.
*
* @author JHC, JP
*
* @version 20070530/JP - GraphView extends ViewModel, most of the basic features have been
* taken to ViewModel.java for better extensibility
* @version 20070330/JP - Display FBNetwork of Resource element when the Resource is selected on tree
* @version 20051129/JHC - Inhibited re-drawing in handleEvent when
* MutationEvent comes from an Action (this is clumsy and will probably
* have to be fixed later).
* @version 20051109/JHC - All notifications now via DOM Event mechanism.
* @version 20050421/JHC
*/
public class GraphView extends ViewModel {
private Document document = null;
/**
*
*/
private static final long serialVersionUID = -2916266848521408112L;
/**
* Sets up a GraphView for an IEC 61499 LibraryElement and its graphical
* sub-elements contained in the specified DOM Document.
*/
public GraphView(Document doc) {
super();
setDocument(doc);
setLayout(new GraphLayout());
setOpaque(true);
setBackground(Color.white);
setFont(GraphView.DEFAULT_FONT);
JPanel dragPanel = new JPanel();
add(dragPanel, DRAG_LAYER);
addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent evt){
if(evt.getButton() == MouseEvent.BUTTON3) {
/**
* Resource is not a FBNetwork but it contains one so
* it is required to pass FBNetwork of Resource as an element
* when Resource is passed in.
*/
System.out.println("GraphView."+element.getNodeName());
Element fbNetworkElem = (Element) (element.getNodeName().equals("Resource")
? element.getFirstChild() : element);
if(fbNetworkElem != null){
String elementName = fbNetworkElem.getNodeName();
ContextMenu contextMenu = new ContextMenu(fbNetworkElem, evt);
contextMenu.create(elementName);
}
}
}
});
}
public void refresh(){
setElement(element);
}
public void rightClick(MouseEvent evt)
{
/**
* Resource is not a FBNetwork but it contains one so
* it is required to pass FBNetwork of Resource as an element
* when Resource is passed in.
*/
System.out.println("GraphView."+element.getNodeName());
Element fbNetworkElem = (Element) (element.getNodeName().equals("Resource")
? element.getFirstChild() : element);
String elementName = "";
try
{
elementName = fbNetworkElem.getNodeName();
}catch(Exception ex)
{
//ex.printStackTrace();
fbNetworkElem = element;
elementName = fbNetworkElem.getNodeName();
}
System.out.println("GraphView."+elementName);
ContextMenu contextMenu = new ContextMenu(fbNetworkElem, evt);
contextMenu.create(elementName);
}
public void handleEvent(Event evt) {
if (evt instanceof MutationEvent) {
Element mutel = (Element) ((MutationEvent) evt).getRelatedNode();
System.out.println("GraphView: "+mutel.getTagName());
if (!mutel.getTagName().equals("ECAction"))
setElement(element);
} else if (evt instanceof ElementSelectionEvent) {
ElementSelectionEvent selevt = (ElementSelectionEvent) evt;
switch (selevt.getDetail()) {
case ElementSelectionEvent.ACTIVATE: {
graphElementSelected(selevt.getSource());
return;
}
case ElementSelectionEvent.HYPERACTIVATE: {
setElement(selevt.getSelectedElement());
((JSplitPane)getParent().getParent().getParent()).validate();
}
}
}
}
public void redraw()
{
this.scrollRectToVisible( this.getVisibleRect() );
}
/**
* Does more than redraw... re-gets the element from the document with the same name
* Used after re-parse to return to last view (with updated view)
*
*/
public void renewElementView()
{
Element last = super.getElement();
Element docEl = document.getDocumentElement();
NodeList similarNodes = docEl.getElementsByTagName( last.getTagName() );
if( similarNodes.getLength() == 1 )
{
setElement( (Element)similarNodes.item(0) );
return;
}
else
{
String elName = last.getAttribute("Name");
if ( elName == null ) return;
for(int i = 0; i < similarNodes.getLength(); i++)
{
if( elName.equals(((Element)similarNodes.item(i)).getAttribute("Name")) )
{
setElement( (Element)similarNodes.item(i) );
return;
}
}
}
setElement( document.getDocumentElement() );
return;
}
public void centerViewPort(Point center)
{
Rectangle view = this.getVisibleRect();
// if center is the center then top x & y must be:
view.x = center.x - (view.width/2);
view.y = center.y - (view.height/2);
if( view.x < 0 ) view.x = 0;
if( view.y < 0 ) view.y = 0;
//System.out.println("[GV] " + view);
//((JViewport)this.getParent()).setScrollMode(JViewport.BACKINGSTORE_SCROLL_MODE);
this.scrollRectToVisible(view);
}
public void setDocument(Document doc)
{
if( document != null )
((org.w3c.dom.events.EventTarget) document).removeEventListener("ElementSelectionEvent", this, false);
document = doc;
((org.w3c.dom.events.EventTarget) document).addEventListener("ElementSelectionEvent", this, false);
}
}