/****************************************************************************** * Product: Adempiere ERP & CRM Smart Business Solution * * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * * by the Free Software Foundation. This program is distributed in the hope * * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * * with this program; if not, write to the Free Software Foundation, Inc., * * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * * For the text or an alternative of this public license, you may reach us * * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * * or via info@compiere.org or http://www.compiere.org/license.html * *****************************************************************************/ package org.compiere.grid.tree; import java.awt.BorderLayout; import java.awt.Container; import java.awt.Cursor; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Insets; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import javax.swing.Action; import javax.swing.ActionMap; import javax.swing.BorderFactory; import javax.swing.DropMode; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JToolBar; import javax.swing.JTree; import javax.swing.KeyStroke; import javax.swing.SwingUtilities; import javax.swing.TransferHandler; import javax.swing.UIManager; import javax.swing.plaf.SplitPaneUI; import javax.swing.plaf.basic.BasicSplitPaneUI; import javax.swing.tree.DefaultTreeSelectionModel; import javax.swing.tree.TreePath; import org.adempiere.exceptions.DBException; import org.adempiere.plaf.AdempierePLAF; import org.adempiere.plaf.AdempiereTaskPaneUI; import org.compiere.apps.ADialog; import org.compiere.model.MTree; import org.compiere.model.MTreeNode; import org.compiere.swing.CButton; import org.compiere.swing.CCheckBox; import org.compiere.swing.CLabel; import org.compiere.swing.CMenuItem; import org.compiere.swing.CPanel; import org.compiere.swing.CTextField; import org.compiere.swing.ShadowBorder; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Msg; import org.compiere.util.Trx; import org.compiere.util.TrxRunnable; import org.jdesktop.swingx.JXTaskPane; import org.jdesktop.swingx.JXTaskPaneContainer; import org.omidp.util.LocaleUtil; import de.schaeffer.compiere.tools.DocumentSearch; /** * Tree Panel displays trees. * <br> * When a node is selected by Left Click, a propertyChange (NODE_SELECTION) event is fired * <pre> * PropertyChangeListener - * treePanel.addPropertyChangeListener(VTreePanel.NODE_SELECTION, this); * calls: public void propertyChange(PropertyChangeEvent e) * </pre> * To select a specific node call * setSelectedNode(NodeID); * * @author Jorg Janke * @version $Id: VTreePanel.java,v 1.3 2006/07/30 00:51:28 jjanke Exp $ * * @author kthiemann / Carlos Ruiz * <li>2761420 - Advanced Search * * @author Teo Sarca * <li>BF [ 2866493 ] VTreePanel is not saving who did the node move * https://sourceforge.net/tracker/?func=detail&atid=879332&aid=2866493&group_id=176962 * * @author Paul Bowden * <li>FR [ 2032092 ] Java 6 improvements to tree drag and drop * https://sourceforge.net/tracker/index.php?func=detail&aid=2032092&group_id=176962&atid=879335 */ public final class VTreePanel extends CPanel implements ActionListener { /****************************************************************************** * Mouse Clicked */ class VTreePanel_mouseAdapter extends java.awt.event.MouseAdapter { VTreePanel m_adaptee; /** * VTreePanel_mouseAdapter * @param adaptee */ VTreePanel_mouseAdapter(VTreePanel adaptee) { m_adaptee = adaptee; } /** * Mouse Clicked * @param e */ public void mouseClicked(MouseEvent e) { m_adaptee.mouseClicked(e); } } // VTreePanel_mouseAdapter /** * Key Pressed */ class VTreePanel_keyAdapter extends java.awt.event.KeyAdapter { VTreePanel m_adaptee; /** * VTreePanel_keyAdapter * @param adaptee */ VTreePanel_keyAdapter(VTreePanel adaptee) { m_adaptee = adaptee; } /** * Key Pressed * @param e */ public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ENTER) m_adaptee.keyPressed(e); } } // VTreePanel_keyAdapter /** * */ private static final long serialVersionUID = -6798614427038652192L; private static final String PREFIX_DOCUMENT_SEARCH = "/"; protected boolean m_lookAndFeelChanged = false; private VTreeTransferHandler handler = new VTreeTransferHandler(); /** * Tree Panel for browsing and editing of a tree. * Need to call initTree * @param WindowNo WindowNo * @param editable if true you can edit it * @param hasBar has OutlookBar */ public VTreePanel(int WindowNo, boolean hasBar, boolean editable) { super(); toolbar = new ArrayList<JToolBar>(); log.config("Bar=" + hasBar + ", Editable=" + editable); m_WindowNo = WindowNo; m_hasBar = hasBar; m_editable = editable; // static init jbInit(); if (!hasBar) { barScrollPane.setPreferredSize(new Dimension(0,0)); barScrollPane.setMaximumSize(new Dimension(0,0)); barScrollPane.setMinimumSize(new Dimension(0,0)); //Begin - [FR 1953769] bar.setBackground(AdempierePLAF.getFormBackground()); //End - [FR 1953769] centerSplitPane.setDividerLocation(0); centerSplitPane.setDividerSize(0); popMenuTree.remove(mBarAdd); } else { centerSplitPane.setDividerLocation(80); UIManager.addPropertyChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { if ("lookAndFeel".equals(evt.getPropertyName())) m_lookAndFeelChanged = true; } }); } // base settings if (editable) { tree.setDragEnabled(true); tree.setTransferHandler(handler); tree.setDropMode(DropMode.INSERT); setMappings(tree); } else { popMenuTree.remove(mFrom); popMenuTree.remove(mTo); } } // VTreePanel /** * Tree initialization. * May be called several times * @param AD_Tree_ID tree to load * @return true if loaded ok */ public boolean initTree (int AD_Tree_ID) { log.config("AD_Tree_ID=" + AD_Tree_ID); // m_AD_Tree_ID = AD_Tree_ID; // Get Tree MTree vTree = new MTree (Env.getCtx(), AD_Tree_ID, m_editable, true, null); m_root = vTree.getRoot(); m_root.setName(Msg.getMsg(Env.getCtx(), vTree.getName() ) ); // translate name of menu. // m_root.setName(Msg.getMsg(Env.getCtx(), "Menu") ); // @Trifon; this is the hardcoded way. log.config("root=" + m_root); m_nodeTableName = vTree.getNodeTableName(); treeModel = new AdempiereTreeModel(m_root, true); treeModel.setMTree(vTree); tree.setModel(treeModel); // Shortcut Bar if (m_hasBar) { for (JToolBar jt : toolbar) jt.removeAll(); toolbarMap = new HashMap<Integer, JToolBar>(); Enumeration<?> enTop = m_root.children(); JToolBar jt = null; Map<JToolBar,String> titleMap = new HashMap<JToolBar, String>(); while (enTop.hasMoreElements()) { MTreeNode ndTop = (MTreeNode)enTop.nextElement(); Enumeration<?> en = ndTop.preorderEnumeration(); boolean labelDrawn=false; while (en.hasMoreElements()) { MTreeNode nd = (MTreeNode)en.nextElement(); if (nd.isOnBar()) { if (!labelDrawn) { jt = new JToolBar(JToolBar.VERTICAL); titleMap.put(jt, ndTop.toString().trim()); labelDrawn=true; toolbarMap.put(ndTop.getNode_ID(), jt); } addToBar(nd, jt, false); } } if (jt!=null) toolbar.add(jt); jt=null; } //jbInit(); for (JToolBar jt2 : toolbar) { jt2.setOpaque(false); //jt2.setLayout(new GridBagLayout()); jt2.setFloatable(false); jt2.setRollover(true); jt2.setBorder(BorderFactory.createEmptyBorder()); JXTaskPane barPart = new JXTaskPane(); //Begin - [FR 1953769] barPart.setUI(new AdempiereTaskPaneUI()); barPart.getContentPane().setBackground(AdempierePLAF.getFormBackground()); //End - [FR 1953769] barPart.setAnimated(true); barPart.setLayout(new BorderLayout()); barPart.add(jt2, BorderLayout.NORTH); barPart.setTitle(titleMap.get(jt2)); bar.add(barPart); //Begin - [FR 1953769] bar.setBackground(AdempierePLAF.getFormBackground()); //End - [FR 1953769] } } return true; } // initTree /** Logger */ private static CLogger log = CLogger.getCLogger(VTreePanel.class); private BorderLayout mainLayout = new BorderLayout(); private JTree tree = new JTree(); private AdempiereTreeModel treeModel; private DefaultTreeSelectionModel treeSelect = new DefaultTreeSelectionModel(); private CPanel southPanel = new CPanel(); private CCheckBox treeExpand = new CCheckBox(); private CTextField treeSearch = new CTextField(10); private CLabel treeSearchLabel = new CLabel(); private JPopupMenu popMenuTree = new JPopupMenu(); private JPopupMenu popMenuBar = new JPopupMenu(); private CMenuItem mFrom = new CMenuItem(); private CMenuItem mTo = new CMenuItem(); private JXTaskPaneContainer bar = new JXTaskPaneContainer(); private java.util.List<JToolBar> toolbar; private HashMap<Integer, JToolBar> toolbarMap; private int toolBarCols=3; private CMenuItem mBarAdd = new CMenuItem(); private CMenuItem mBarRemove = new CMenuItem(); private BorderLayout southLayout = new BorderLayout(); private JSplitPane centerSplitPane = new JSplitPane(); private JScrollPane treePane = new JScrollPane(); private MouseListener mouseListener = new VTreePanel_mouseAdapter(this); private KeyListener keyListener = new VTreePanel_keyAdapter(this); // private int m_WindowNo; /** Tree ID */ private int m_AD_Tree_ID = 0; /** Table Name for TreeNode */ private String m_nodeTableName = null; /** Tree is editable (can move nodes) - also not active shown */ private boolean m_editable; /** Tree has a shortcut Bar */ private boolean m_hasBar; /** The root node */ private MTreeNode m_root = null; private String m_search = ""; private Enumeration<?> m_nodeEn; private MTreeNode m_selectedNode; // the selected model node private CButton m_buttonSelected; private JScrollPane barScrollPane; /** Property Listener NodeSelected by Left Click */ public static final String NODE_SELECTION = "NodeSelected"; /** * Static Component initialization. * <pre> * - centerSplitPane * - treePane * - tree * - bar * - southPanel * </pre> */ private void jbInit() { this.setLayout(mainLayout); mainLayout.setVgap(5); // // only one node to be selected treeSelect.setSelectionMode(DefaultTreeSelectionModel.SINGLE_TREE_SELECTION); tree.setSelectionModel(treeSelect); //omidp LocaleUtil.applyComponentOrientation(tree); // tree.setEditable(false); // allows to change the text tree.addMouseListener(mouseListener); tree.addKeyListener(keyListener); tree.setCellRenderer(new VTreeCellRenderer()); treePane.getViewport().add(tree, null); treePane.setBorder(new ShadowBorder()); tree.setBorder(BorderFactory.createEmptyBorder()); CPanel treePart = new CPanel(); treePart.setLayout(new BorderLayout()); treePart.add(treePane, BorderLayout.CENTER); treePart.setBorder(BorderFactory.createEmptyBorder()); // treeExpand.setText(Msg.getMsg(Env.getCtx(), "ExpandTree")); treeExpand.setActionCommand("Expand"); treeExpand.addMouseListener(mouseListener); treeExpand.addActionListener(this); // treeSearchLabel.setText(Msg.getMsg(Env.getCtx(), "TreeSearch") + " "); treeSearchLabel.setLabelFor(treeSearch); treeSearchLabel.setToolTipText(Msg.getMsg(Env.getCtx(), "TreeSearchText")); treeSearch.setBackground(AdempierePLAF.getInfoBackground()); treeSearch.addKeyListener(keyListener); southPanel.setLayout(southLayout); southPanel.add(treeExpand, BorderLayout.WEST); southPanel.add(treeSearchLabel, BorderLayout.CENTER); southPanel.add(treeSearch, BorderLayout.EAST); treePart.add(southPanel, BorderLayout.SOUTH); // centerSplitPane.setOpaque(false); barScrollPane = new JScrollPane(); barScrollPane.getViewport().add(bar); centerSplitPane.add(barScrollPane, JSplitPane.LEFT); //hengsin, jxtaskpane centerSplitPane.add(treePart, JSplitPane.RIGHT); centerSplitPane.setBorder(BorderFactory.createEmptyBorder()); removeSplitPaneBorder(); this.add(centerSplitPane, BorderLayout.CENTER); // mFrom.setText(Msg.getMsg(Env.getCtx(), "ItemMove")); mFrom.setActionCommand((String)TransferHandler.getCutAction(). getValue(Action.NAME)); mFrom.addActionListener(this); mFrom.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_X, ActionEvent.CTRL_MASK)); mTo.setText(Msg.getMsg(Env.getCtx(), "ItemInsert")); mTo.setActionCommand((String)TransferHandler.getPasteAction(). getValue(Action.NAME)); mTo.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_V, ActionEvent.CTRL_MASK)); mTo.setMnemonic(KeyEvent.VK_V); mTo.addActionListener(this); mBarAdd.setText(Msg.getMsg(Env.getCtx(), "BarAdd")); mBarAdd.setActionCommand("BarAdd"); mBarAdd.addActionListener(this); mBarRemove.setText(Msg.getMsg(Env.getCtx(), "BarRemove")); mBarRemove.setActionCommand("BarRemove"); mBarRemove.addActionListener(this); // popMenuTree.setLightWeightPopupEnabled(false); popMenuTree.add(mBarAdd); popMenuTree.add(mFrom); if(!m_hasBar){ popMenuTree.addSeparator(); } popMenuTree.add(mTo); popMenuBar.setLightWeightPopupEnabled(false); popMenuBar.add(mBarRemove); } // jbInit private void removeSplitPaneBorder() { if (centerSplitPane != null) { SplitPaneUI splitPaneUI = centerSplitPane.getUI(); if (splitPaneUI instanceof BasicSplitPaneUI) { BasicSplitPaneUI basicUI = (BasicSplitPaneUI) splitPaneUI; basicUI.getDivider().setBorder(BorderFactory.createEmptyBorder()); } } } /** * Set Divider Location * @param location location (80 default) */ public void setDividerLocation(int location) { centerSplitPane.setDividerLocation(location); } // setDividerLocation /** * Get Divider Location * @return divider location */ public int getDividerLocation() { return centerSplitPane.getDividerLocation(); } // getDividerLocation /** * Enter Key * @param e event */ protected void keyPressed(KeyEvent e) { //CHANGED - document search if (e.getSource() == treeSearch && treeSearch.getText() != null && treeSearch.getText().length() > 0 && treeSearch.getText().substring(0, 1).equals(PREFIX_DOCUMENT_SEARCH)) { setBusy(true); DocumentSearch search = new DocumentSearch(); if (search.openDocumentsByDocumentNo(treeSearch.getText().substring(1))) treeSearch.setText(null); setBusy(false); return; } // *** Tree *** if (e.getSource() instanceof JTree || (e.getSource() == treeSearch && e.getModifiers() != 0)) // InputEvent.CTRL_MASK { TreePath tp = tree.getSelectionPath(); if (tp == null) ADialog.beep(); else { MTreeNode tn = (MTreeNode)tp.getLastPathComponent(); setSelectedNode(tn); } } // *** treeSearch *** else if (e.getSource() == treeSearch) { String search = treeSearch.getText(); boolean found = false; // at the end - try from top if (m_nodeEn != null && !m_nodeEn.hasMoreElements()) m_search = ""; // this is the first time if (!search.equals(m_search)) { // get enumeration of all nodes m_nodeEn = m_root.preorderEnumeration(); m_search = search; } // search the nodes while(!found && m_nodeEn != null && m_nodeEn.hasMoreElements()) { MTreeNode nd = (MTreeNode)m_nodeEn.nextElement(); // compare in upper case if (nd.toString().toUpperCase().indexOf(search.toUpperCase()) != -1) { found = true; TreePath treePath = new TreePath(nd.getPath()); tree.setSelectionPath(treePath); tree.makeVisible(treePath); // expand it tree.scrollPathToVisible(treePath); } } if (!found) ADialog.beep(); } // treeSearch } // keyPressed /*************************************************************************/ /** * Mouse clicked * @param e event */ protected void mouseClicked(MouseEvent e) { // *** JTree *** if (e.getSource() instanceof JTree) { // Left Double Click if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() > 0) { int selRow = tree.getRowForLocation(e.getX(), e.getY()); if(selRow != -1) { MTreeNode tn = (MTreeNode)tree.getPathForLocation (e.getX(), e.getY()).getLastPathComponent(); setSelectedNode(tn); } } // Right Click for PopUp else if ((m_editable || m_hasBar) && SwingUtilities.isRightMouseButton(e) ) { int selRow = tree.getRowForLocation(e.getX(), e.getY()); if(selRow != -1) { tree.setSelectionRow(selRow); } if (tree.getSelectionPath() != null) // need select first { MTreeNode nd = (MTreeNode)tree.getSelectionPath().getLastPathComponent(); if (nd.isLeaf()) // only add leaves to bar mBarAdd.setEnabled(true); else mBarAdd.setEnabled(false); Rectangle r = tree.getPathBounds(tree.getSelectionPath()); popMenuTree.show(tree, (int)r.getMaxX(), (int)r.getY()); } } } // JTree // *** JButton *** else if (e.getSource() instanceof JButton) { if (SwingUtilities.isRightMouseButton(e)) { m_buttonSelected = (CButton)e.getSource(); popMenuBar.show(m_buttonSelected, e.getX(), e.getY()); } } // JButton } // mouseClicked /** * Get currently selected node * @return MTreeNode */ public MTreeNode getSelectedNode() { return m_selectedNode; } // getSelectedNode /** * Search Field * @return Search Field */ public JComponent getSearchField() { return treeSearch; } // getSearchField /** * Set Selection to Node in Event * @param nodeID Node ID * @return true if selected */ public boolean setSelectedNode (int nodeID) { log.config("ID=" + nodeID); if (nodeID != -1) // new is -1 return selectID(nodeID, true); // show selection return false; } // setSelectedNode /** * Select ID in Tree * @param nodeID Node ID * @param show scroll to node * @return true if selected */ private boolean selectID (int nodeID, boolean show) { if (m_root == null) return false; log.config("NodeID=" + nodeID + ", Show=" + show + ", root=" + m_root); // try to find the node MTreeNode node = m_root.findNode (nodeID); if (node != null) { TreePath treePath = new TreePath(node.getPath()); log.config("Node=" + node + ", Path=" + treePath.toString()); tree.setSelectionPath(treePath); if (show) { tree.makeVisible(treePath); // expand it tree.scrollPathToVisible(treePath); } return true; } log.info("Node not found; ID=" + nodeID); return false; } // selectID /** * Set the selected node & initiate all listeners * @param nd node */ private void setSelectedNode (MTreeNode nd) { log.config("Node = " + nd); m_selectedNode = nd; // firePropertyChange(NODE_SELECTION, null, nd); } // setSelectedNode /************************************************************************** * Node Changed - synchronize Node * * @param save true the node was saved (changed/added), false if the row was deleted * @param keyID the ID of the row changed * @param name name * @param description description * @param isSummary summary node * @param imageIndicator image indicator */ public void nodeChanged (boolean save, int keyID, String name, String description, boolean isSummary, String imageIndicator) { log.config("Save=" + save + ", KeyID=" + keyID + ", Name=" + name + ", Description=" + description + ", IsSummary=" + isSummary + ", ImageInd=" + imageIndicator + ", root=" + m_root); // if ID==0=root - don't update it if (keyID == 0) return; // try to find the node MTreeNode node = m_root.findNode(keyID); // Node not found and saved -> new if (node == null && save) { node = new MTreeNode (keyID, 0, name, description, m_root.getNode_ID(), isSummary, imageIndicator, false, null); m_root.add (node); } // Node found and saved -> change else if (node != null && save) { node.setName (name); node.setAllowsChildren(isSummary); } // Node found and not saved -> delete else if (node != null && !save) { MTreeNode parent = (MTreeNode)node.getParent(); node.removeFromParent(); node = parent; // select Parent } // Error else { log.log(Level.SEVERE, "Save=" + save + ", KeyID=" + keyID + ", Node=" + node); node = null; } // Nothing to display if (node == null) return; // (Re) Display Node tree.updateUI(); TreePath treePath = new TreePath(node.getPath()); tree.setSelectionPath(treePath); tree.makeVisible(treePath); // expand it tree.scrollPathToVisible(treePath); } // nodeChanged /************************************************************************** * ActionListener * @param e event */ public void actionPerformed(ActionEvent e) { // bar button pressed if (e.getSource() instanceof JButton) { // Find Node - don't show selectID(Integer.parseInt(e.getActionCommand()), false); // Select it MTreeNode tn = (MTreeNode)tree.getSelectionPath().getLastPathComponent(); setSelectedNode(tn); } // popup menu commands else if (e.getSource() instanceof JMenuItem) { String action = (String)e.getActionCommand(); Action a = tree.getActionMap().get(action); if (a != null) { a.actionPerformed(new ActionEvent(tree, ActionEvent.ACTION_PERFORMED, null)); } else if (action.equals("BarAdd")) barAdd(); else if (action.equals("BarRemove")) barRemove(); } else if (e.getSource() instanceof JCheckBox) { if (e.getActionCommand().equals("Expand")) expandTree(); } } // actionPerformed /** * Add selected TreeNode to Bar */ private void barAdd() { MTreeNode nd = (MTreeNode)tree.getSelectionPath().getLastPathComponent(); if (barDBupdate(true, nd.getNode_ID())) addToBar(nd,getParentToolBar(nd), false); else if (DBException.isUniqueContraintError(CLogger.retrieveException())) ADialog.error(0, this, "BookmarkExist", null); } // barAdd /** * Returns the top level parent JToolBar for the given MTreenode. If the parent is not on * the CPanel yet a new one is created and added. * @param nd * @return top level parent JToolBar for the given MTreenode */ private JToolBar getParentToolBar(MTreeNode nd){ int topParentId = getTopParentId(nd); JToolBar parent = toolbarMap.get(topParentId); if(parent==null){ Enumeration<?> enTop =m_root.children(); while (enTop.hasMoreElements()) { MTreeNode ndTop = (MTreeNode)enTop.nextElement(); if(ndTop.getNode_ID()==topParentId){ log.fine("add new category: " + ndTop); parent = new JToolBar(JToolBar.VERTICAL); toolbarMap.put(ndTop.getNode_ID(), parent); toolbar.add(parent); parent.setOpaque(false); parent.setFloatable(false); parent.setRollover(true); parent.setBorder(BorderFactory.createEmptyBorder()); JXTaskPane barPart = new JXTaskPane(); //Begin - [FR 1953769] barPart.setUI(new AdempiereTaskPaneUI()); barPart.getContentPane().setBackground(AdempierePLAF.getFormBackground()); //End - [FR 1953769] barPart.setTitle(ndTop.toString().trim()); barPart.setAnimated(true); barPart.setLayout(new BorderLayout()); barPart.add(parent, BorderLayout.NORTH); bar.add(barPart); return parent; } } } else { log.fine("parent found: " + parent); } return parent; } /** * Returns the id of the top level parent of the given MTreenode * @param nd * @return */ private int getTopParentId(MTreeNode nd) { MTreeNode parent = (MTreeNode) nd.getParent(); if(parent!=null && parent.getNode_ID()!=0){ return getTopParentId(parent); } return nd.getNode_ID(); } /** * Add TreeNode to Bar * @param nd node */ private void addToBar(MTreeNode nd, JToolBar currentToolBar, boolean isLabel) { // Only first word of Label String label = nd.toString().trim(); // int space = label.indexOf(' '); // if (space != -1) // label = label.substring(0, space); if (!isLabel) { CButton button = new CButton(label); button.setOpaque(false); button.setHorizontalAlignment(JButton.LEFT); button.setMargin(new Insets(0, 0, 0, 0)); button.setIcon(nd.getIcon()); button.setRequestFocusEnabled(false); button.setToolTipText(nd.getDescription()); button.setActionCommand(String.valueOf(nd.getNode_ID())); button.addActionListener(this); button.addMouseListener(mouseListener); currentToolBar.add(button); } else { currentToolBar.add(new JLabel("<html><u><b>" +label+"</b></u></html>")); } bar.validate(); //if (centerSplitPane.getDividerLocation() == -1) // centerSplitPane.setDividerLocation(button.getPreferredSize().width); bar.repaint(); } // addToBar /** * Remove from Bar */ private void barRemove() { //the button in on a JToolBar which is on a CPanel JToolBar parentBar = (JToolBar) m_buttonSelected.getParent(); Container parentPanel = null; if(parentBar!=null){ parentPanel = parentBar.getParent(); } for (JToolBar jt : toolbar) { jt.remove(m_buttonSelected); } if(parentPanel != null && parentBar.getComponentCount()==1){ //only label left bar.remove(parentPanel); //remove from toolBarMap.. toolbarMap.values().remove(parentBar); } bar.validate(); bar.repaint(); barDBupdate(false, Integer.parseInt(m_buttonSelected.getActionCommand())); } // barRemove /** * Make Bar add/remove persistent * @param add true if add - otherwise remove * @param Node_ID Node ID * @return true if updated */ private boolean barDBupdate (boolean add, int Node_ID) { int AD_Client_ID = Env.getAD_Client_ID(Env.getCtx()); int AD_Org_ID = Env.getContextAsInt(Env.getCtx(), "#AD_Org_ID"); int AD_User_ID = Env.getContextAsInt(Env.getCtx(), "#AD_User_ID"); StringBuffer sql = new StringBuffer(); if (add) sql.append("INSERT INTO AD_TreeBar " + "(AD_Tree_ID,AD_User_ID,Node_ID, " + "AD_Client_ID,AD_Org_ID, " + "IsActive,Created,CreatedBy,Updated,UpdatedBy)VALUES (") .append(m_AD_Tree_ID).append(",").append(AD_User_ID).append(",").append(Node_ID).append(",") .append(AD_Client_ID).append(",").append(AD_Org_ID).append(",") .append("'Y',SysDate,").append(AD_User_ID).append(",SysDate,").append(AD_User_ID).append(")"); // if already exist, will result in ORA-00001: unique constraint (ADEMPIERE.AD_TREEBAR_KEY) else sql.append("DELETE AD_TreeBar WHERE AD_Tree_ID=").append(m_AD_Tree_ID) .append(" AND AD_User_ID=").append(AD_User_ID) .append(" AND Node_ID=").append(Node_ID); int no = DB.executeUpdate(sql.toString(), false, null); return no == 1; } // barDBupdate /** * Clicked on Expand All */ private void expandTree() { if (treeExpand.isSelected()) { for (int row = 0; row < tree.getRowCount(); row++) tree.expandRow(row); } else { // patch: 1654055 +jgubo Changed direction of collapsing the tree nodes for (int row = tree.getRowCount(); row > 0; row--) tree.collapseRow(row); } } // expandTree @Override public void paint(Graphics g) { if (m_lookAndFeelChanged) { m_lookAndFeelChanged = false; if (m_hasBar) removeSplitPaneBorder(); } super.paint(g); } private void setMappings(JTree tree) { ActionMap map = tree.getActionMap(); map.put(TransferHandler.getCutAction().getValue(Action.NAME), TransferHandler.getCutAction()); map.put(TransferHandler.getPasteAction().getValue(Action.NAME), TransferHandler.getPasteAction()); } //CHANGED - SET BUSY ADDED /** * Indicate Busy * @param busy busy */ private void setBusy (boolean busy) { JFrame frame = Env.getFrame(this); log.info("frame: " + frame); if (frame == null) // during init return; if (busy) { this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); frame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); treeSearch.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); } else { this.setCursor(Cursor.getDefaultCursor()); frame.setCursor(Cursor.getDefaultCursor()); treeSearch.setCursor(Cursor.getDefaultCursor()); } } // set Busy } // VTreePanel