1 package com.mxgraph.examples.swing.editor;
2 
3 import java.awt.Component;
4 
5 import javax.swing.JTable;
6 import javax.swing.JViewport;
7 
8 import com.mxgraph.swing.mxGraphComponent;
9 import com.mxgraph.util.mxPoint;
10 import com.mxgraph.util.mxUtils;
11 import com.mxgraph.view.mxCellState;
12 import com.mxgraph.view.mxGraph;
13 import com.mxgraph.view.mxGraphView;
14 
15 public class SchemaGraphComponent extends mxGraphComponent
16 {
17 
18 	/**
19 	 *
20 	 */
21 	private static final long serialVersionUID = -1152655782652932774L;
22 
23 	/**
24 	 *
25 	 * @param graph
26 	 */
SchemaGraphComponent(mxGraph graph)27 	public SchemaGraphComponent(mxGraph graph)
28 	{
29 		super(graph);
30 
31 		mxGraphView graphView = new mxGraphView(graph)
32 		{
33 
34 			/**
35 			 *
36 			 */
37 			public void updateFloatingTerminalPoint(mxCellState edge,
38 					mxCellState start, mxCellState end, boolean isSource)
39 			{
40 				int col = getColumn(edge, isSource);
41 
42 				if (col >= 0)
43 				{
44 					double y = getColumnLocation(edge, start, col);
45 					boolean left = start.getX() > end.getX();
46 
47 					if (isSource)
48 					{
49 						double diff = Math.abs(start.getCenterX()
50 								- end.getCenterX())
51 								- start.getWidth() / 2 - end.getWidth() / 2;
52 
53 						if (diff < 40)
54 						{
55 							left = !left;
56 						}
57 					}
58 
59 					double x = (left) ? start.getX() : start.getX()
60 							+ start.getWidth();
61 					double x2 = (left) ? start.getX() - 20 : start.getX()
62 							+ start.getWidth() + 20;
63 
64 					int index2 = (isSource) ? 1
65 							: edge.getAbsolutePointCount() - 1;
66 					edge.getAbsolutePoints().add(index2, new mxPoint(x2, y));
67 
68 					int index = (isSource) ? 0
69 							: edge.getAbsolutePointCount() - 1;
70 					edge.setAbsolutePoint(index, new mxPoint(x, y));
71 				}
72 				else
73 				{
74 					super.updateFloatingTerminalPoint(edge, start, end,
75 							isSource);
76 				}
77 			}
78 		};
79 
80 		graph.setView(graphView);
81 	}
82 
83 	/**
84 	 *
85 	 * @param edge
86 	 * @param isSource
87 	 * @return the column number the edge is attached to
88 	 */
getColumn(mxCellState state, boolean isSource)89 	public int getColumn(mxCellState state, boolean isSource)
90 	{
91 		if (state != null)
92 		{
93 			if (isSource)
94 			{
95 				return mxUtils.getInt(state.getStyle(), "sourceRow", -1);
96 			}
97 			else
98 			{
99 				return mxUtils.getInt(state.getStyle(), "targetRow", -1);
100 			}
101 		}
102 
103 		return -1;
104 	}
105 
106 	/**
107 	 *
108 	 */
getColumnLocation(mxCellState edge, mxCellState terminal, int column)109 	public int getColumnLocation(mxCellState edge, mxCellState terminal,
110 			int column)
111 	{
112 		Component[] c = components.get(terminal.getCell());
113 		int y = 0;
114 
115 		if (c != null)
116 		{
117 			for (int i = 0; i < c.length; i++)
118 			{
119 				if (c[i] instanceof JTableRenderer)
120 				{
121 					JTableRenderer vertex = (JTableRenderer) c[i];
122 
123 					JTable table = vertex.table;
124 					JViewport viewport = (JViewport) table.getParent();
125 					double dy = -viewport.getViewPosition().getY();
126 					y = (int) Math.max(terminal.getY() + 22, terminal.getY()
127 							+ Math.min(terminal.getHeight() - 20, 30 + dy
128 									+ column * 16));
129 				}
130 			}
131 		}
132 
133 		return y;
134 	}
135 
136 	/**
137 	 *
138 	 */
createComponents(mxCellState state)139 	public Component[] createComponents(mxCellState state)
140 	{
141 		if (getGraph().getModel().isVertex(state.getCell()))
142 		{
143 			return new Component[] { new JTableRenderer(state.getCell(), this) };
144 		}
145 
146 		return null;
147 	}
148 }
149