1 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 ; 11 import javax.swing.event.TableModelListener ; 12 import javax.swing.event.TreeSelectionEvent ; 13 import javax.swing.event.TreeSelectionListener ; 14 import javax.swing.table.DefaultTableModel ; 15 import javax.swing.table.TableColumn ; 16 import javax.swing.tree.*; 17 import java.awt.*; 18 import java.awt.event.*; 19 import java.io.File ; 20 import java.util.*; 21 22 23 28 public class ReplicatedTreeDemo { 29 30 31 41 static class ReplicatedTreeView extends JFrame implements WindowListener, ReplicatedTree.ReplicatedTreeListener, 42 TreeSelectionListener , TableModelListener { 43 DefaultTreeModel tree_model=null; 44 JTree jtree=null; 45 final DefaultTableModel table_model=new DefaultTableModel (); 46 final JTable table=new JTable(table_model); 47 final MyNode root=new MyNode(SEP); 48 final String props=null; 49 String selected_node=null; 50 ReplicatedTree tree=null; JPanel tablePanel=null; 52 JMenu operationsMenu=null; 53 JPopupMenu operationsPopup=null; 54 JMenuBar menubar=null; 55 static final String 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 title) throws Exception { 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 []{"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); 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 evt) { 144 int row, col; 145 String key, val; 146 147 if(evt.getType() == TableModelEvent.UPDATE) { 148 row=evt.getFirstRow(); 149 col=evt.getColumn(); 150 if(col == 0) { key=(String )table_model.getValueAt(row, col); 152 val=(String )table_model.getValueAt(row, col + 1); 153 if(key != null && val != null) { 154 tree.put(selected_node, key, val); 155 } 156 } 157 else { key=(String )table_model.getValueAt(row, col - 1); 159 val=(String )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 evt) { 169 TreePath path=evt.getPath(); 170 String fqn=SEP; 171 String 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 199 200 public void nodeAdded(String 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 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 fqn) { 225 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 245 246 247 248 public void run() { 249 250 } 251 252 253 254 255 256 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 275 private void populateTree() { 276 addGuiNode(SEP); 277 } 278 279 280 283 void addGuiNode(String fqn) { 284 Set children; 285 String child_name; 286 287 if(fqn == null) return; 288 289 root.add(fqn); 291 292 children=tree.getChildrenNames(fqn); 294 if(children != null) { 295 for(Iterator it=children.iterator(); it.hasNext();) { 296 child_name=(String )it.next(); 297 addGuiNode(fqn + SEP + child_name); 298 } 299 } 300 } 301 302 303 String makeFQN(Object [] path) { 304 StringBuffer sb=new StringBuffer (""); 305 String 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 key, strval="<null>"; 336 Object 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 )entry.getKey(); 348 val=entry.getValue(); 349 if(val != null) strval=val.toString(); 350 table_model.addRow(new Object []{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 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 fqn) { 392 HashMap data; 393 Set keys; 394 String key; 395 Object 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 )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 414 415 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 [] information={"Enter fully qualified name", 428 fqnTextField}; 429 final String btnString1="OK"; 430 final String btnString2="Cancel"; 431 Object [] 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 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 504 505 class MyNode extends DefaultMutableTreeNode { 506 String name="<unnamed>"; 507 508 509 MyNode(String name) { 510 this.name=name; 511 } 512 513 514 518 public MyNode add(String fqn) { 519 MyNode curr, n, ret=null; 520 StringTokenizer tok; 521 String 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 544 public void remove(String fqn) { 545 removeFromParent(); 546 } 547 548 549 MyNode findNode(String fqn) { 550 MyNode curr, n; 551 StringTokenizer tok; 552 String 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 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 print(int indent) { 588 StringBuffer sb=new StringBuffer (); 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 toString() { 613 return name; 614 } 615 616 } 617 618 619 } 620 621 622 public static void main(String args[]) { 623 ReplicatedTree tree; 624 String start_directory=null; 625 626 String 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 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 660 if(start_directory != null && start_directory.length() > 0) { 661 populateTree(tree, start_directory); 662 } 663 else { 664 673 } 674 } 675 catch(Exception 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 dir) { 687 File file=new File (dir); 688 689 if(!file.exists()) return; 690 tree.put(dir, null); 691 692 if(file.isDirectory()) { 693 String [] 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 |