1 14 package org.compiere.grid.tree; 15 16 import java.awt.*; 17 import java.awt.dnd.*; 18 import java.awt.datatransfer.*; 19 import java.awt.event.*; 20 import javax.swing.*; 21 import java.util.*; 22 import javax.swing.*; 23 import javax.swing.tree.*; 24 import java.sql.*; 25 26 import org.compiere.apps.*; 27 import org.compiere.model.*; 28 import org.compiere.util.*; 29 import org.compiere.plaf.*; 30 import org.compiere.swing.*; 31 32 47 public final class VTreePanel extends CPanel 48 implements ActionListener, DragGestureListener, DragSourceListener, DropTargetListener 49 { 50 57 public VTreePanel(int WindowNo, boolean hasBar, boolean editable) 58 { 59 super(); 60 Log.trace(Log.l3_Util, "VTreePanel", "Bar=" + hasBar + ", Editable=" + editable); 61 m_WindowNo = WindowNo; 62 m_hasBar = hasBar; 63 m_editable = editable; 64 65 jbInit(); 67 if (!hasBar) 68 { 69 bar.setPreferredSize(new Dimension(0,0)); 70 centerSplitPane.setDividerLocation(0); 71 centerSplitPane.setDividerSize(0); 72 popMenuTree.remove(mBarAdd); 73 } 74 else 75 centerSplitPane.setDividerLocation(80); 76 if (editable) 78 tree.setDropTarget(dropTarget); 79 else 80 { 81 popMenuTree.remove(mFrom); 82 popMenuTree.remove(mTo); 83 } 84 } 86 92 public boolean initTree (int AD_Tree_ID) 93 { 94 Log.trace(Log.l3_Util, "VTreePanel.initTree " + AD_Tree_ID); 95 m_AD_Tree_ID = AD_Tree_ID; 97 98 MTree vTree = new MTree (Env.getCtx(), AD_Tree_ID, m_editable); 100 m_root = vTree.getRoot(); 101 m_nodeTableName = vTree.getNodeTableName(); 102 treeModel = new DefaultTreeModel(m_root, true); 103 tree.setModel(treeModel); 104 105 if (m_hasBar) 107 { 108 bar.removeAll(); Enumeration en = m_root.preorderEnumeration(); 110 while (en.hasMoreElements()) 111 { 112 MTreeNode nd = (MTreeNode)en.nextElement(); 113 if (nd.isOnBar()) 114 addToBar(nd); 115 } 116 } 117 118 return true; 119 } 121 122 private BorderLayout mainLayout = new BorderLayout(); 123 private JTree tree = new JTree(); 124 private DefaultTreeModel treeModel; 125 private DefaultTreeSelectionModel treeSelect = new DefaultTreeSelectionModel(); 126 private CPanel southPanel = new CPanel(); 127 private CCheckBox treeExpand = new CCheckBox(); 128 private CTextField treeSearch = new CTextField(10); 129 private JPopupMenu popMenuTree = new JPopupMenu(); 130 private JPopupMenu popMenuBar = new JPopupMenu(); 131 private JMenuItem mFrom = new JMenuItem(); 132 private JMenuItem mTo = new JMenuItem(); 133 private CPanel bar = new CPanel(); 134 private JMenuItem mBarAdd = new JMenuItem(); 135 private JMenuItem mBarRemove = new JMenuItem(); 136 private BorderLayout southLayout = new BorderLayout(); 137 private JSplitPane centerSplitPane = new JSplitPane(); 138 private JScrollPane treePane = new JScrollPane(); 139 private MouseListener mouseListener = new VTreePanel_mouseAdapter(this); 140 private KeyListener keyListener = new VTreePanel_keyAdapter(this); 141 142 private int m_WindowNo; 144 145 private int m_AD_Tree_ID = 0; 146 147 private String m_nodeTableName = null; 148 149 private boolean m_editable; 150 151 private boolean m_hasBar; 152 153 private MTreeNode m_root = null; 154 155 156 private MTreeNode m_moveNode; private String m_search = ""; 158 private Enumeration m_nodeEn; 159 private MTreeNode m_selectedNode; private CButton m_buttonSelected; 161 162 public static final String NODE_SELECTION = "NodeSelected"; 164 165 176 private void jbInit() 177 { 178 this.setLayout(mainLayout); 179 mainLayout.setVgap(5); 180 treeSelect.setSelectionMode(DefaultTreeSelectionModel.SINGLE_TREE_SELECTION); 183 tree.setSelectionModel(treeSelect); 184 tree.setEditable(false); tree.addMouseListener(mouseListener); 187 tree.addKeyListener(keyListener); 188 tree.setCellRenderer(new VTreeCellRenderer()); 189 treePane.getViewport().add(tree, null); 190 treeExpand.setText("Expand"); 194 treeExpand.setActionCommand("Expand"); 195 treeExpand.addMouseListener(mouseListener); 196 treeExpand.addActionListener(this); 197 198 treeSearch.setBackground(CompierePLAF.getInfoBackground()); 199 treeSearch.addKeyListener(keyListener); 200 southPanel.setLayout(southLayout); 201 southPanel.add(treeExpand, BorderLayout.WEST); 202 southPanel.add(treeSearch, BorderLayout.EAST); 203 this.add(southPanel, BorderLayout.SOUTH); 204 centerSplitPane.add(treePane, JSplitPane.RIGHT); 206 centerSplitPane.add(bar, JSplitPane.LEFT); 207 this.add(centerSplitPane, BorderLayout.CENTER); 208 mFrom.setText("From."); 210 mFrom.setActionCommand("From"); 211 mFrom.addActionListener(this); 212 mTo.setEnabled(false); 213 mTo.setText("To."); 214 mTo.setActionCommand("To"); 215 mTo.addActionListener(this); 216 bar.setLayout(new BoxLayout(bar, BoxLayout.Y_AXIS)); 218 bar.setMinimumSize(new Dimension (50,50)); 219 220 mBarAdd.setText("BarAdd."); 221 mBarAdd.setActionCommand("BarAdd"); 222 mBarAdd.addActionListener(this); 223 mBarRemove.setText("BarRemove."); 224 mBarRemove.setActionCommand("BarRemove"); 225 mBarRemove.addActionListener(this); 226 popMenuTree.setLightWeightPopupEnabled(false); 228 popMenuTree.add(mBarAdd); 229 popMenuTree.addSeparator(); 230 popMenuTree.add(mFrom); 231 popMenuTree.add(mTo); 232 popMenuBar.setLightWeightPopupEnabled(false); 233 popMenuBar.add(mBarRemove); 234 235 treeExpand.setText(Msg.getMsg(Env.getCtx(), "ExpandTree")); 237 treeSearch.setToolTipText(Msg.getMsg(Env.getCtx(), "EnterSearchText")); 238 mBarAdd.setText(Msg.getMsg(Env.getCtx(), "BarAdd")); 239 mBarRemove.setText(Msg.getMsg(Env.getCtx(), "BarRemove")); 240 mFrom.setText(Msg.getMsg(Env.getCtx(), "ItemMove")); 241 mTo.setText(Msg.getMsg(Env.getCtx(), "ItemInsert")); 242 } 244 245 248 protected DragSource dragSource 249 = DragSource.getDefaultDragSource(); 250 protected DropTarget dropTarget 251 = new DropTarget(tree, DnDConstants.ACTION_MOVE, this, true, null); 252 protected DragGestureRecognizer recognizer 253 = dragSource.createDefaultDragGestureRecognizer(tree, DnDConstants.ACTION_MOVE, this); 254 255 256 260 public void dragGestureRecognized(DragGestureEvent e) 261 { 262 if (!m_editable) 263 return; 264 try 266 { 267 m_moveNode = (MTreeNode)tree.getSelectionPath().getLastPathComponent(); 268 } 269 catch (Exception ex) { 271 return; 272 } 273 StringSelection content = new StringSelection(m_moveNode.toString()); 275 e.startDrag(DragSource.DefaultMoveDrop, content, this); 278 Log.trace(Log.l5_DData, "Drag: " + m_moveNode.toString()); 279 } 281 282 286 public void dragDropEnd(DragSourceDropEvent e) {} 287 public void dragEnter(DragSourceDragEvent e) {} 288 public void dragExit(DragSourceEvent e) {} 289 public void dragOver(DragSourceDragEvent e) {} 290 public void dropActionChanged(DragSourceDragEvent e) {} 291 292 296 public void dragEnter(DropTargetDragEvent e) 297 { 298 e.acceptDrag(DnDConstants.ACTION_MOVE); 299 } 300 public void dropActionChanged(DropTargetDragEvent e) {} 301 public void dragExit(DropTargetEvent e) {} 302 303 304 308 public void dragOver(DropTargetDragEvent e) 309 { 310 Point mouseLoc = e.getLocation(); TreePath path = tree.getClosestPathForLocation(mouseLoc.x, mouseLoc.y); 312 tree.setSelectionPath(path); MTreeNode toNode = (MTreeNode)path.getLastPathComponent(); 314 if (m_moveNode == null || toNode == null) e.rejectDrag(); 319 else 320 e.acceptDrag(DnDConstants.ACTION_MOVE); 321 } 323 324 328 public void drop(DropTargetDropEvent e) 329 { 330 Point mouseLoc = e.getLocation(); TreePath path = tree.getClosestPathForLocation(mouseLoc.x, mouseLoc.y); 332 tree.setSelectionPath(path); MTreeNode toNode = (MTreeNode)path.getLastPathComponent(); 334 Log.trace(Log.l5_DData, "Drop: " + toNode); 336 if (m_moveNode == null || toNode == null) { 339 e.rejectDrop(); 340 return; 341 } 342 e.acceptDrop(DnDConstants.ACTION_MOVE); 344 moveNode(m_moveNode, toNode); 345 346 e.dropComplete(true); 347 m_moveNode = null; 348 } 350 351 356 private void moveNode(MTreeNode movingNode, MTreeNode toNode) 357 { 358 Log.trace(Log.l1_User, "VTreePanel.moveNode " + movingNode.toString() + " to " + toNode.toString()); 359 360 if (movingNode == toNode) 361 return; 362 363 MTreeNode oldParent = (MTreeNode)movingNode.getParent(); 365 movingNode.removeFromParent(); 366 treeModel.nodeStructureChanged(oldParent); 367 368 MTreeNode newParent; 370 int index; 371 if (!toNode.isSummary()) { 373 newParent = (MTreeNode)toNode.getParent(); 374 index = newParent.getIndex(toNode) + 1; } 376 else { 378 newParent = toNode; 379 index = 0; } 381 newParent.insert(movingNode, index); 382 treeModel.nodeStructureChanged(newParent); 383 384 setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); 386 Connection conn = DB.getConnectionRW(); 387 try 388 { 389 conn.setAutoCommit(false); 390 Statement stmt = conn.createStatement(); 391 for (int i = 0; i < oldParent.getChildCount(); i++) 393 { 394 MTreeNode nd = (MTreeNode)oldParent.getChildAt(i); 395 StringBuffer sql = new StringBuffer ("UPDATE "); 396 sql.append(m_nodeTableName) 397 .append(" SET Parent_ID=").append(oldParent.getID()) 398 .append(", SeqNo=").append(i) 399 .append(", Updated=SysDate") 400 .append(" WHERE AD_Tree_ID=").append(m_AD_Tree_ID) 401 .append(" AND Node_ID=").append(nd.getID()); 402 Log.trace(Log.l6_Database, "SQL", sql.toString()); 403 stmt.executeUpdate(sql.toString()); 404 } 405 if (oldParent != newParent) 406 for (int i = 0; i < newParent.getChildCount(); i++) 407 { 408 MTreeNode nd = (MTreeNode)newParent.getChildAt(i); 409 StringBuffer sql = new StringBuffer ("UPDATE "); 410 sql.append(m_nodeTableName) 411 .append(" SET Parent_ID=").append(newParent.getID()) 412 .append(", SeqNo=").append(i) 413 .append(", Updated=SysDate") 414 .append(" WHERE AD_Tree_ID=").append(m_AD_Tree_ID) 415 .append(" AND Node_ID=").append(nd.getID()); 416 Log.trace(Log.l6_Database, "SQL", sql.toString()); 417 stmt.executeUpdate(sql.toString()); 418 } 419 try 421 { 422 conn.commit(); } 424 catch (Exception e1) 425 { 426 Log.error("VTreePanel.moveNode - commit", e1); 427 } 428 stmt.close(); 429 conn.close(); 430 } 431 catch (SQLException e) 432 { 433 try 434 { 435 conn.rollback(); 436 conn.close(); 437 } 438 catch (SQLException e2) {} 439 Log.error("VTreePanel.moveNode", e); 440 ADialog.error(m_WindowNo, this, "TreeUpdateError", e.getLocalizedMessage()); 441 } 442 conn = null; 443 setCursor(Cursor.getDefaultCursor()); 444 Log.trace(Log.l3_Util, "VTreePanel.moveNode complete"); 445 } 447 448 449 450 454 protected void keyPressed(KeyEvent e) 455 { 456 if (e.getSource() instanceof JTree 458 || (e.getSource() == treeSearch && e.getModifiers() != 0)) { 460 TreePath tp = tree.getSelectionPath(); 461 if (tp == null) 462 ADialog.beep(); 463 else 464 { 465 MTreeNode tn = (MTreeNode)tp.getLastPathComponent(); 466 setSelectedNode(tn); 467 } 468 } 469 470 else if (e.getSource() == treeSearch) 472 { 473 String search = treeSearch.getText(); 474 boolean found = false; 475 476 if (m_nodeEn != null && !m_nodeEn.hasMoreElements()) 478 m_search = ""; 479 480 if (!search.equals(m_search)) 482 { 483 m_nodeEn = m_root.preorderEnumeration(); 485 m_search = search; 486 } 487 488 while(!found && m_nodeEn != null && m_nodeEn.hasMoreElements()) 490 { 491 MTreeNode nd = (MTreeNode)m_nodeEn.nextElement(); 492 if (nd.toString().toUpperCase().indexOf(search.toUpperCase()) != -1) 494 { 495 found = true; 496 TreePath treePath = new TreePath(nd.getPath()); 497 tree.setSelectionPath(treePath); 498 tree.makeVisible(treePath); tree.scrollPathToVisible(treePath); 500 } 501 } 502 if (!found) 503 ADialog.beep(); 504 } 506 } 508 509 510 511 515 protected void mouseClicked(MouseEvent e) 516 { 517 if (e.getSource() instanceof JTree) 519 { 520 if (SwingUtilities.isLeftMouseButton(e) 522 && e.getClickCount() == 2) 523 { 524 int selRow = tree.getRowForLocation(e.getX(), e.getY()); 525 if(selRow != -1) 526 { 527 MTreeNode tn = (MTreeNode)tree.getPathForLocation 528 (e.getX(), e.getY()).getLastPathComponent(); 529 setSelectedNode(tn); 530 } 531 } 532 533 else if ((m_editable || m_hasBar) 535 && SwingUtilities.isRightMouseButton(e) 536 && tree.getSelectionPath() != null) { 538 MTreeNode nd = (MTreeNode)tree.getSelectionPath().getLastPathComponent(); 539 { 541 Rectangle r = tree.getPathBounds(tree.getSelectionPath()); 542 popMenuTree.show(tree, (int)r.getMaxX(), (int)r.getY()); 543 } 544 } 545 } 547 else if (e.getSource() instanceof JButton) 549 { 550 if (SwingUtilities.isRightMouseButton(e)) 551 { 552 m_buttonSelected = (CButton)e.getSource(); 553 popMenuBar.show(m_buttonSelected, e.getX(), e.getY()); 554 } 555 } 557 } 559 560 564 public MTreeNode getSelectedNode() 565 { 566 return m_selectedNode; 567 } 569 573 public JComponent getSearchField() 574 { 575 return treeSearch; 576 } 578 582 public void setSelectedNode (int nodeID) 583 { 584 Log.trace(Log.l3_Util, "VTreePanel.setSelectedNode - ID=" + nodeID); 585 if (nodeID != -1) selectID(nodeID, true); } 589 594 private void selectID (int nodeID, boolean show) 595 { 596 Log.trace(Log.l3_Util, "VTreePanel.selectID", "NodeID=" + nodeID + ", Show=" + show); 597 MTreeNode node = m_root.findNode (nodeID); 599 if (node != null) 600 { 601 Log.trace(Log.l4_Data, node.toString()); 602 TreePath treePath = new TreePath(node.getPath()); 603 Log.trace(Log.l4_Data, treePath.toString()); 604 tree.setSelectionPath(treePath); 605 if (show) 606 { 607 tree.makeVisible(treePath); tree.scrollPathToVisible(treePath); 609 } 610 } 611 else 612 Log.error("VTreePanel.selectID - Node not found; ID=" + nodeID); 613 } 615 616 620 private void setSelectedNode (MTreeNode nd) 621 { 622 Log.trace(Log.l3_Util, "VTreePanel.setSelectedNode = " + nd); 623 m_selectedNode = nd; 624 firePropertyChange(NODE_SELECTION, null, nd); 626 } 628 629 630 640 public void nodeChanged (boolean save, int keyID, 641 String name, String description, boolean isSummary, String imageIndicator) 642 { 643 Log.trace(Log.l3_Util, "VTreePanel.nodeChanged - Save=" + save + ", KeyID=" + keyID, 644 "Name=" + name + ", Description=" + description + ", IsSummary=" + isSummary + ", ImageInd=" + imageIndicator); 645 MTreeNode node = m_root.findNode(keyID); 647 648 if (node == null && save) 650 { 651 node = new MTreeNode (keyID, 0, name, description, 652 m_root.getID(), isSummary, imageIndicator, false); 653 m_root.add (node); 654 } 655 656 else if (node != null && save) 658 { 659 node.setName (name); 660 } 661 662 else if (node != null && !save) 664 { 665 MTreeNode parent = (MTreeNode)node.getParent(); 666 node.removeFromParent(); 667 node = parent; } 669 670 else 672 { 673 Log.error("VTreePanel.nodeChanged ERROR - Save=" + save + ", KeyID=" + keyID + ", Node=" + node); 674 node = null; 675 } 676 677 if (node == null) 679 return; 680 681 tree.updateUI(); 683 TreePath treePath = new TreePath(node.getPath()); 684 tree.setSelectionPath(treePath); 685 tree.makeVisible(treePath); tree.scrollPathToVisible(treePath); 687 } 689 690 691 692 696 public void actionPerformed(ActionEvent e) 697 { 698 if (e.getSource() instanceof JButton) 700 { 701 selectID(Integer.parseInt(e.getActionCommand()), false); 703 MTreeNode tn = (MTreeNode)tree.getSelectionPath().getLastPathComponent(); 705 setSelectedNode(tn); 706 } 707 708 else if (e.getSource() instanceof JMenuItem) 710 { 711 if (e.getActionCommand().equals("From")) 712 moveFrom(); 713 else if (e.getActionCommand().equals("To")) 714 moveTo(); 715 else if (e.getActionCommand().equals("BarAdd")) 716 barAdd(); 717 else if (e.getActionCommand().equals("BarRemove")) 718 barRemove(); 719 } 720 721 else if (e.getSource() instanceof JCheckBox) 722 { 723 if (e.getActionCommand().equals("Expand")) 724 expandTree(); 725 } 726 } 728 729 730 731 734 private void moveFrom() 735 { 736 m_moveNode = (MTreeNode)tree.getSelectionPath().getLastPathComponent(); 737 if (m_moveNode != null) 738 mTo.setEnabled(true); } 741 744 private void moveTo() 745 { 746 mFrom.setEnabled(true); 747 mTo.setEnabled(false); 748 if (m_moveNode == null) 749 return; 750 751 MTreeNode toNode = (MTreeNode)tree.getSelectionPath().getLastPathComponent(); 752 moveNode(m_moveNode, toNode); 753 m_moveNode = null; 755 } 757 760 private void barAdd() 761 { 762 MTreeNode nd = (MTreeNode)tree.getSelectionPath().getLastPathComponent(); 763 addToBar(nd); 764 barDBupdate(true, nd.getID()); 765 } 767 771 private void addToBar(MTreeNode nd) 772 { 773 String label = nd.toString().trim(); 775 int space = label.indexOf(" "); 776 779 CButton button = new CButton(label); button.setToolTipText(nd.getDescription()); 781 button.setActionCommand(String.valueOf(nd.getID())); 782 button.setMargin(new Insets(0, 0, 0, 0)); 784 button.setIcon(nd.getIcon()); 785 button.setBorderPainted(false); 786 button.setRequestFocusEnabled(false); 788 button.addActionListener(this); 790 button.addMouseListener(mouseListener); 791 bar.add(button); 793 bar.validate(); 794 if (centerSplitPane.getDividerLocation() == -1) 795 centerSplitPane.setDividerLocation(button.getPreferredSize().width); 796 bar.repaint(); 797 } 799 802 private void barRemove() 803 { 804 bar.remove(m_buttonSelected); 805 bar.validate(); 806 bar.repaint(); 807 barDBupdate(false, Integer.parseInt(m_buttonSelected.getActionCommand())); 808 } 810 815 private void barDBupdate (boolean add, int Node_ID) 816 { 817 int AD_Client_ID = Env.getAD_Client_ID(Env.getCtx()); 818 int AD_Org_ID = Env.getContextAsInt(Env.getCtx(), "#AD_Org_ID"); 819 int AD_User_ID = Env.getContextAsInt(Env.getCtx(), "#AD_User_ID"); 820 StringBuffer sql = new StringBuffer (); 821 if (add) 822 sql.append("INSERT INTO AD_TreeBar " 823 + "(AD_Tree_ID,AD_User_ID,Node_ID, " 824 + "AD_Client_ID,AD_Org_ID, " 825 + "IsActive,Created,CreatedBy,Updated,UpdatedBy)VALUES (") 826 .append(m_AD_Tree_ID).append(",").append(AD_User_ID).append(",").append(Node_ID).append(",") 827 .append(AD_Client_ID).append(",").append(AD_Org_ID).append(",") 828 .append("'Y',SysDate,").append(AD_User_ID).append(",SysDate,").append(AD_User_ID).append(")"); 829 else 831 sql.append("DELETE AD_TreeBar WHERE AD_Tree_ID=").append(m_AD_Tree_ID) 832 .append(" AND AD_User_ID=").append(AD_User_ID) 833 .append(" AND Node_ID=").append(Node_ID); 834 int no = DB.executeUpdate(sql.toString()); 835 } 837 838 841 private void expandTree() 842 { 843 if (treeExpand.isSelected()) 844 { 845 for (int row = 0; row < tree.getRowCount(); row++) 846 tree.expandRow(row); 847 } 848 else 849 { 850 for (int row = 0; row < tree.getRowCount(); row++) 851 tree.collapseRow(row); 852 } 853 } 855 } 857 858 859 862 class VTreePanel_mouseAdapter extends java.awt.event.MouseAdapter 863 { 864 VTreePanel adaptee; 865 866 VTreePanel_mouseAdapter(VTreePanel adaptee) 867 { 868 this.adaptee = adaptee; 869 } 870 871 public void mouseClicked(MouseEvent e) 872 { 873 adaptee.mouseClicked(e); 874 } 875 } 877 880 class VTreePanel_keyAdapter extends java.awt.event.KeyAdapter 881 { 882 VTreePanel adaptee; 883 884 VTreePanel_keyAdapter(VTreePanel adaptee) 885 { 886 this.adaptee = adaptee; 887 } 888 889 public void keyPressed(KeyEvent e) 890 { 891 if (e.getKeyCode() == KeyEvent.VK_ENTER) 892 adaptee.keyPressed(e); 893 } 894 } | Popular Tags |