-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathStateConnection.java
executable file
·185 lines (151 loc) · 5.64 KB
/
StateConnection.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
package StateMachine;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.CubicCurve2D;
import java.awt.geom.Point2D;
import java.util.Enumeration;
import java.util.Vector;
import javax.swing.JOptionPane;
import CH.ifa.draw.command.Command;
import CH.ifa.draw.command.DeleteCommand;
import CH.ifa.draw.figure.ArrowTip;
import CH.ifa.draw.figure.PolyLineFigure;
import CH.ifa.draw.figure.TextFigure;
import CH.ifa.draw.figure.connection.LineConnection;
import CH.ifa.draw.framework.Drawing;
import CH.ifa.draw.framework.Figure;
import CH.ifa.draw.framework.FigureChangeEvent;
import CH.ifa.draw.framework.Handle;
import CH.ifa.draw.handle.NullHandle;
import CH.ifa.draw.samples.pert.PertFigure;
import CH.ifa.draw.util.Animatable;
import CH.ifa.draw.util.TextHolder;
public class StateConnection extends LineConnection{
/*
* Serialization support.
*/
private static final long serialVersionUID = -7959500008698525009L;
@SuppressWarnings("unused")
private int pertDependencySerializedDataVersion = 1;
private TextFigure name;
public StateConnection() {
setEndDecoration(new ArrowTip());
setStartDecoration(null);
fFrameColor = Color.BLACK;
Font fb = new Font("Helvetica", Font.BOLD, 20);
name = new TextFigure();
name.setFont(fb);
name.setAttribute("TextColor", Color.BLACK);
}
@Override
public boolean canConnect(Figure start, Figure end) {
if(start instanceof StateFigure && end instanceof StateFigure)
{
StateFigure source = (StateFigure) start;
if(source.getNumTransitions() < 2) return true;
else return false;
}
else return false;
}
@Override
public void draw(Graphics g) {
g.setColor(getFrameColor());
if(fPoints.size() == 2) /* Straight arrow connection */
{
Point p1, p2;
for (int i = 0; i < fPoints.size() - 1; i++) {
p1 = fPoints.elementAt(i);
p2 = fPoints.elementAt(i + 1);
g.drawLine(p1.x, p1.y, p2.x, p2.y);
}
}
else if(fPoints.size() == 3) /* Arc Connection to another state */
{
Point P1 = fPoints.elementAt(0);
Point ctrl = fPoints.elementAt(1);
Point P2 = fPoints.elementAt(2);
/* Cubic curve requires 4 points, initial, end, and 2 control points.
* Just use the same value for control point 1 and 2 */
CubicCurve2D.Double cubicCurve;
cubicCurve = new CubicCurve2D.Double(P1.getX(), P1.getY(),
ctrl.getX(), ctrl.getY(),
ctrl.getX(), ctrl.getY(),
P2.getX(), P2.getY());
Graphics2D g2 = (Graphics2D)g;
g2.draw(cubicCurve);
}
else if(fPoints.size() == 4) /* Arc connection to the same state */
{
Point P1 = fPoints.elementAt(0);
Point ctrl1 = fPoints.elementAt(1);
Point ctrl2 = fPoints.elementAt(2);
Point P2 = fPoints.elementAt(3);
/* Cubic curve requires 4 points, initial, end, and 2 control points. */
CubicCurve2D.Double cubicCurve;
cubicCurve = new CubicCurve2D.Double(P1.getX(), P1.getY(),
ctrl1.getX(), ctrl1.getY(),
ctrl2.getX(), ctrl2.getY(),
P2.getX(), P2.getY());
Graphics2D g2 = (Graphics2D)g;
g2.draw(cubicCurve);
}
decorate(g);
name.draw(g);
}
private void decorate(Graphics g) {
Point p3 = fPoints.elementAt(fPoints.size() - 2);
Point p4 = fPoints.elementAt(fPoints.size() - 1);
fEndDecoration.draw(g, p4.x, p4.y, p3.x, p3.y);
}
@Override
public void handleConnect(Figure start, Figure end) {
StateFigure source = (StateFigure) start;
StateFigure target = (StateFigure) end;
int midX = (target.center().x - source.center().x) / 2;
int midY = (target.center().y - source.center().y) / 2;
String input = JOptionPane.showInputDialog("Please enter the input variable for transition: ");
if(source.nextState(input) == null)
{
if(input != null)
{
name.setText(input);
source.addTransition(new Transition(target, input));
target.addPreState(source);
if(source == target) /* Add two control points to line if the state is connected to itself */
{
insertPointAt(new Point(source.center().x + midX + 50, source.center().y + midY - 50), fPoints.size()-1);
insertPointAt(new Point(source.center().x + midX + 75, source.center().y + midY - 10), fPoints.size()-1);
}
else insertPointAt(new Point(source.center().x + midX, source.center().y + midY), fPoints.size()-1);
TextHolder textHolder = (TextHolder) ((Figure) name);
textHolder.connect(this);
}
else listener().figureRequestRemove(new FigureChangeEvent(this));
} else {
listener().figureRequestRemove(new FigureChangeEvent(this));
}
}
@Override
public void handleDisconnect(Figure start, Figure end) {
StateFigure source = (StateFigure) start;
StateFigure target = (StateFigure) end;
if (target != null) {
target.removePreState(source);
}
if (source != null) {
source.removeTransition(name.getText());
}
}
@Override
public Vector<Handle> handles() {
Vector<Handle> handles = super.handles();
// don't allow to reconnect the starting figure
handles.setElementAt(
new NullHandle(this, PolyLineFigure.locator(0)), 0);
return handles;
}
}