KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jgroups > demos > ReplicatedTreeDemo


1 // $Id: ReplicatedTreeDemo.java,v 1.6 2004/09/23 16:29:35 belaban Exp $
2

3 package org.jgroups.demos;
4
5
6 import org.jgroups.View;
7 import org.jgroups.blocks.ReplicatedTree;
8
9 import javax.swing.*;
10 import javax.swing.event.TableModelEvent JavaDoc;
11 import javax.swing.event.TableModelListener JavaDoc;
12 import javax.swing.event.TreeSelectionEvent JavaDoc;
13 import javax.swing.event.TreeSelectionListener JavaDoc;
14 import javax.swing.table.DefaultTableModel JavaDoc;
15 import javax.swing.table.TableColumn JavaDoc;
16 import javax.swing.tree.*;
17 import java.awt.*;
18 import java.awt.event.*;
19 import java.io.File JavaDoc;
20 import java.util.*;
21
22
23 /**
24  * Graphical view of a ReplicatedTree
25  *
26  * @author Bela Ban
27  */

28 public class ReplicatedTreeDemo {
29
30
31     /**
32      * Graphical view of a ReplicatedTree (using the MVC paradigm). An instance of this class needs to be given a
33      * reference to the underlying model (ReplicatedTree) and needs to registers as a ReplicatedTreeListener. Changes
34      * to the tree structure are propagated from the model to the view (via ReplicatedTreeListener), changes from the
35      * GUI (e.g. by a user) are executed on the tree model (which will broadcast the changes to all replicas).<p>
36      * The view itself caches only the nodes, but doesn't cache any of the data (HashMap) associated with it. When
37      * data needs to be displayed, the underlying tree will be accessed directly.
38      *
39      * @author Bela Ban
40      */

41     static class ReplicatedTreeView extends JFrame implements WindowListener, ReplicatedTree.ReplicatedTreeListener,
42             TreeSelectionListener JavaDoc, TableModelListener JavaDoc {
43         DefaultTreeModel tree_model=null;
44         JTree jtree=null;
45         final DefaultTableModel JavaDoc table_model=new DefaultTableModel JavaDoc();
46         final JTable table=new JTable(table_model);
47         final MyNode root=new MyNode(SEP);
48         final String JavaDoc props=null;
49         String JavaDoc selected_node=null;
50         ReplicatedTree tree=null; // the underlying model
51
JPanel tablePanel=null;
52         JMenu operationsMenu=null;
53         JPopupMenu operationsPopup=null;
54         JMenuBar menubar=null;
55         static final String JavaDoc SEP=ReplicatedTree.SEPARATOR;
56         private static final int KEY_COL_WIDTH=20;
57         private static final int VAL_COL_WIDTH=300;
58
59
60         public ReplicatedTreeView(ReplicatedTree tree, Object JavaDoc title) throws Exception JavaDoc {
61             this.tree=tree;
62             tree.addReplicatedTreeListener(this);
63
64             addNotify();
65             setTitle("ReplicatedTreeDemo: mbr=" + title);
66
67             tree_model=new DefaultTreeModel(root);
68             jtree=new JTree(tree_model);
69             jtree.setDoubleBuffered(true);
70             jtree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
71
72             JScrollPane scroll_pane=new JScrollPane(jtree);
73
74             populateTree();
75
76             getContentPane().add(scroll_pane, BorderLayout.CENTER);
77             addWindowListener(this);
78
79             table_model.setColumnIdentifiers(new String JavaDoc[]{"Name", "Value"});
80             table_model.addTableModelListener(this);
81
82             setTableColumnWidths();
83
84             tablePanel=new JPanel();
85             tablePanel.setLayout(new BorderLayout());
86             tablePanel.add(table.getTableHeader(), BorderLayout.NORTH);
87             tablePanel.add(table, BorderLayout.CENTER);
88
89             getContentPane().add(tablePanel, BorderLayout.SOUTH);
90
91             jtree.addTreeSelectionListener(this);//REVISIT
92

93             MouseListener ml=new MouseAdapter() {
94                 public void mouseClicked(MouseEvent e) {
95                     int selRow=jtree.getRowForLocation(e.getX(), e.getY());
96                     TreePath selPath=jtree.getPathForLocation(e.getX(), e.getY());
97                     if(selRow != -1) {
98                         selected_node=makeFQN(selPath.getPath());
99                         jtree.setSelectionPath(selPath);
100
101                         if(e.getModifiers() == java.awt.event.InputEvent.BUTTON3_MASK) {
102                             operationsPopup.show(e.getComponent(),
103                                     e.getX(), e.getY());
104                         }
105                     }
106                 }
107             };
108
109             jtree.addMouseListener(ml);
110
111             createMenus();
112             setLocation(50, 50);
113             setSize(getInsets().left + getInsets().right + 485,
114                     getInsets().top + getInsets().bottom + 367);
115
116             init();
117             setVisible(true);
118         }
119
120         public void windowClosed(WindowEvent event) {
121         }
122
123         public void windowDeiconified(WindowEvent event) {
124         }
125
126         public void windowIconified(WindowEvent event) {
127         }
128
129         public void windowActivated(WindowEvent event) {
130         }
131
132         public void windowDeactivated(WindowEvent event) {
133         }
134
135         public void windowOpened(WindowEvent event) {
136         }
137
138         public void windowClosing(WindowEvent event) {
139             System.exit(0);
140         }
141
142
143         public void tableChanged(TableModelEvent JavaDoc evt) {
144             int row, col;
145             String JavaDoc key, val;
146
147             if(evt.getType() == TableModelEvent.UPDATE) {
148                 row=evt.getFirstRow();
149                 col=evt.getColumn();
150                 if(col == 0) { // set()
151
key=(String JavaDoc)table_model.getValueAt(row, col);
152                     val=(String JavaDoc)table_model.getValueAt(row, col + 1);
153                     if(key != null && val != null) {
154                         tree.put(selected_node, key, val);
155                     }
156                 }
157                 else { // add()
158
key=(String JavaDoc)table_model.getValueAt(row, col - 1);
159                     val=(String JavaDoc)table.getValueAt(row, col);
160                     if(key != null && val != null) {
161                         tree.put(selected_node, key, val);
162                     }
163                 }
164             }
165         }
166
167
168         public void valueChanged(TreeSelectionEvent JavaDoc evt) {
169             TreePath path=evt.getPath();
170             String JavaDoc fqn=SEP;
171             String JavaDoc component_name;
172             HashMap data=null;
173
174             for(int i=0; i < path.getPathCount(); i++) {
175                 component_name=((MyNode)path.getPathComponent(i)).name;
176                 if(component_name.equals(SEP))
177                     continue;
178                 if(fqn.equals(SEP))
179                     fqn+=component_name;
180                 else
181                     fqn=fqn + SEP + component_name;
182             }
183             data=getData(tree, fqn);
184             if(data != null) {
185                 getContentPane().add(tablePanel, BorderLayout.SOUTH);
186                 populateTable(data);
187                 validate();
188             }
189             else {
190                 clearTable();
191                 getContentPane().remove(tablePanel);
192                 validate();
193             }
194         }
195
196
197
198         /* ------------------ ReplicatedTree.ReplicatedTreeListener interface ------------ */
199
200         public void nodeAdded(String JavaDoc fqn) {
201             MyNode n, p;
202
203             n=root.add(fqn);
204             if(n != null) {
205                 p=(MyNode)n.getParent();
206                 tree_model.reload(p);
207                 jtree.scrollPathToVisible(new TreePath(n.getPath()));
208             }
209         }
210
211         public void nodeRemoved(String JavaDoc fqn) {
212             MyNode n;
213             TreeNode par;
214
215             n=root.findNode(fqn);
216             if(n != null) {
217                 n.removeAllChildren();
218                 par=n.getParent();
219                 n.removeFromParent();
220                 tree_model.reload(par);
221             }
222         }
223
224         public void nodeModified(String JavaDoc fqn) {
225 // HashMap data;
226
// data=getData(tree, fqn);
227
//populateTable(data); REVISIT
228
/*
229               poulateTable is the current table being shown is the info of the node. that is modified.
230             */

231         }
232
233         public void viewChange(View new_view) {
234             Vector mbrship;
235             if(new_view != null && (mbrship=new_view.getMembers()) != null) {
236                 tree._put(SEP, "members", mbrship);
237                 tree._put(SEP, "coordinator", mbrship.firstElement());
238             }
239         }
240
241
242
243
244         /* ---------------- End of ReplicatedTree.ReplicatedTreeListener interface -------- */
245
246         /*----------------- Runnable implementation to make View change calles in AWT Thread ---*/
247
248         public void run() {
249
250         }
251
252
253
254         /* ----------------------------- Private Methods ---------------------------------- */
255
256         /**
257          * Fetches all data from underlying tree model and display it graphically
258          */

259         void init() {
260             Vector mbrship=null;
261
262             addGuiNode(SEP);
263
264             mbrship=tree != null && tree.getMembers() != null ? (Vector)tree.getMembers().clone() : null;
265             if(mbrship != null) {
266                 tree._put(SEP, "members", mbrship);
267                 tree._put(SEP, "coordinator", mbrship.firstElement());
268             }
269         }
270
271
272         /**
273          * Fetches all data from underlying tree model and display it graphically
274          */

275         private void populateTree() {
276             addGuiNode(SEP);
277         }
278
279
280         /**
281          * Recursively adds GUI nodes starting from fqn
282          */

283         void addGuiNode(String JavaDoc fqn) {
284             Set children;
285             String JavaDoc child_name;
286
287             if(fqn == null) return;
288
289             // 1 . Add myself
290
root.add(fqn);
291
292             // 2. Then add my children
293
children=tree.getChildrenNames(fqn);
294             if(children != null) {
295                 for(Iterator it=children.iterator(); it.hasNext();) {
296                     child_name=(String JavaDoc)it.next();
297                     addGuiNode(fqn + SEP + child_name);
298                 }
299             }
300         }
301
302
303         String JavaDoc makeFQN(Object JavaDoc[] path) {
304             StringBuffer JavaDoc sb=new StringBuffer JavaDoc("");
305             String JavaDoc tmp_name;
306
307             if(path == null) return null;
308             for(int i=0; i < path.length; i++) {
309                 tmp_name=((MyNode)path[i]).name;
310                 if(tmp_name.equals(SEP))
311                     continue;
312                 else
313                     sb.append(SEP + tmp_name);
314             }
315             tmp_name=sb.toString();
316             if(tmp_name.length() == 0)
317                 return SEP;
318             else
319                 return tmp_name;
320         }
321
322         void clearTable() {
323             int num_rows=table.getRowCount();
324
325             if(num_rows > 0) {
326                 for(int i=0; i < num_rows; i++)
327                     table_model.removeRow(0);
328                 table_model.fireTableRowsDeleted(0, num_rows - 1);
329                 repaint();
330             }
331         }
332
333
334         void populateTable(HashMap data) {
335             String JavaDoc key, strval="<null>";
336             Object JavaDoc val;
337             int num_rows=0;
338             Map.Entry entry;
339
340             if(data == null) return;
341             num_rows=data.size();
342             clearTable();
343
344             if(num_rows > 0) {
345                 for(Iterator it=data.entrySet().iterator(); it.hasNext();) {
346                     entry=(Map.Entry)it.next();
347                     key=(String JavaDoc)entry.getKey();
348                     val=entry.getValue();
349                     if(val != null) strval=val.toString();
350                     table_model.addRow(new Object JavaDoc[]{key, strval});
351                 }
352                 table_model.fireTableRowsInserted(0, num_rows - 1);
353                 validate();
354             }
355         }
356
357         private void setTableColumnWidths() {
358             table.sizeColumnsToFit(JTable.AUTO_RESIZE_NEXT_COLUMN);
359             TableColumn JavaDoc column=null;
360             column=table.getColumnModel().getColumn(0);
361             column.setMinWidth(KEY_COL_WIDTH);
362             column.setPreferredWidth(KEY_COL_WIDTH);
363             column=table.getColumnModel().getColumn(1);
364             column.setPreferredWidth(VAL_COL_WIDTH);
365         }
366
367         private void createMenus() {
368             menubar=new JMenuBar();
369             operationsMenu=new JMenu("Operations");
370             AddNodeAction addNode=new AddNodeAction();
371             addNode.putValue(AbstractAction.NAME, "Add to this node");
372             RemoveNodeAction removeNode=new RemoveNodeAction();
373             removeNode.putValue(AbstractAction.NAME, "Remove this node");
374             AddModifyDataForNodeAction addModAction=new AddModifyDataForNodeAction();
375             addModAction.putValue(AbstractAction.NAME, "Add/Modify data");
376             ExitAction exitAction=new ExitAction();
377             exitAction.putValue(AbstractAction.NAME, "Exit");
378             operationsMenu.add(addNode);
379             operationsMenu.add(removeNode);
380             operationsMenu.add(addModAction);
381             operationsMenu.add(exitAction);
382             menubar.add(operationsMenu);
383             setJMenuBar(menubar);
384
385             operationsPopup=new JPopupMenu();
386             operationsPopup.add(addNode);
387             operationsPopup.add(removeNode);
388             operationsPopup.add(addModAction);
389         }
390
391         HashMap getData(ReplicatedTree tree, String JavaDoc fqn) {
392             HashMap data;
393             Set keys;
394             String JavaDoc key;
395             Object JavaDoc value;
396
397             if(tree == null || fqn == null) return null;
398             keys=tree.getKeys(fqn);
399             if(keys == null) return null;
400             data=new HashMap();
401             for(Iterator it=keys.iterator(); it.hasNext();) {
402                 key=(String JavaDoc)it.next();
403                 value=tree.get(fqn, key);
404                 if(value != null)
405                     data.put(key, value);
406             }
407             return data;
408         }
409
410
411
412
413         /* -------------------------- End of Private Methods ------------------------------ */
414
415         /*----------------------- Actions ---------------------------*/
416         class ExitAction extends AbstractAction {
417             public void actionPerformed(ActionEvent e) {
418                 System.exit(0);
419             }
420         }
421
422         class AddNodeAction extends AbstractAction {
423             public void actionPerformed(ActionEvent e) {
424                 JTextField fqnTextField=new JTextField();
425                 if(selected_node != null)
426                     fqnTextField.setText(selected_node);
427                 Object JavaDoc[] information={"Enter fully qualified name",
428                                       fqnTextField};
429                 final String JavaDoc btnString1="OK";
430                 final String JavaDoc btnString2="Cancel";
431                 Object JavaDoc[] options={btnString1, btnString2};
432                 int userChoice=JOptionPane.showOptionDialog(null,
433                         information,
434                         "Add Node",
435                         JOptionPane.YES_NO_OPTION,
436                         JOptionPane.PLAIN_MESSAGE,
437                         null,
438                         options,
439                         options[0]);
440                 if(userChoice == 0) {
441                     String JavaDoc userInput=fqnTextField.getText();
442                     tree.put(userInput, null);
443                 }
444             }
445         }
446
447         class RemoveNodeAction extends AbstractAction {
448             public void actionPerformed(ActionEvent e) {
449                 tree.remove(selected_node);
450             }
451         }
452
453         class AddModifyDataForNodeAction extends AbstractAction {
454             public void actionPerformed(ActionEvent e) {
455                 HashMap data=getData(tree, selected_node);
456                 if(data != null) {
457                 }
458                 else {
459                     clearTable();
460                     data=new HashMap();
461                     data.put("Add Key", "Add Value");
462
463                 }
464                 populateTable(data);
465                 getContentPane().add(tablePanel, BorderLayout.SOUTH);
466                 validate();
467
468             }
469         }
470
471
472 // public static void main(String args[]) {
473
// ReplicatedTree tree;
474
//
475
// for(int i=0; i < args.length; i++) {
476
// if(args[i].equals("-help")) {
477
// System.out.println("ReplicatedTreeView [-help]");
478
// return;
479
// }
480
// }
481
//
482
// try {
483
// tree=new ReplicatedTree(null);
484
// tree.setRemoteCalls(false);
485
// HashMap map=new HashMap();
486
// map.put("name", "Framework");
487
// map.put("pid", new Integer(322649));
488
// tree.put("/federations/fed1/servers/Framework", map);
489
// tree.put("/federations/fed1/servers/Security", null);
490
//
491
// // demo.setVisible(true);
492
// new ReplicatedTreeView(tree, "<null address>");
493
//
494
// tree.put("/federations/fed1/servers/Security/components/RuntimeMonitor", null);
495
// tree.put("/federations/fed1/servers/fenics", null);
496
//
497
//
498
// }
499
// catch(Exception ex) {
500
// ex.printStackTrace(System.err);
501
// }
502
// }
503

504
505         class MyNode extends DefaultMutableTreeNode {
506             String JavaDoc name="<unnamed>";
507
508
509             MyNode(String JavaDoc name) {
510                 this.name=name;
511             }
512
513
514             /**
515              * Adds a new node to the view. Intermediary nodes will be created if they don't yet exist.
516              * Returns the first node that was created or null if node already existed
517              */

518             public MyNode add(String JavaDoc fqn) {
519                 MyNode curr, n, ret=null;
520                 StringTokenizer tok;
521                 String JavaDoc child_name;
522
523                 if(fqn == null) return null;
524                 curr=this;
525                 tok=new StringTokenizer(fqn, ReplicatedTreeView.SEP);
526
527                 while(tok.hasMoreTokens()) {
528                     child_name=tok.nextToken();
529                     n=curr.findChild(child_name);
530                     if(n == null) {
531                         n=new MyNode(child_name);
532                         if(ret == null) ret=n;
533                         curr.add(n);
534                     }
535                     curr=n;
536                 }
537                 return ret;
538             }
539
540
541             /**
542              * Removes a node from the view. Child nodes will be removed as well
543              */

544             public void remove(String JavaDoc fqn) {
545                 removeFromParent();
546             }
547
548
549             MyNode findNode(String JavaDoc fqn) {
550                 MyNode curr, n;
551                 StringTokenizer tok;
552                 String JavaDoc child_name;
553
554                 if(fqn == null) return null;
555                 curr=this;
556                 tok=new StringTokenizer(fqn, ReplicatedTreeView.SEP);
557
558                 while(tok.hasMoreTokens()) {
559                     child_name=tok.nextToken();
560                     n=curr.findChild(child_name);
561                     if(n == null)
562                         return null;
563                     curr=n;
564                 }
565                 return curr;
566             }
567
568
569             MyNode findChild(String JavaDoc relative_name) {
570                 MyNode child;
571
572                 if(relative_name == null || getChildCount() == 0)
573                     return null;
574                 for(int i=0; i < getChildCount(); i++) {
575                     child=(MyNode)getChildAt(i);
576                     if(child.name == null) {
577                         continue;
578                     }
579
580                     if(child.name.equals(relative_name))
581                         return child;
582                 }
583                 return null;
584             }
585
586
587             String JavaDoc print(int indent) {
588                 StringBuffer JavaDoc sb=new StringBuffer JavaDoc();
589
590                 for(int i=0; i < indent; i++)
591                     sb.append(' ');
592                 if(!isRoot()) {
593                     if(name == null)
594                         sb.append("/<unnamed>");
595                     else {
596                         sb.append(ReplicatedTreeView.SEP + name);
597                     }
598                 }
599                 sb.append('\n');
600                 if(getChildCount() > 0) {
601                     if(isRoot())
602                         indent=0;
603                     else
604                         indent+=4;
605                     for(int i=0; i < getChildCount(); i++)
606                         sb.append(((MyNode)getChildAt(i)).print(indent));
607                 }
608                 return sb.toString();
609             }
610
611
612             public String JavaDoc toString() {
613                 return name;
614             }
615
616         }
617
618
619     }
620
621
622     public static void main(String JavaDoc args[]) {
623         ReplicatedTree tree;
624         String JavaDoc start_directory=null;
625
626         String JavaDoc props="UDP(mcast_addr=224.0.0.36;mcast_port=55566;ip_ttl=32;" +
627                 "mcast_send_buf_size=150000;mcast_recv_buf_size=80000):" +
628                 "PING(timeout=2000;num_initial_members=3):" +
629                 "MERGE2(min_interval=5000;max_interval=10000):" +
630                 "FD_SOCK:" +
631                 "VERIFY_SUSPECT(timeout=1500):" +
632                 "pbcast.NAKACK(gc_lag=50;retransmit_timeout=600,1200,2400,4800):" +
633                 "UNICAST(timeout=600,1200,2400,4800):" +
634                 "pbcast.STABLE(desired_avg_gossip=20000):" +
635                 "FRAG(frag_size=16000;down_thread=false;up_thread=false):" +
636                 "pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;" +
637                 "shun=false;print_local_addr=true):" +
638                 "pbcast.STATE_TRANSFER";
639         // "PERF(details=true)";
640

641
642         for(int i=0; i < args.length; i++) {
643             if("-props".equals(args[i])) {
644                 props=args[++i];
645                 continue;
646             }
647             if("-start_directory".equals(args[i])) {
648                 start_directory=args[++i];
649                 continue;
650             }
651             help();
652             return;
653         }
654
655         try {
656             tree=new ReplicatedTree("ReplicatedTreeDemo-Group", props, 10000);
657             new ReplicatedTreeView(tree, tree.getLocalAddress());
658             // demo.setVisible(true);
659

660             if(start_directory != null && start_directory.length() > 0) {
661                 populateTree(tree, start_directory);
662             }
663             else {
664                 /*
665                 HashMap map=new HashMap();
666                 map.put("name", "Framework");
667                 map.put("pid", new Integer(322649));
668                 tree.put("/federations/fed1/servers/Framework", map);
669                 tree.put("/federations/fed1/servers/Security", null);
670                 tree.put("/federations/fed1/servers/Security/components/RuntimeMonitor", null);
671                 tree.put("/federations/fed1/servers/fenics", null);
672                 */

673             }
674         }
675         catch(Exception JavaDoc ex) {
676             ex.printStackTrace(System.err);
677         }
678     }
679
680
681     static void help() {
682         System.out.println("ReplicatedTreeView [-help] " +
683                 "[-props <channel properties>] [-start_directory <dirname>]");
684     }
685
686     static void populateTree(ReplicatedTree tree, String JavaDoc dir) {
687         File JavaDoc file=new File JavaDoc(dir);
688
689         if(!file.exists()) return;
690         tree.put(dir, null);
691
692         if(file.isDirectory()) {
693             String JavaDoc[] children=file.list();
694             if(children != null && children.length > 0) {
695                 for(int i=0; i < children.length; i++)
696                     populateTree(tree, dir + '/' + children[i]);
697             }
698         }
699     }
700
701
702 }
703
704
705
706
707
708
709
710
711
Popular Tags