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 package uk.ac.rdg.resc.jstyx.gridservice.client;
30
31 import javax.swing.JFrame;
32 import javax.swing.JMenuBar;
33 import javax.swing.JMenu;
34 import javax.swing.JMenuItem;
35 import javax.swing.JLabel;
36 import javax.swing.BorderFactory;
37 import javax.swing.KeyStroke;
38 import javax.swing.JOptionPane;
39 import javax.swing.JTree;
40 import javax.swing.JScrollPane;
41 import javax.swing.JSplitPane;
42
43 import javax.swing.tree.TreeSelectionModel;
44 import javax.swing.tree.TreePath;
45
46 import java.awt.BorderLayout;
47
48 import java.awt.event.WindowAdapter;
49 import java.awt.event.WindowEvent;
50 import java.awt.event.KeyEvent;
51 import java.awt.event.ActionListener;
52 import java.awt.event.ActionEvent;
53 import java.awt.event.MouseListener;
54 import java.awt.event.MouseAdapter;
55 import java.awt.event.MouseEvent;
56
57 import java.net.URL;
58 import java.net.MalformedURLException;
59
60 import java.util.Vector;
61
62 import uk.ac.rdg.resc.jstyx.StyxException;
63 import uk.ac.rdg.resc.jstyx.client.StyxConnection;
64 import uk.ac.rdg.resc.jstyx.client.StyxConnectionListener;
65
66 /***
67 * GUI application for browsing and using Styx Grid Services
68 *
69 * @author Jon Blower
70 * $Revision: 367 $
71 * $Date: 2005-08-30 17:27:20 +0100 (Tue, 30 Aug 2005) $
72 * $Log$
73 * Revision 1.8 2005/08/30 16:27:20 jonblower
74 * Made sure graphical operations operate on the contentPane, not directly on the JFrame
75 *
76 * Revision 1.7 2005/05/26 16:51:40 jonblower
77 * Minor change to dialog box contents
78 *
79 * Revision 1.6 2005/05/18 17:13:51 jonblower
80 * Created SGSInstanceGUI
81 *
82 * Revision 1.5 2005/05/18 08:03:24 jonblower
83 * Implemented creation of new service instances
84 *
85 * Revision 1.4 2005/05/17 18:21:36 jonblower
86 * Added initial pop-up menu support
87 *
88 * Revision 1.3 2005/05/17 15:51:43 jonblower
89 * Correct operation of display of tree of SGS servers, services and instances
90 *
91 * Revision 1.2 2005/05/17 07:52:23 jonblower
92 * Further developments
93 *
94 * Revision 1.1 2005/05/16 16:17:47 jonblower
95 * Initial import
96 *
97 */
98 public class SGSExplorer extends JFrame implements StyxConnectionListener
99 {
100
101 private JLabel statusBar;
102 private Vector openConnections;
103 private JTree tree;
104 private PropertiesPanel propsPanel;
105
106 private SGSExplorerTreeModel treeModel;
107
108 /*** Creates a new instance of SGSExplorer */
109 public SGSExplorer()
110 {
111 super("SGSExplorer");
112 this.init();
113 }
114
115 private void init()
116 {
117 this.getContentPane().setLayout(new BorderLayout());
118 this.setSize(200, 500);
119 this.createMenus();
120 this.createStatusBar();
121 this.setupTree();
122
123
124 this.addWindowListener(new WindowAdapter()
125 {
126 public void windowClosing(WindowEvent we)
127 {
128 shutdown();
129 }
130 });
131
132 this.openConnections = new Vector();
133
134 this.propsPanel = new PropertiesPanel();
135 this.tree.addTreeSelectionListener(this.propsPanel);
136
137 JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
138 new JScrollPane(this.tree), new JScrollPane(this.propsPanel));
139
140 this.getContentPane().add(split, BorderLayout.CENTER);
141
142 }
143
144 private void createMenus()
145 {
146
147 JMenuBar menuBar = new JMenuBar();
148
149
150
151 JMenu serviceMenu = new JMenu("Service");
152 serviceMenu.setMnemonic(KeyEvent.VK_S);
153
154 JMenuItem connectItem = new JMenuItem("Connect to server...");
155 connectItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,
156 ActionEvent.CTRL_MASK));
157 connectItem.addActionListener(new ActionListener()
158 {
159 public void actionPerformed(ActionEvent e)
160 {
161
162
163
164 String input = JOptionPane.showInputDialog("Enter path to the "
165 + "server root (e.g. \"myserver:9092\")");
166 if (input != null)
167 {
168 connectToServer(input);
169 }
170 }
171 });
172 serviceMenu.add(connectItem);
173
174 serviceMenu.addSeparator();
175
176 JMenuItem quitItem = new JMenuItem("Quit");
177 quitItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q,
178 ActionEvent.CTRL_MASK));
179 quitItem.addActionListener(new ActionListener()
180 {
181 public void actionPerformed(ActionEvent e)
182 {
183 shutdown();
184 }
185 });
186 serviceMenu.add(quitItem);
187
188 menuBar.add(serviceMenu);
189
190 this.setJMenuBar(menuBar);
191 }
192
193 /***
194 * Takes the input from the message dialog box and tries to connect to the
195 * remote server
196 */
197 private void connectToServer(String inputURL)
198 {
199 String host = "";
200 int port = -1;
201 try
202 {
203
204 if (inputURL.indexOf("://") == -1)
205 {
206 inputURL = "styx://".concat(inputURL);
207 }
208 URL url = new URL(inputURL);
209 if (!url.getProtocol().equals("styx"))
210 {
211 JOptionPane.showMessageDialog(null,
212 "Invalid protocol \"".concat(url.getProtocol()).concat("\""),
213 "Invalid URL", JOptionPane.ERROR_MESSAGE);
214 }
215 host = url.getHost();
216 port = url.getPort();
217 StyxConnection conn = new StyxConnection(url.getHost(), url.getPort());
218 conn.addListener(this);
219
220
221
222 conn.connectAsync();
223 }
224 catch (MalformedURLException mue)
225 {
226 JOptionPane.showMessageDialog(null,
227 "Invalid URL: " + mue.getMessage(), "Invalid URL",
228 JOptionPane.ERROR_MESSAGE);
229 }
230 catch (StyxException se)
231 {
232
233
234 JOptionPane.showMessageDialog(null, "Error connecting to " +
235 host + ":" + port + ": " + se.getMessage(),
236 "Connection error", JOptionPane.ERROR_MESSAGE);
237 }
238 }
239
240 private void createStatusBar()
241 {
242 statusBar = new JLabel("Status bar");
243 statusBar.setBorder(BorderFactory.createLoweredBevelBorder());
244 this.getContentPane().add(statusBar, BorderLayout.SOUTH);
245 }
246
247 /***
248 * Sets up the tree that is used to browse the available SGS servers
249 */
250 private void setupTree()
251 {
252 this.treeModel = new SGSExplorerTreeModel();
253 this.tree = new JTree(this.treeModel);
254 this.tree.addTreeExpansionListener(this.treeModel);
255 this.tree.setRootVisible(false);
256 this.tree.setShowsRootHandles(true);
257
258 this.tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
259 this.tree.addMouseListener(ml);
260 }
261
262 /***
263 * Sets the status bar text to the given string
264 */
265 public void setStatusBarText(String text)
266 {
267 this.statusBar.setText(text);
268 }
269
270 /***
271 * Called just before the application closes. Add code to cleanly shut down
272 * here.
273 */
274 private void shutdown()
275 {
276
277 for (int i = 0; i < this.openConnections.size(); i++)
278 {
279 StyxConnection conn = (StyxConnection)this.openConnections.get(i);
280 conn.close();
281 }
282 System.exit(0);
283 }
284
285 /***
286 * Required by StyxConnectionListener interface. Called when the relevant
287 * handshaking has been performed and the connection is ready for Styx
288 * messages to be sent
289 */
290 public void connectionReady(StyxConnection conn)
291 {
292 System.out.println("Connected to " +
293 conn.getRemoteHost() + ":" + conn.getRemotePort());
294
295 this.openConnections.add(conn);
296
297 this.treeModel.addNewConnection(conn);
298 }
299
300 /***
301 * Required by StyxConnectionListener interface. Called when the connection
302 * has been closed. Does nothing here.
303 * TODO: use this as signal to remove connection from tree
304 */
305 public void connectionClosed(StyxConnection conn){}
306
307 /***
308 * Required by StyxConnectionListener interface. Called when an error has
309 * occurred when connecting.
310 * @param message String describing the problem
311 */
312 public void connectionError(StyxConnection conn, String message)
313 {
314 JOptionPane.showMessageDialog(null, "Could not connect to " +
315 conn.getRemoteHost() + ":" + conn.getRemotePort() + ": "
316 + message, "Connection error", JOptionPane.ERROR_MESSAGE);
317 }
318
319 /***
320 * Listens for requests for the pop-up menu.
321 * Note that for platform independence we must check for the popup trigger
322 * in both mousePressed and mouseReleased
323 */
324 private MouseListener ml = new MouseAdapter()
325 {
326 public void mousePressed(MouseEvent e)
327 {
328 maybeShowPopup(e);
329 }
330 public void mouseReleased(MouseEvent e)
331 {
332 maybeShowPopup(e);
333 }
334 private void maybeShowPopup(MouseEvent e)
335 {
336 if (e.isPopupTrigger())
337 {
338 TreePath selPath = tree.getPathForLocation(e.getX(), e.getY());
339
340
341 if (selPath != null)
342 {
343 Object lastPathComp = selPath.getLastPathComponent();
344 if (lastPathComp instanceof CStyxFileNode)
345 {
346
347 CStyxFileNode node = (CStyxFileNode)lastPathComp;
348 StyxExplorerPopupMenu.showContext(node, tree, e.getX(),
349 e.getY());
350 }
351 }
352 }
353 }
354 };
355
356 public static void main(String[] args)
357 {
358
359 System.setProperty("java.protocol.handler.pkgs", "uk.ac.rdg.resc.jstyx.client.protocol");
360 new SGSExplorer().setVisible(true);
361 }
362
363 }