root / trunk / code / projects / colonet / client / Colonet.java @ 567
History | View | Annotate | Download (38 KB)
1 | 32 | gtress | //
|
---|---|---|---|
2 | 531 | emarinel | // Colonet.java
|
3 | 32 | gtress | //
|
4 | |||
5 | import javax.swing.*; |
||
6 | 320 | gtress | import javax.swing.event.*; |
7 | import javax.imageio.*; |
||
8 | 32 | gtress | import java.awt.*; |
9 | import java.awt.image.*; |
||
10 | import java.awt.event.*; |
||
11 | import java.net.*; |
||
12 | import java.io.*; |
||
13 | 427 | gtress | import java.util.*; |
14 | 32 | gtress | |
15 | 320 | gtress | /**
|
16 | 531 | emarinel | * The Colonet Graphical User Interface Applet for use locally and over an internet connection.
|
17 | * @author Gregory Tress
|
||
18 | 527 | emarinel | *
|
19 | 531 | emarinel | * To generate javadoc on this file or other java files, use javadoc *.java -d doc, where doc
|
20 | * is the name of the folder into which the files should be written.
|
||
21 | 320 | gtress | */
|
22 | 559 | gtress | public class Colonet extends JApplet implements ActionListener, MouseInputListener, KeyListener { |
23 | 320 | gtress | |
24 | 427 | gtress | // Used for images
|
25 | 531 | emarinel | final int CANVAS_SIZE = 500; //the applet may be slow if the canvas gets too large |
26 | 32 | gtress | final int BUFFER = 50; |
27 | final int RADIUS = 30; |
||
28 | 527 | emarinel | |
29 | 341 | gtress | //Used for the robot controller
|
30 | final int VECTOR_CONTROLLER_HEIGHT = 220; |
||
31 | 420 | gtress | final int VECTOR_CONTROLLER_WIDTH = 350; |
32 | 32 | gtress | |
33 | // Connection
|
||
34 | 527 | emarinel | JTextField txtHost;
|
35 | JTextField txtPort;
|
||
36 | JButton btnConnect;
|
||
37 | 414 | gtress | JButton btnGetXBeeIDs;
|
38 | 32 | gtress | JLabel lblConnectionStatus;
|
39 | 320 | gtress | JTextArea txtMatrix;
|
40 | 527 | emarinel | JTextArea txtInfo;
|
41 | 32 | gtress | JPanel panelConnect;
|
42 | JPanel panelServerInterface;
|
||
43 | 527 | emarinel | Socket socket;
|
44 | 427 | gtress | OutputStreamWriter out;
|
45 | 527 | emarinel | DataUpdater dataUpdater; |
46 | |||
47 | 32 | gtress | // South
|
48 | JPanel panelSouth;
|
||
49 | JTextArea log;
|
||
50 | JScrollPane spLog;
|
||
51 | 527 | emarinel | |
52 | 32 | gtress | // Control
|
53 | JPanel panelControl;
|
||
54 | JTabbedPane tabPaneControl;
|
||
55 | JPanel panelRobotControl;
|
||
56 | JPanel panelRobotDirection;
|
||
57 | 320 | gtress | JPanel panelRobotDirectionButtons;
|
58 | 32 | gtress | JPanel panelRobotCommands;
|
59 | JButton btnF, btnB, btnL, btnR, btnActivate;
|
||
60 | 320 | gtress | JComboBox cmbRobotNum;
|
61 | JLabel lblBattery;
|
||
62 | 428 | gtress | JLabel lblSelected;
|
63 | 333 | gtress | BatteryIcon batteryIcon; |
64 | 320 | gtress | JPanel panelBattery;
|
65 | VectorController vectorController; |
||
66 | BufferedImage imageVectorControl;
|
||
67 | 427 | gtress | JButton btnAssignID;
|
68 | 428 | gtress | boolean setWaypoint;
|
69 | 429 | gtress | int setWaypointID;
|
70 | 428 | gtress | JButton btnCommand_MoveTo;
|
71 | 429 | gtress | JButton btnCommand_MoveAll;
|
72 | 320 | gtress | JButton btnCommand_StopTask;
|
73 | JButton btnCommand_ResumeTask;
|
||
74 | JButton btnCommand_ChargeNow;
|
||
75 | JButton btnCommand_StopCharging;
|
||
76 | 527 | emarinel | |
77 | 32 | gtress | // Task Manager
|
78 | JPanel panelTaskManager;
|
||
79 | JScrollPane spTaskManager;
|
||
80 | JPanel panelTaskManagerControls;
|
||
81 | JPanel panelTaskManagerControlsPriority;
|
||
82 | DefaultListModel taskListModel;
|
||
83 | JList taskList;
|
||
84 | JButton btnAddTask;
|
||
85 | JButton btnRemoveTask;
|
||
86 | JButton btnMoveTaskUp;
|
||
87 | JButton btnMoveTaskDown;
|
||
88 | 320 | gtress | JButton btnUpdateTasks;
|
89 | TaskAddWindow taskAddWindow; |
||
90 | 527 | emarinel | |
91 | 427 | gtress | //Webcam
|
92 | 320 | gtress | WebcamPanel panelWebcam; |
93 | GraphicsPanel panelGraph; |
||
94 | 32 | gtress | GraphicsConfiguration gc;
|
95 | volatile BufferedImage image; |
||
96 | volatile Graphics2D canvas; |
||
97 | int cx, cy;
|
||
98 | 320 | gtress | JTabbedPane tabPaneMain;
|
99 | 527 | emarinel | |
100 | 32 | gtress | Font botFont;
|
101 | volatile int numBots; |
||
102 | 531 | emarinel | volatile int selectedBot; //the user has selected this bot graphically |
103 | 556 | gtress | volatile java.util.Map <Integer, RobotIcon> robotIcons; //contains boundary shapes around bots for click detection |
104 | 320 | gtress | volatile int[] xbeeID; |
105 | 527 | emarinel | |
106 | 501 | gtress | Colonet self = this;
|
107 | 320 | gtress | WebcamLoader webcamLoader; |
108 | 549 | gtress | volatile ColonetServerInterface csi;
|
109 | 32 | gtress | |
110 | public void init () { |
||
111 | 427 | gtress | // Set the default look and feel - choose one
|
112 | 531 | emarinel | //String laf = UIManager.getSystemLookAndFeelClassName();
|
113 | 320 | gtress | String laf = UIManager.getCrossPlatformLookAndFeelClassName(); |
114 | //String laf = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
|
||
115 | 531 | emarinel | try {
|
116 | UIManager.setLookAndFeel(laf);
|
||
117 | } catch (UnsupportedLookAndFeelException exc) { |
||
118 | System.err.println ("Warning: UnsupportedLookAndFeel: " + laf); |
||
119 | } catch (Exception exc) { |
||
120 | System.err.println ("Error loading " + laf + ": " + exc); |
||
121 | } |
||
122 | |||
123 | 32 | gtress | // We should invoke and wait to avoid browser display difficulties
|
124 | Runnable r = new Runnable() { |
||
125 | public void run() { |
||
126 | createAndShowGUI(); |
||
127 | } |
||
128 | }; |
||
129 | 531 | emarinel | |
130 | 32 | gtress | try {
|
131 | SwingUtilities.invokeAndWait(r);
|
||
132 | } catch (InterruptedException e) { |
||
133 | //Not really sure why we would be in this situation
|
||
134 | 320 | gtress | System.out.println("InterruptedException in init: " + e); |
135 | 32 | gtress | } catch (java.lang.reflect.InvocationTargetException e) {
|
136 | 320 | gtress | //This could happen for various reasons if there is a problem in createAndShowGUI
|
137 | e.printStackTrace(); |
||
138 | 32 | gtress | } |
139 | } |
||
140 | 527 | emarinel | |
141 | 32 | gtress | public void destroy () { |
142 | 567 | gtress | csi.disconnect(); |
143 | 32 | gtress | } |
144 | |||
145 | private synchronized void createAndShowGUI () { |
||
146 | // init graphical elements
|
||
147 | 320 | gtress | // Get the graphics configuration of the screen to create a buffer
|
148 | 527 | emarinel | gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
|
149 | 320 | gtress | image = gc.createCompatibleImage(CANVAS_SIZE,CANVAS_SIZE); |
150 | canvas = image.createGraphics(); |
||
151 | 531 | emarinel | canvas.setStroke(new BasicStroke(2)); //set pen width |
152 | panelGraph = new GraphicsPanel(image, false); //set automatic double-buffering to false. we are doing it manually. |
||
153 | 320 | gtress | panelWebcam = new WebcamPanel();
|
154 | tabPaneMain = new JTabbedPane(); |
||
155 | 555 | emarinel | tabPaneMain.setFont(new Font("arial", Font.PLAIN, 16)); |
156 | 320 | gtress | tabPaneMain.add(panelWebcam, "Webcam");
|
157 | 429 | gtress | //tabPaneMain.add(panelGraph, "Graph");
|
158 | 527 | emarinel | |
159 | 320 | gtress | // Calculate center of canvas
|
160 | cx = image.getWidth() / 2;
|
||
161 | cy = image.getHeight() / 2;
|
||
162 | 527 | emarinel | |
163 | 427 | gtress | // Set up robots
|
164 | 555 | emarinel | botFont = new Font("arial", Font.PLAIN, 14); |
165 | 320 | gtress | numBots = 0;
|
166 | 428 | gtress | selectedBot = -1;
|
167 | 556 | gtress | robotIcons = new HashMap <Integer, RobotIcon> (); |
168 | 527 | emarinel | |
169 | 32 | gtress | // Connection area
|
170 | 320 | gtress | txtMatrix = new JTextArea(); |
171 | 501 | gtress | txtMatrix.setBorder(BorderFactory.createTitledBorder("Info")); |
172 | 32 | gtress | txtInfo = new JTextArea(); |
173 | txtInfo.setBorder(BorderFactory.createTitledBorder("Info")); |
||
174 | txtInfo.setEditable(false);
|
||
175 | 470 | gtress | txtHost = new JTextField(this.getDocumentBase().getHost()); |
176 | 32 | gtress | txtHost.setBorder(BorderFactory.createTitledBorder("Host")); |
177 | txtPort = new JTextField("10123"); |
||
178 | txtPort.setBorder(BorderFactory.createTitledBorder("Port")); |
||
179 | btnConnect = new JButton("Connect"); |
||
180 | 555 | emarinel | btnConnect.setFont(new Font("arial", Font.BOLD, 16)); |
181 | 414 | gtress | btnGetXBeeIDs = new JButton("Get XBee IDs"); |
182 | 389 | gtress | getRootPane().setDefaultButton(btnConnect); |
183 | 32 | gtress | lblConnectionStatus = new JLabel("Status: Offline"); |
184 | panelConnect = new JPanel(); |
||
185 | panelConnect.setLayout(new GridLayout(6,1)); |
||
186 | panelConnect.add(lblConnectionStatus); |
||
187 | panelConnect.add(txtHost); |
||
188 | panelConnect.add(txtPort); |
||
189 | panelConnect.add(btnConnect); |
||
190 | 470 | gtress | //panelConnect.add(btnGetXBeeIDs);
|
191 | 32 | gtress | panelServerInterface = new JPanel(); |
192 | panelServerInterface.setLayout(new GridLayout(2,1)); |
||
193 | panelServerInterface.add(panelConnect); |
||
194 | 320 | gtress | panelServerInterface.add(txtMatrix); |
195 | 527 | emarinel | |
196 | 32 | gtress | // Robot direction panel
|
197 | panelRobotDirection = new JPanel(); |
||
198 | 320 | gtress | panelRobotDirectionButtons = new JPanel(); |
199 | 555 | emarinel | |
200 | Font f = new Font(null, Font.PLAIN, 18); |
||
201 | btnF = new JButton("\u2191"); |
||
202 | btnF.setFont(f); |
||
203 | btnB = new JButton("\u2193"); |
||
204 | btnB.setFont(f); |
||
205 | btnL = new JButton("\u2190"); |
||
206 | btnL.setFont(f); |
||
207 | btnR = new JButton("\u2192"); |
||
208 | btnR.setFont(f); |
||
209 | btnActivate = new JButton("\u25A0"); |
||
210 | btnActivate.setFont(new Font(null, Font.BOLD, 36)); |
||
211 | |||
212 | 320 | gtress | panelRobotDirectionButtons.setLayout(new GridLayout(1,5)); |
213 | panelRobotDirectionButtons.add(btnActivate); |
||
214 | panelRobotDirectionButtons.add(btnF); |
||
215 | panelRobotDirectionButtons.add(btnB); |
||
216 | panelRobotDirectionButtons.add(btnL); |
||
217 | panelRobotDirectionButtons.add(btnR); |
||
218 | 527 | emarinel | |
219 | 341 | gtress | imageVectorControl = gc.createCompatibleImage(VECTOR_CONTROLLER_WIDTH, VECTOR_CONTROLLER_HEIGHT); |
220 | 320 | gtress | vectorController = new VectorController(imageVectorControl);
|
221 | panelRobotDirection.setLayout(new BorderLayout()); |
||
222 | 559 | gtress | //panelRobotDirection.add(vectorController, BorderLayout.CENTER);
|
223 | 320 | gtress | panelRobotDirection.add(panelRobotDirectionButtons, BorderLayout.SOUTH);
|
224 | 527 | emarinel | |
225 | 32 | gtress | // Robot Control and Commands
|
226 | panelRobotCommands = new JPanel(); |
||
227 | 320 | gtress | panelRobotCommands.setLayout(new GridLayout(5,2)); |
228 | cmbRobotNum = new JComboBox(); |
||
229 | 333 | gtress | // Battery subset
|
230 | 514 | gtress | batteryIcon = new BatteryIcon(0); |
231 | 333 | gtress | lblBattery = new JLabel(batteryIcon); |
232 | 428 | gtress | lblSelected = new JLabel("None"); |
233 | // Command subset
|
||
234 | setWaypoint = false;
|
||
235 | 429 | gtress | setWaypointID = -1;
|
236 | 427 | gtress | btnAssignID = new JButton("Assign ID"); |
237 | 428 | gtress | btnCommand_MoveTo = new JButton("Move to ..."); |
238 | 429 | gtress | btnCommand_MoveAll = new JButton("Move all ..."); |
239 | 320 | gtress | btnCommand_StopTask = new JButton("Stop Current Task"); |
240 | btnCommand_ResumeTask = new JButton("Resume Current Task"); |
||
241 | btnCommand_ChargeNow = new JButton("Recharge Now"); |
||
242 | btnCommand_StopCharging = new JButton("Stop Recharging"); |
||
243 | panelRobotCommands.add(new JLabel("Select Robot to Control: ")); |
||
244 | panelRobotCommands.add(cmbRobotNum); |
||
245 | panelRobotCommands.add(new JLabel("Battery Level: ")); |
||
246 | panelRobotCommands.add(lblBattery); |
||
247 | 428 | gtress | panelRobotCommands.add(new JLabel("Selected Icon: ")); |
248 | panelRobotCommands.add(lblSelected); |
||
249 | 427 | gtress | panelRobotCommands.add(btnAssignID); |
250 | 429 | gtress | panelRobotCommands.add(new JLabel("")); |
251 | 428 | gtress | panelRobotCommands.add(btnCommand_MoveTo); |
252 | 429 | gtress | panelRobotCommands.add(btnCommand_MoveAll); |
253 | 427 | gtress | //panelRobotCommands.add(btnCommand_StopTask);
|
254 | //panelRobotCommands.add(btnCommand_ResumeTask);
|
||
255 | //panelRobotCommands.add(btnCommand_ChargeNow);
|
||
256 | //panelRobotCommands.add(btnCommand_StopCharging);
|
||
257 | 32 | gtress | panelRobotControl = new JPanel(); |
258 | panelRobotControl.setLayout(new GridLayout(2,1)); |
||
259 | panelRobotControl.add(panelRobotDirection); |
||
260 | panelRobotControl.add(panelRobotCommands); |
||
261 | 527 | emarinel | |
262 | |||
263 | 32 | gtress | // Task Manager
|
264 | panelTaskManager = new JPanel(); |
||
265 | panelTaskManager.setLayout(new BorderLayout()); |
||
266 | taskListModel = new DefaultListModel(); |
||
267 | taskList = new JList(taskListModel); |
||
268 | taskList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||
269 | taskList.setSelectedIndex(0);
|
||
270 | spTaskManager = new JScrollPane(taskList); |
||
271 | panelTaskManagerControls = new JPanel(); |
||
272 | 320 | gtress | panelTaskManagerControls.setLayout(new GridLayout(1,4)); |
273 | 32 | gtress | panelTaskManagerControlsPriority = new JPanel(); |
274 | panelTaskManagerControlsPriority.setLayout(new GridLayout(1,2)); |
||
275 | btnAddTask = new JButton("Add..."); |
||
276 | btnRemoveTask = new JButton("Remove"); |
||
277 | btnMoveTaskUp = new JButton("^"); |
||
278 | btnMoveTaskDown = new JButton("v"); |
||
279 | 320 | gtress | btnUpdateTasks = new JButton("Update"); |
280 | 32 | gtress | panelTaskManagerControlsPriority.add(btnMoveTaskUp); |
281 | panelTaskManagerControlsPriority.add(btnMoveTaskDown); |
||
282 | panelTaskManagerControls.add(btnAddTask); |
||
283 | panelTaskManagerControls.add(btnRemoveTask); |
||
284 | 320 | gtress | panelTaskManagerControls.add(btnUpdateTasks); |
285 | 32 | gtress | panelTaskManagerControls.add(panelTaskManagerControlsPriority); |
286 | panelTaskManager.add(spTaskManager, BorderLayout.CENTER);
|
||
287 | panelTaskManager.add(panelTaskManagerControls, BorderLayout.SOUTH);
|
||
288 | panelTaskManager.add(new JLabel("Current Task Queue"), BorderLayout.NORTH); |
||
289 | 320 | gtress | taskAddWindow = new TaskAddWindow();
|
290 | 527 | emarinel | |
291 | 32 | gtress | // Message log
|
292 | log = new JTextArea(); |
||
293 | 531 | emarinel | spLog = new JScrollPane(log, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, |
294 | 32 | gtress | ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
295 | spLog.setBorder(BorderFactory.createTitledBorder("Log")); |
||
296 | 320 | gtress | spLog.setPreferredSize(new Dimension(0, 120)); |
297 | 32 | gtress | log.setEditable(false);
|
298 | 527 | emarinel | |
299 | 32 | gtress | // Main control mechanism
|
300 | panelControl = new JPanel(); |
||
301 | panelControl.setLayout(new GridLayout(1,1)); |
||
302 | tabPaneControl = new JTabbedPane(JTabbedPane.TOP); |
||
303 | 555 | emarinel | tabPaneControl.setFont(new Font("arial", Font.PLAIN, 16)); |
304 | 341 | gtress | tabPaneControl.setPreferredSize(new Dimension(VECTOR_CONTROLLER_WIDTH, 0)); |
305 | 32 | gtress | tabPaneControl.addTab("Connection", panelServerInterface);
|
306 | tabPaneControl.addTab("Robots", panelRobotControl);
|
||
307 | 514 | gtress | //tabPaneControl.addTab("Tasks", panelTaskManager);
|
308 | 32 | gtress | panelControl.add(tabPaneControl); |
309 | 527 | emarinel | |
310 | 32 | gtress | // Set up elements in the south
|
311 | panelSouth = new JPanel(); |
||
312 | panelSouth.setLayout(new GridLayout(1,2)); |
||
313 | 320 | gtress | //panelSouth.add(spLog);
|
314 | 32 | gtress |