/*
* NanoGraph, a small footprint java graph drawing component
*
* Copyright (C) 2004 Jeroen van Grondelle
*
* This library 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 library 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 library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You can contact the author at jeroen@nanoworks.nl.
*
*/
package nl.nanoworks.nanograph;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.util.HashMap;
import javax.swing.JPanel;
import nl.nanoworks.nanograph.layout.LayoutAlgorithm;
import nl.nanoworks.nanograph.model.GraphModel;
import nl.nanoworks.nanograph.renderer.ArrowEdgeRenderer;
import nl.nanoworks.nanograph.renderer.DefaultNodeRenderer;
import nl.nanoworks.nanograph.renderer.EdgeRenderer;
import nl.nanoworks.nanograph.renderer.NodeRenderer;
import nl.nanoworks.nanograph.selection.Selection;
import nl.nanoworks.nanograph.selection.SelectionManager;
/**
* NanoGraph.java
*
* @author Jeroen van Grondelle
*/
public class NanoGraph extends JPanel implements Printable
{
GraphModel graph = null;
LayoutAlgorithm layoutAlgorithm = null;
Image logo = null;
NodeRenderer defaultNodeRenderer = new DefaultNodeRenderer();
HashMap nodeRenderers = new HashMap();
EdgeRenderer defaultEdgeRenderer = new ArrowEdgeRenderer();
public NanoGraph()
{
SelectionMouseListener sml = new SelectionMouseListener();
this.addMouseListener(sml);
this.addMouseMotionListener(sml);
}
public NanoGraph(Image logo)
{
this();
this.logo = logo;
}
public void setGraph(GraphModel graph)
{
this.graph = graph;
if(layoutAlgorithm != null)
{
layoutAlgorithm.layout(graph);
}
manager.setModel(graph);
}
public void setLayout(LayoutAlgorithm layout)
{
this.layoutAlgorithm = layout;
if(graph != null)
layoutAlgorithm.layout(graph);
}
public void paintComponent(Graphics g)
{
if (graph == null)
{
return;
}
Graphics2D g2d = (Graphics2D) g;
//g2d.setRenderingHint(
// RenderingHints.KEY_ANTIALIASING,
// RenderingHints.VALUE_ANTIALIAS_ON);
Selection selection = manager.getSelection();
g2d.setColor(Color.white);
g2d.fillRect(0, 0, (int)getSize().getWidth(), (int)getSize().getHeight());
if(logo != null)
{
g.drawImage(logo,10,0,null);
}
Object node = null, type = null;
for (int t = 0; t < graph.getNodeCount(); t++)
{
node = graph.getNode(t);
for(int r = 0; r < graph.getEdgeTypeCount(node); r++)
{
type = graph.getEdgeType(r);
for (int s = 0; s < graph.getEdgeCount(node, type); s++)
{
defaultEdgeRenderer.render(
g2d,
graph.getEdge(node, type, s),
getNodeRenderer(node).getMountingPoint(getNodeRenderer(node).getNodeBounds(g2d, node, graph.getLocation(node)),
graph.getLocation(graph.getDestinationNode(node, type, s))),
getNodeRenderer(graph.getDestinationNode(node, type, s)).getMountingPoint(
getNodeRenderer(graph.getDestinationNode(node, type, s)).getNodeBounds(g2d, graph.getDestinationNode(node, type, s), graph.getLocation(graph.getDestinationNode(node, type, s))),
graph.getLocation(node)));
}
}
}
for (int t = 0; t < graph.getNodeCount(); t++)
{
node = graph.getNode(t);
if(selection.contains(node))
{
getNodeRenderer(node).renderSelected(
g2d,
node,
graph.getLocation(node));
}
else
{
getNodeRenderer(node).render(
g2d,
node,
graph.getLocation(node));
}
}
Rectangle2D box = manager.getSelectionBox();
if(box != null)
{
g2d.setColor(Color.darkGray);
g2d.draw(box);
g2d.setColor(new Color(10,0,20,50));
g2d.fill(box);
}
box = manager.getMoveBox();
if(box != null)
{
g2d.setColor(Color.darkGray);
g2d.draw(box);
}
}
public Dimension getPreferredSize()
{
return new Dimension(400, 400);
}
private Object getNodeForLocation(Point2D p2d)
{
for(int t=0; t <graph.getNodeCount(); t++)
{
Object n = graph.getNode(t);
if (getNodeRenderer(n).contains(graph.getLocation(n), p2d))
{
return n;
}
}
return null;
}
public void registerNodeRenderer(Class c, NodeRenderer r)
{
nodeRenderers.put(c,r);
}
private NodeRenderer getNodeRenderer(Object node)
{
if(nodeRenderers.get(node.getClass())==null)
return defaultNodeRenderer;
else
return (NodeRenderer)nodeRenderers.get(node.getClass());
}
public int print(Graphics g, PageFormat pageFormat, int pageIndex) {
if (pageIndex > 0) {
return(Printable.NO_SUCH_PAGE);
} else {
Graphics2D g2d = (Graphics2D)g;
g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
double scale = Math.max(this.getWidth()/pageFormat.getImageableWidth(),
this.getHeight()/pageFormat.getImageableHeight());
g2d.scale(1/scale, 1/scale);
// Turn off double buffering
paint(g2d);
// Turn double buffering back on
return(PAGE_EXISTS);
}
}
//////////////////////////////////////
// SelectionExperiment
SelectionManager manager = new SelectionManager();
public class SelectionMouseListener extends MouseAdapter implements MouseMotionListener {
public void mousePressed(MouseEvent e)
{
int modifiers = 0;
if(e.isShiftDown()) modifiers |= SelectionManager.MODIFIER_SHIFT;
if(e.isControlDown()) modifiers |= SelectionManager.MODIFIER_CTRL;
if(e.isAltDown()) modifiers |= SelectionManager.MODIFIER_ALT;
manager.handleMouseDown(e.getX(), e.getY(), modifiers);
repaint();
}
public void mouseDragged(MouseEvent e)
{
manager.handleMouseDrag(e.getX(), e.getY());
repaint();
}
public void mouseMoved(MouseEvent e)
{
}
public void mouseReleased(MouseEvent e)
{
manager.handleMouseUp(e.getX(), e.getY());
repaint();
}
}
public SelectionManager getSelectionManager()
{
return manager;
}
}