1 package org.glassbox.graphview;
2
3 import java.awt.*;
4
5 import de.fzi.wim.guibase.graphview.graph.*;
6 import de.fzi.wim.guibase.graphview.view.*;
7
8 /***
9 A NodePainter which paints several lines of text above the top or below the bottom of a node.
10 */
11 public class TextNodePainter2 implements ZoomableNodePainter {
12 public static final int TOP = 1;
13 public static final int BOTTOM = 2;
14
15 private Color _color;
16 private Font _font;
17 private Rectangle _bounds, _bounds2;
18 private FontMetrics _metrics;
19 private int _font_height;
20 private int _font_ascent;
21 private int _valign;
22 private int _gap;
23 private NodePainter _delegate;
24
25 /***
26 Constructor.
27 @param delegate The delegate NodePainter decorated by this painter.
28 @param font The font.
29 @param color The text color.
30 @param valign The vertical alignment of the text, one of <code>TOP, BOTTOM</code>.
31 @param gap The vertical gap between node and text.
32 */
33 public TextNodePainter2(NodePainter delegate, Font font, Color color, int valign, int gap) {
34 _delegate = delegate;
35 _valign = valign;
36 _font = font;
37 _gap = gap;
38 _metrics = Toolkit.getDefaultToolkit().getFontMetrics(_font);
39 _font_height = _metrics.getHeight();
40 _font_ascent = _metrics.getAscent();
41 _color = color;
42 _bounds = new Rectangle();
43 _bounds2 = new Rectangle();
44 }
45
46 protected NodePainter getDelegate() {
47 return _delegate;
48 }
49
50 public void setZoomFactor(double zf) {
51 if (_delegate instanceof ZoomableNodePainter) {
52 ((ZoomableNodePainter)_delegate).setZoomFactor(zf);
53 }
54 }
55
56 /***
57 Subclasses may override this method to provide the
58 text to be painted for the specified node.
59 @param node The node to be painted.
60 @return An array of strings: the lines of text to be painted for the node.
61 */
62 protected String[] getText(Node node) {
63 return new String[] { node.toString() };
64 }
65
66 /***
67 Get the bounds of the text of the given node.
68 @param grp The graphpane.
69 @param node The node.
70 @param lines The text of the node.
71 @param bounds The rectangle to set to the bounds of the text.
72 */
73 protected void getTextBounds(JGraphPane grp, Node node, String[] lines, Rectangle bounds) {
74 _delegate.getNodeScreenBounds(grp, node, bounds);
75 Point p = grp.getScreenPointForNode(node);
76 int height = lines.length * _font_height;
77 int width = 0;
78 for (int i=0; i<lines.length; i++) {
79 width = Math.max(width, _metrics.stringWidth(lines[i]));
80 }
81 if (_valign == BOTTOM) {
82 bounds.setBounds(p.x - width/2,
83 bounds.y + bounds.height + _gap,
84 width,
85 height);
86 } else {
87 bounds.setBounds(p.x - width/2,
88 bounds.y - _gap - height,
89 width,
90 height);
91 }
92 }
93
94 public void paintNode(JGraphPane graphpane,Graphics2D g,Node node) {
95 _delegate.paintNode(graphpane, g, node);
96
97 String[] lines = getText(node);
98
99 g.setFont(_font);
100 g.setColor(_color);
101
102 getTextBounds(graphpane, node, lines, _bounds);
103
104 for (int i=0; i<lines.length; i++) {
105 g.drawString(lines[i], _bounds.x, _bounds.y + (i * _font_height) + _font_ascent);
106 }
107 }
108
109 public boolean isInNode(JGraphPane graphpane,Node node,Point point) {
110 _delegate.getNodeScreenBounds(graphpane, node, _bounds);
111 getTextBounds(graphpane, node, getText(node), _bounds2);
112 _bounds.add(_bounds2);
113 return _bounds.contains(point);
114 }
115
116 public void getNodeScreenBounds(JGraphPane graphpane, Node node, Rectangle nodebounds) {
117 _delegate.getNodeScreenBounds(graphpane, node, nodebounds);
118 getTextBounds(graphpane, node, getText(node), _bounds);
119 nodebounds.add(_bounds);
120 }
121
122 public String getToolTipText(JGraphPane graphpane,Node node,Point point) {
123 return _delegate.getToolTipText(graphpane, node, point);
124 }
125 }