1 36 37 40 41 import javax.swing.*; 42 import javax.swing.event.*; 43 import java.awt.BorderLayout ; 44 import java.awt.Color ; 45 import java.awt.Dimension ; 46 import java.awt.FlowLayout ; 47 import java.awt.event.ActionEvent ; 48 import java.awt.event.ActionListener ; 49 import java.awt.event.WindowAdapter ; 50 import java.awt.event.WindowEvent ; 51 import java.util.*; 52 import javax.swing.border.*; 53 import javax.swing.tree.*; 54 55 75 76 public class SampleTree 77 { 78 79 protected JFrame frame; 80 81 protected JTree tree; 82 83 protected DefaultTreeModel treeModel; 84 85 88 public SampleTree() { 89 try { 91 UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); 92 } catch (Exception exc) { 96 System.err.println("Error loading L&F: " + exc); 97 } 98 99 100 JMenuBar menuBar = constructMenuBar(); 101 JPanel panel = new JPanel(true); 102 103 frame = new JFrame("SampleTree"); 104 frame.getContentPane().add("Center", panel); 105 frame.setJMenuBar(menuBar); 106 frame.setBackground(Color.lightGray); 107 108 109 DefaultMutableTreeNode root = createNewNode("Root"); 110 treeModel = new SampleTreeModel(root); 111 112 113 tree = new JTree(treeModel); 114 115 117 ToolTipManager.sharedInstance().registerComponent(tree); 118 119 121 tree.setCellRenderer(new SampleTreeCellRenderer()); 122 123 124 tree.setRowHeight(-1); 125 126 127 JScrollPane sp = new JScrollPane(); 128 sp.setPreferredSize(new Dimension (300, 300)); 129 sp.getViewport().add(tree); 130 131 132 panel.setLayout(new BorderLayout ()); 133 panel.add("Center", sp); 134 panel.add("South", constructOptionsPanel()); 135 136 frame.addWindowListener( new WindowAdapter () { 137 public void windowClosing(WindowEvent e) {System.exit(0);}}); 138 139 frame.pack(); 140 frame.show(); 141 } 142 143 145 private JPanel constructOptionsPanel() { 146 JCheckBox aCheckbox; 147 JPanel retPanel = new JPanel(false); 148 JPanel borderPane = new JPanel(false); 149 150 borderPane.setLayout(new BorderLayout ()); 151 retPanel.setLayout(new FlowLayout ()); 152 153 aCheckbox = new JCheckBox("show top level handles"); 154 aCheckbox.setSelected(tree.getShowsRootHandles()); 155 aCheckbox.addChangeListener(new ShowHandlesChangeListener()); 156 retPanel.add(aCheckbox); 157 158 aCheckbox = new JCheckBox("show root"); 159 aCheckbox.setSelected(tree.isRootVisible()); 160 aCheckbox.addChangeListener(new ShowRootChangeListener()); 161 retPanel.add(aCheckbox); 162 163 aCheckbox = new JCheckBox("editable"); 164 aCheckbox.setSelected(tree.isEditable()); 165 aCheckbox.addChangeListener(new TreeEditableChangeListener()); 166 aCheckbox.setToolTipText("Triple click to edit"); 167 retPanel.add(aCheckbox); 168 169 borderPane.add(retPanel, BorderLayout.CENTER); 170 171 173 ButtonGroup group = new ButtonGroup(); 174 JPanel buttonPane = new JPanel(false); 175 JRadioButton button; 176 177 buttonPane.setLayout(new FlowLayout ()); 178 buttonPane.setBorder(new TitledBorder("Selection Mode")); 179 button = new JRadioButton("Single"); 180 button.addActionListener(new AbstractAction() { 181 public boolean isEnabled() { return true; } 182 public void actionPerformed(ActionEvent e) { 183 tree.getSelectionModel().setSelectionMode 184 (TreeSelectionModel.SINGLE_TREE_SELECTION); 185 } 186 }); 187 group.add(button); 188 buttonPane.add(button); 189 button = new JRadioButton("Contiguous"); 190 button.addActionListener(new AbstractAction() { 191 public boolean isEnabled() { return true; } 192 public void actionPerformed(ActionEvent e) { 193 tree.getSelectionModel().setSelectionMode 194 (TreeSelectionModel.CONTIGUOUS_TREE_SELECTION); 195 } 196 }); 197 group.add(button); 198 buttonPane.add(button); 199 button = new JRadioButton("Discontiguous"); 200 button.addActionListener(new AbstractAction() { 201 public boolean isEnabled() { return true; } 202 public void actionPerformed(ActionEvent e) { 203 tree.getSelectionModel().setSelectionMode 204 (TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION); 205 } 206 }); 207 button.setSelected(true); 208 group.add(button); 209 buttonPane.add(button); 210 211 borderPane.add(buttonPane, BorderLayout.SOUTH); 212 213 238 return borderPane; 239 } 240 241 242 private JMenuBar constructMenuBar() { 243 JMenu menu; 244 JMenuBar menuBar = new JMenuBar(); 245 JMenuItem menuItem; 246 247 248 menu = new JMenu("File"); 249 menuBar.add(menu); 250 251 menuItem = menu.add(new JMenuItem("Exit")); 252 menuItem.addActionListener(new ActionListener () { 253 public void actionPerformed(ActionEvent e) { 254 System.exit(0); 255 }}); 256 257 258 menu = new JMenu("Tree"); 259 menuBar.add(menu); 260 261 menuItem = menu.add(new JMenuItem("Add")); 262 menuItem.addActionListener(new AddAction()); 263 264 menuItem = menu.add(new JMenuItem("Insert")); 265 menuItem.addActionListener(new InsertAction()); 266 267 menuItem = menu.add(new JMenuItem("Reload")); 268 menuItem.addActionListener(new ReloadAction()); 269 270 menuItem = menu.add(new JMenuItem("Remove")); 271 menuItem.addActionListener(new RemoveAction()); 272 273 return menuBar; 274 } 275 276 280 protected DefaultMutableTreeNode getSelectedNode() { 281 TreePath selPath = tree.getSelectionPath(); 282 283 if(selPath != null) 284 return (DefaultMutableTreeNode)selPath.getLastPathComponent(); 285 return null; 286 } 287 288 292 protected TreePath[] getSelectedPaths() { 293 return tree.getSelectionPaths(); 294 } 295 296 protected DefaultMutableTreeNode createNewNode(String name) { 297 return new DynamicTreeNode(new SampleData(null, Color.black, name)); 298 } 299 300 303 class AddAction extends Object implements ActionListener  304 { 305 306 public int addCount; 307 308 314 public void actionPerformed(ActionEvent e) { 315 DefaultMutableTreeNode lastItem = getSelectedNode(); 316 DefaultMutableTreeNode parent; 317 318 319 if(lastItem != null) { 320 parent = (DefaultMutableTreeNode)lastItem.getParent(); 321 if(parent == null) { 322 parent = (DefaultMutableTreeNode)treeModel.getRoot(); 323 lastItem = null; 324 } 325 } 326 else 327 parent = (DefaultMutableTreeNode)treeModel.getRoot(); 328 if (parent == null) { 329 treeModel.setRoot(createNewNode("Added " + 331 Integer.toString(addCount++))); 332 } 333 else { 334 int newIndex; 335 if(lastItem == null) 336 newIndex = treeModel.getChildCount(parent); 337 else 338 newIndex = parent.getIndex(lastItem) + 1; 339 340 341 treeModel.insertNodeInto(createNewNode("Added " + 342 Integer.toString(addCount++)), 343 parent, newIndex); 344 } 345 } 346 } 348 349 352 class InsertAction extends Object implements ActionListener  353 { 354 355 public int insertCount; 356 357 363 public void actionPerformed(ActionEvent e) { 364 DefaultMutableTreeNode lastItem = getSelectedNode(); 365 DefaultMutableTreeNode parent; 366 367 368 if(lastItem != null) { 369 parent = (DefaultMutableTreeNode)lastItem.getParent(); 370 if(parent == null) { 371 parent = (DefaultMutableTreeNode)treeModel.getRoot(); 372 lastItem = null; 373 } 374 } 375 else 376 parent = (DefaultMutableTreeNode)treeModel.getRoot(); 377 if (parent == null) { 378 treeModel.setRoot(createNewNode("Inserted " + 380 Integer.toString(insertCount++))); 381 } 382 else { 383 int newIndex; 384 385 if(lastItem == null) 386 newIndex = treeModel.getChildCount(parent); 387 else 388 newIndex = parent.getIndex(lastItem); 389 390 391 treeModel.insertNodeInto(createNewNode("Inserted " + 392 Integer.toString(insertCount++)), 393 parent, newIndex); 394 } 395 } 396 } 398 399 403 class ReloadAction extends Object implements ActionListener  404 { 405 410 public void actionPerformed(ActionEvent e) { 411 DefaultMutableTreeNode lastItem = getSelectedNode(); 412 413 if(lastItem != null) 414 treeModel.reload(lastItem); 415 } 416 } 418 422 class RemoveAction extends Object implements ActionListener  423 { 424 427 public void actionPerformed(ActionEvent e) { 428 TreePath[] selected = getSelectedPaths(); 429 430 if (selected != null && selected.length > 0) { 431 TreePath shallowest; 432 433 while ((shallowest = findShallowestPath(selected)) != null) { 444 removeSiblings(shallowest, selected); 445 } 446 } 447 } 448 449 453 private void removeSiblings(TreePath path, TreePath[] paths) { 454 if (path.getPathCount() == 1) { 456 for (int counter = paths.length - 1; counter >= 0; counter--) { 458 paths[counter] = null; 459 } 460 treeModel.setRoot(null); 461 } 462 else { 463 TreePath parent = path.getParentPath(); 465 MutableTreeNode parentNode = (MutableTreeNode)parent. 466 getLastPathComponent(); 467 ArrayList toRemove = new ArrayList(); 468 int depth = parent.getPathCount(); 469 470 for (int counter = paths.length - 1; counter >= 0; counter--) { 472 if (paths[counter] != null && paths[counter]. 473 getParentPath().equals(parent)) { 474 toRemove.add(paths[counter]); 475 paths[counter] = null; 476 } 477 } 478 479 int rCount = toRemove.size(); 484 for (int counter = paths.length - 1; counter >= 0; counter--) { 485 if (paths[counter] != null) { 486 for (int rCounter = rCount - 1; rCounter >= 0; 487 rCounter--) { 488 if (((TreePath)toRemove.get(rCounter)). 489 isDescendant(paths[counter])) { 490 paths[counter] = null; 491 } 492 } 493 } 494 } 495 496 if (rCount > 1) { 498 Collections.sort(toRemove, new PositionComparator()); 499 } 500 int[] indices = new int[rCount]; 501 Object [] removedNodes = new Object [rCount]; 502 for (int counter = rCount - 1; counter >= 0; counter--) { 503 removedNodes[counter] = ((TreePath)toRemove.get(counter)). 504 getLastPathComponent(); 505 indices[counter] = treeModel.getIndexOfChild 506 (parentNode, removedNodes[counter]); 507 parentNode.remove(indices[counter]); 508 } 509 treeModel.nodesWereRemoved(parentNode, indices, removedNodes); 510 } 511 } 512 513 518 private TreePath findShallowestPath(TreePath[] paths) { 519 int shallowest = -1; 520 TreePath shallowestPath = null; 521 522 for (int counter = paths.length - 1; counter >= 0; counter--) { 523 if (paths[counter] != null) { 524 if (shallowest != -1) { 525 if (paths[counter].getPathCount() < shallowest) { 526 shallowest = paths[counter].getPathCount(); 527 shallowestPath = paths[counter]; 528 if (shallowest == 1) { 529 return shallowestPath; 530 } 531 } 532 } 533 else { 534 shallowestPath = paths[counter]; 535 shallowest = paths[counter].getPathCount(); 536 } 537 } 538 } 539 return shallowestPath; 540 } 541 542 543 550 private class PositionComparator implements Comparator { 551 public int compare(Object o1, Object o2) { 552 TreePath p1 = (TreePath)o1; 553 int o1Index = treeModel.getIndexOfChild(p1.getParentPath(). 554 getLastPathComponent(), p1.getLastPathComponent()); 555 TreePath p2 = (TreePath)o2; 556 int o2Index = treeModel.getIndexOfChild(p2.getParentPath(). 557 getLastPathComponent(), p2.getLastPathComponent()); 558 return o1Index - o2Index; 559 } 560 561 public boolean equals(Object obj) { 562 return super.equals(obj); 563 } 564 } 565 566 } 568 569 573 class ShowHandlesChangeListener extends Object implements ChangeListener 574 { 575 public void stateChanged(ChangeEvent e) { 576 tree.setShowsRootHandles(((JCheckBox)e.getSource()).isSelected()); 577 } 578 579 } 581 582 586 class ShowRootChangeListener extends Object implements ChangeListener 587 { 588 public void stateChanged(ChangeEvent e) { 589 tree.setRootVisible(((JCheckBox)e.getSource()).isSelected()); 590 } 591 592 } 594 595 600 class TreeEditableChangeListener extends Object implements ChangeListener 601 { 602 public void stateChanged(ChangeEvent e) { 603 tree.setEditable(((JCheckBox)e.getSource()).isSelected()); 604 } 605 606 } 608 609 static public void main(String args[]) { 610 new SampleTree(); 611 } 612 613 } 614 | Popular Tags |