Main Page | Class Hierarchy | Class List | File List | Class Members | Related Pages

ChannelListSwing.java

00001 /* 00002 * Created on Mar 25, 2004 00003 */ 00004 package org.nees.rbnb; 00005 00006 import javax.swing.JPanel; 00007 import javax.swing.JFrame; 00008 import javax.swing.JScrollPane; 00009 import javax.swing.JEditorPane; 00010 import javax.swing.JSplitPane; 00011 00012 import javax.swing.BorderFactory; 00013 00014 import javax.swing.JTree; 00015 import javax.swing.tree.DefaultMutableTreeNode; 00016 import javax.swing.tree.TreeSelectionModel; 00017 import javax.swing.tree.TreeModel; 00018 import javax.swing.tree.DefaultTreeModel; 00019 import javax.swing.event.TreeSelectionEvent; 00020 import javax.swing.event.TreeSelectionListener; 00021 00022 import javax.swing.Timer; 00023 00024 import java.awt.BorderLayout; 00025 import java.awt.Dimension; 00026 import java.awt.event.ActionEvent; 00027 import java.awt.event.ActionListener; 00028 00029 import java.util.Iterator; 00030 import java.util.List; 00031 import java.util.Vector; 00032 import java.util.Enumeration; 00033 import java.util.Date; 00034 import java.util.TimeZone; 00035 import java.text.SimpleDateFormat; 00036 00037 import com.rbnb.sapi.*; 00038 import com.rbnb.utility.ArgHandler; //for argument parsing 00039 //import COM.Creare.Utility.ArgHandler; //for argument parsing 00040 00050 public class ChannelListSwing extends JPanel 00051 implements TreeSelectionListener 00052 { 00053 private static final String SERVER_NAME = "localhost"; 00054 private static final String SERVER_PORT = "3333"; 00055 00056 private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("MMM d, yyyy h:mm aa"); 00057 private static final TimeZone TZ = TimeZone.getTimeZone("GMT"); 00058 00059 private String server = SERVER_NAME + ":" + SERVER_PORT; 00060 00061 private Sink sink = null; 00062 private ChannelMap sMap; 00063 private boolean connected = false; 00064 00065 private JTree tree; 00066 private JEditorPane htmlPane; 00067 private boolean needsRefresh = false; 00068 private Timer checkRefresh; 00069 private Thread timerThread; 00070 private boolean runit = false; 00071 00072 public static void main(String[] args) { 00073 //Schedule a job for the event-dispatching thread: 00074 //creating and showing this application's GUI and start the applicaiton 00075 final String[] a = args; 00076 javax.swing.SwingUtilities.invokeLater(new Runnable() { 00077 public void run() { 00078 ChannelListSwing c = new ChannelListSwing(); 00079 if (c.setArgs(a)) 00080 { 00081 c.connect(); 00082 c.createAndShowGUI(); 00083 c.setTimer(); 00084 c.startCheckThread(); 00085 } 00086 } 00087 }); 00088 } 00089 00090 private void printUsage() { 00091 System.out.println("ChannelListSwing: usage is..."); 00092 System.out.print("ChannelListSwing "); 00093 System.out.print("[-s Server Name *" + SERVER_NAME + "] "); 00094 System.out.print("[-p Server Port *" + SERVER_PORT + "] "); 00095 System.out.println(); 00096 } 00097 00098 public boolean setArgs(String[] args) { 00099 String serverName = SERVER_NAME; 00100 String serverPort = SERVER_PORT; 00101 //parse args 00102 try { 00103 ArgHandler ah=new ArgHandler(args); 00104 if (ah.checkFlag('h')) { 00105 printUsage(); 00106 return false; 00107 } 00108 if (ah.checkFlag('s')) { 00109 String a=ah.getOption('s'); 00110 if (a!=null) serverName=a; 00111 } 00112 if (ah.checkFlag('p')) { 00113 String a=ah.getOption('p'); 00114 if (a!=null) serverPort=a; 00115 } 00116 } catch (Exception e) { 00117 System.err.println("ChannelList argument exception "+e.getMessage()); 00118 e.printStackTrace(); 00119 return false; 00120 } 00121 00122 setArgs(serverName,serverPort); 00123 00124 System.out.println("Starting ChannelList on " + server); 00125 System.out.println(" Use ChannelList -h to see optional parameters"); 00126 00127 return true; 00128 } 00129 00130 public ChannelListSwing() 00131 { 00132 setArgs(SERVER_NAME,SERVER_PORT); 00133 } 00134 00135 public void setArgs(String serverName, String serverPort) 00136 { 00137 server = serverName + ":" + serverPort; 00138 } 00139 00140 protected void createAndShowGUI() { 00141 00142 //Make sure we have nice window decorations. 00143 //JFrame.setDefaultLookAndFeelDecorated(true); 00144 00145 //Create and set up the window. 00146 JFrame frame = new JFrame("Channel List"); 00147 //frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 00148 00149 initGraphics(); 00150 setOpaque(true); //content panes must be opaque 00151 frame.setContentPane(this); 00152 00153 //Display the window. 00154 frame.pack(); 00155 frame.setVisible(true); 00156 } 00157 00158 protected void initGraphics() { 00159 setLayout(new BorderLayout()); 00160 setBorder(BorderFactory.createEmptyBorder(10,10,10,10)); 00161 00162 //Create the nodes. 00163 DefaultMutableTreeNode top = createNodes(); 00164 00165 //Create a tree that allows one selection at a time. 00166 tree = new JTree(top); 00167 tree.getSelectionModel().setSelectionMode 00168 (TreeSelectionModel.SINGLE_TREE_SELECTION); 00169 00170 //Listen for when the selection changes. 00171 tree.addTreeSelectionListener(this); 00172 00173 //Create the scroll pane and add the tree to it. 00174 JScrollPane treeView = new JScrollPane(tree); 00175 00176 //Create the HTML viewing pane. 00177 htmlPane = new JEditorPane(); 00178 htmlPane.setEditable(false); 00179 JScrollPane htmlView = new JScrollPane(htmlPane); 00180 00181 //Add the scroll panes to a split pane. 00182 JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); 00183 splitPane.setTopComponent(treeView); 00184 splitPane.setBottomComponent(htmlView); 00185 00186 Dimension minimumSize = new Dimension(100, 50); 00187 htmlView.setMinimumSize(minimumSize); 00188 treeView.setMinimumSize(minimumSize); 00189 splitPane.setDividerLocation(100); //XXX: ignored in some releases 00190 //of Swing. bug 4101306 00191 //workaround for bug 4101306: 00192 //treeView.setPreferredSize(new Dimension(100, 100)); 00193 00194 splitPane.setPreferredSize(new Dimension(500, 300)); 00195 00196 //Add the split pane to this panel. 00197 add(splitPane); 00198 00199 //root and frame 00200 JFrame itsFrame = new JFrame("ChannelList"); 00201 itsFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 00202 itsFrame.setSize(new Dimension(120, 40)); 00203 itsFrame.getContentPane().add(this, BorderLayout.CENTER); 00204 00205 //Display the window. 00206 itsFrame.pack(); 00207 itsFrame.setVisible(true); 00208 } 00209 00210 protected void setTimer() 00211 { 00212 int delay = 100; //milliseconds; 1/10 second 00213 ActionListener taskPerformer = new ActionListener() { 00214 public void actionPerformed(ActionEvent evt) { 00215 if (needsRefresh) 00216 { 00217 //recreate the nodes. 00218 DefaultMutableTreeNode top = createNodes(); 00219 DefaultTreeModel model = new DefaultTreeModel(top); 00220 tree.setModel(model); 00221 invalidate(); 00222 needsRefresh = false; 00223 } 00224 } 00225 }; 00226 checkRefresh = new Timer(delay, taskPerformer); 00227 checkRefresh.start(); 00228 } 00229 00230 00231 private DefaultMutableTreeNode createNodes() { 00232 DefaultMutableTreeNode top; 00233 if (!connected) 00234 top = new DefaultMutableTreeNode("UNCONNECTED (attempting to connect to " 00235 + server + ")"); 00236 else 00237 { 00238 top = new DefaultMutableTreeNode("Connected to " + server); 00239 ChannelTree ct = getChannelTree(); 00240 if (ct == null) 00241 { 00242 top = new DefaultMutableTreeNode("No Channel Tree (connection dropped?)"); 00243 } 00244 else 00245 { 00246 Iterator i = ct.rootIterator(); 00247 while (i.hasNext()) 00248 { 00249 top.add(makeNodes((ChannelTree.Node)i.next())); 00250 } 00251 } 00252 } 00253 00254 return top; 00255 } 00256 00257 private DefaultMutableTreeNode makeNodes(ChannelTree.Node node) 00258 { 00259 DefaultMutableTreeNode root = new DefaultMutableTreeNode(new NodeCover(node)); 00260 List l = node.getChildren(); 00261 Iterator i = l.iterator(); 00262 while (i.hasNext()) 00263 { 00264 root.add(makeNodes((ChannelTree.Node)i.next())); 00265 } 00266 00267 return root; 00268 } 00269 00271 public void valueChanged(TreeSelectionEvent e) { 00272 DefaultMutableTreeNode node = (DefaultMutableTreeNode) 00273 tree.getLastSelectedPathComponent(); 00274 00275 if (node == null) return; 00276 Object nodeInfo = node.getUserObject(); 00277 if (nodeInfo instanceof NodeCover) 00278 { 00279 NodeCover nc = (NodeCover)nodeInfo; 00280 ChannelTree.Node ctNode = nc.node; 00281 displayMetaData(ctNode); 00282 } 00283 else 00284 { 00285 htmlPane.setText(nodeInfo.toString()); 00286 } 00287 } 00288 00289 protected void connect() 00290 { 00291 try { 00292 // Create a sink and connect: 00293 sink=new Sink(); 00294 sink.OpenRBNBConnection(server,"ChannelListRequest"); 00295 connected = true; 00296 System.out.println("ChannelList: Connection made to server = " 00297 + server + " requesting channel list."); 00298 } 00299 catch (SAPIException se) 00300 { 00301 System.out.println("ChannelList: Cannot connect to " 00302 + server + "; exception = " + se); 00303 } 00304 } 00305 00306 private ChannelTree getChannelTree() { 00307 try { 00308 sMap = new ChannelMap(); 00309 sink.RequestRegistration(); 00310 sMap = sink.Fetch(-1,sMap); 00311 return ChannelTree.createFromChannelMap(sMap); 00312 } 00313 catch (SAPIException se) 00314 { 00315 System.out.println("ChannelList: get channel tree failed. Reconnect?"); 00316 System.out.println("Exception = " + se); 00317 connected = false; 00318 } 00319 return null; 00320 } 00321 00322 private void displayMetaData(ChannelTree.Node node) { 00323 double start = node.getStart(); 00324 double duration = node.getDuration(); 00325 double end = start + duration; 00326 00327 long unixTime = (long)(start * 1000.0); // convert sec to millisec 00328 String startTime = DATE_FORMAT.format(new Date(unixTime)); 00329 unixTime = (long)(end * 1000.0); 00330 String endTime = DATE_FORMAT.format(new Date(unixTime)); 00331 00332 if (((node.getType()).toString()).equals("Channel")) 00333 htmlPane.setText( 00334 "FullName = " + node.getFullName() + "\n" + 00335 "Time (start, duration) = " + start + ", " + duration + "\n" + 00336 "[Assuming \"standard\" time:" + "\n" + 00337 " from " + startTime + "\n" + 00338 " to " + endTime + "]\n" + 00339 "Type = " + node.getType() + "\n" + 00340 "Mime type = " + node.getMime() + "\n" + 00341 "Size = " + node.getSize() 00342 ); 00343 else 00344 htmlPane.setText( 00345 "FullName = " + node.getFullName() + "\n" + 00346 "Type = " + node.getType() + "\n" 00347 ); 00348 } 00349 00350 protected void startCheckThread() 00351 { 00352 // Use this inner class to hide the public run method 00353 Runnable r = new Runnable() { 00354 public void run() { 00355 runWork(); 00356 } 00357 }; 00358 runit = true; 00359 timerThread = new Thread(r, "Timer"); 00360 timerThread.start(); 00361 System.out.println("Started checker thread."); 00362 } 00363 00364 private void stopThread() 00365 { 00366 runit = false; 00367 timerThread.interrupt(); 00368 System.out.println("Stopped checker thread."); 00369 } 00370 00371 private void runWork () 00372 { 00373 int delay = 10000; // 10 seconds 00374 while(runit) 00375 { 00376 if (!connected) 00377 { 00378 delay = 10000; // 10 seconds 00379 // try connecting 00380 connect(); 00381 if (connected) delay = 1000; // one second 00382 } 00383 else if (!sameTree(tree)) 00384 { 00385 System.out.println("Found mismatched tree"); 00386 needsRefresh = true; 00387 } 00388 try {Thread.sleep(delay);} catch (InterruptedException ignore) {} 00389 } 00390 timerThread = null; 00391 } 00392 00393 private boolean sameTree(JTree tree) 00394 { 00395 TreeModel m = tree.getModel(); 00396 ChannelTree ct = getChannelTree(); 00397 if (ct == null) return false; 00398 return sameTreeNodes(ct.rootIterator(),(DefaultMutableTreeNode)m.getRoot()); 00399 } 00400 00401 private boolean sameTreeNodes(Iterator i, DefaultMutableTreeNode tree) 00402 { 00403 // its the Iterator of the ChannelTree.Node's of this level of the tree 00404 00405 // if all the ChannelTree.Node's in the iterator are in the children of this tree 00406 // and all the decendent trees match, then the trees match. 00407 // (name equivalance is good enough) 00408 00409 if (tree.isLeaf() && !i.hasNext()) 00410 { 00411 // expected leaf node 00412 return true; 00413 } 00414 00415 if (tree.isLeaf() && i.hasNext()) 00416 { 00417 // unexpected leaf node 00418 return false; 00419 } 00420 00421 if (!tree.isLeaf() && !i.hasNext()) 00422 { 00423 // unexpected empty itereator 00424 return false; 00425 } 00426 00427 // not a leaf node... 00428 00429 // make a vector of all the names at this level 00430 Vector nodeList = new Vector(); 00431 int count = tree.getChildCount(); 00432 for (int k = 0; k < count; k++) 00433 { 00434 nodeList.add(tree.getChildAt(k)); 00435 } 00436 00437 while (i.hasNext()) 00438 { 00439 ChannelTree.Node n = (ChannelTree.Node)i.next(); 00440 Enumeration e = nodeList.elements(); 00441 DefaultMutableTreeNode found = null; 00442 while(e.hasMoreElements()) 00443 { 00444 DefaultMutableTreeNode test = (DefaultMutableTreeNode)e.nextElement(); 00445 Object nodeInfo = test.getUserObject(); 00446 NodeCover nc = (NodeCover)nodeInfo; 00447 ChannelTree.Node ctNode = nc.node; 00448 if (n.getName().equals(ctNode.getName())) 00449 { 00450 found = test; 00451 break; 00452 } 00453 } 00454 if (found == null) return false; 00455 nodeList.remove(found); 00456 if (!sameTreeNodes(n.getChildren().iterator(),found)) return false; 00457 } 00458 if (nodeList.size() > 0) 00459 { 00460 // extra nodes at this level 00461 return false; 00462 } 00463 return true; 00464 } 00465 00466 private class NodeCover 00467 { 00468 ChannelTree.Node node; 00469 00470 NodeCover(ChannelTree.Node node) 00471 { 00472 this.node = node; 00473 } 00474 00475 public String toString() 00476 { 00477 return node.getName(); 00478 } 00479 } 00480 }

Generated on Tue Aug 24 11:12:24 2004 for Data turbine for NEESGrid by doxygen 1.3.7