📄 vtreepanel.java
字号:
/******************************************************************************
* The contents of this file are subject to the Compiere License Version 1.1
* ("License"); You may not use this file except in compliance with the License
* You may obtain a copy of the License at http://www.compiere.org/license.html
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
* the specific language governing rights and limitations under the License.
* The Original Code is Compiere ERP & CRM Business Solution
* The Initial Developer of the Original Code is Jorg Janke and ComPiere, Inc.
* Portions created by Jorg Janke are Copyright (C) 1999-2001 Jorg Janke, parts
* created by ComPiere are Copyright (C) ComPiere, Inc.; All Rights Reserved.
* Contributor(s): ______________________________________.
*****************************************************************************/
package org.compiere.grid.tree;
import java.awt.*;
import java.awt.dnd.*;
import java.awt.datatransfer.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import javax.swing.*;
import javax.swing.tree.*;
import java.sql.*;
import org.compiere.apps.*;
import org.compiere.model.*;
import org.compiere.util.*;
import org.compiere.plaf.*;
import org.compiere.swing.*;
/**
* Tree Panel displays trees.
* <br>
* When a node is selected, 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.19 2003/02/21 06:37:53 jjanke Exp $
*/
public final class VTreePanel extends CPanel
implements ActionListener, DragGestureListener, DragSourceListener, DropTargetListener
{
/**
* 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();
Log.trace(Log.l3_Util, "VTreePanel", "Bar=" + hasBar + ", Editable=" + editable);
m_WindowNo = WindowNo;
m_hasBar = hasBar;
m_editable = editable;
// static init
jbInit();
if (!hasBar)
{
bar.setPreferredSize(new Dimension(0,0));
centerSplitPane.setDividerLocation(0);
centerSplitPane.setDividerSize(0);
popMenuTree.remove(mBarAdd);
}
else
centerSplitPane.setDividerLocation(80);
// base settings
if (editable)
tree.setDropTarget(dropTarget);
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.trace(Log.l3_Util, "VTreePanel.initTree " + AD_Tree_ID);
//
m_AD_Tree_ID = AD_Tree_ID;
m_AD_User_ID = Env.getContextAsInt(Env.getCtx(), "#AD_User_ID");
m_AD_Role_ID = Env.getContextAsInt(Env.getCtx(), "#AD_Role_ID");
// m_AD_Client_ID = Env.getContextAsInt(Env.getCtx(), "#AD_Client_ID");
// m_AD_Org_ID = Env.getContextAsInt(Env.getCtx(), "#AD_Org_ID");
// Get Tree
MTree vTree = new MTree (AD_Tree_ID, m_AD_User_ID, m_AD_Role_ID, m_editable);
m_root = vTree.getRoot();
m_tableName = vTree.getTableName();
treeModel = new DefaultTreeModel(m_root, true);
tree.setModel(treeModel);
// Shortcut Bar
if (m_hasBar)
{
bar.removeAll(); // remove all existing buttons
Enumeration en = m_root.preorderEnumeration();
while (en.hasMoreElements())
{
MTreeNode nd = (MTreeNode)en.nextElement();
if (nd.isOnBar())
addToBar(nd);
}
}
return true;
} // initTree
private BorderLayout mainLayout = new BorderLayout();
private JTree tree = new JTree();
private DefaultTreeModel treeModel;
private DefaultTreeSelectionModel treeSelect = new DefaultTreeSelectionModel();
private CPanel southPanel = new CPanel();
private CCheckBox treeExpand = new CCheckBox();
private CTextField treeSearch = new CTextField(10);
private JPopupMenu popMenuTree = new JPopupMenu();
private JPopupMenu popMenuBar = new JPopupMenu();
private JMenuItem mFrom = new JMenuItem();
private JMenuItem mTo = new JMenuItem();
private CPanel bar = new CPanel();
private JMenuItem mBarAdd = new JMenuItem();
private JMenuItem mBarRemove = new JMenuItem();
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_tableName = 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;
/** User */
private int m_AD_User_ID;
/** Login Role */
private int m_AD_Role_ID;
/** Client */
private int m_AD_Client_ID;
/** Org */
private int m_AD_Org_ID;
private MTreeNode m_moveNode; // the node to move
private String m_search = "";
private Enumeration m_nodeEn;
private MTreeNode m_selectedNode; // the selected model node
private CButton m_buttonSelected;
// Property Listener
public static final String NODE_SELECTION = "NodeSelected";
/**
* Static Component initialization.
* <pre>
* - centerSplitPane
* - treePane
* - tree
* - bar
* - southPanel
* </pre>
* @throws Exception
*/
private void jbInit()
{
this.setLayout(mainLayout);
mainLayout.setVgap(5);
//
// only one node to be selected
treeSelect.setSelectionMode(DefaultTreeSelectionModel.SINGLE_TREE_SELECTION);
tree.setSelectionModel(treeSelect);
//
tree.setEditable(false); // allows to change the text
tree.addMouseListener(mouseListener);
tree.addKeyListener(keyListener);
tree.setCellRenderer(new VTreeCellRenderer());
treePane.getViewport().add(tree, null);
// treePane.setPreferredSize(new Dimension(50,200));
// tree.setPreferredSize(new Dimension(100,150));
//
treeExpand.setText("Expand");
treeExpand.setActionCommand("Expand");
treeExpand.addMouseListener(mouseListener);
treeExpand.addActionListener(this);
treeSearch.setBackground(CompierePLAF.getInfoBackground());
treeSearch.addKeyListener(keyListener);
southPanel.setLayout(southLayout);
southPanel.add(treeExpand, BorderLayout.WEST);
southPanel.add(treeSearch, BorderLayout.EAST);
this.add(southPanel, BorderLayout.SOUTH);
//
centerSplitPane.add(treePane, JSplitPane.RIGHT);
centerSplitPane.add(bar, JSplitPane.LEFT);
this.add(centerSplitPane, BorderLayout.CENTER);
//
mFrom.setText("From.");
mFrom.setActionCommand("From");
mFrom.addActionListener(this);
mTo.setEnabled(false);
mTo.setText("To.");
mTo.setActionCommand("To");
mTo.addActionListener(this);
//
bar.setLayout(new BoxLayout(bar, BoxLayout.Y_AXIS));
bar.setMinimumSize(new Dimension (50,50));
mBarAdd.setText("BarAdd.");
mBarAdd.setActionCommand("BarAdd");
mBarAdd.addActionListener(this);
mBarRemove.setText("BarRemove.");
mBarRemove.setActionCommand("BarRemove");
mBarRemove.addActionListener(this);
//
popMenuTree.setLightWeightPopupEnabled(false);
popMenuTree.add(mBarAdd);
popMenuTree.addSeparator();
popMenuTree.add(mFrom);
popMenuTree.add(mTo);
popMenuBar.setLightWeightPopupEnabled(false);
popMenuBar.add(mBarRemove);
// translation
treeExpand.setText(Msg.getMsg(Env.getCtx(), "ExpandTree"));
treeSearch.setToolTipText(Msg.getMsg(Env.getCtx(), "EnterSearchText"));
mBarAdd.setText(Msg.getMsg(Env.getCtx(), "BarAdd"));
mBarRemove.setText(Msg.getMsg(Env.getCtx(), "BarRemove"));
mFrom.setText(Msg.getMsg(Env.getCtx(), "ItemMove"));
mTo.setText(Msg.getMsg(Env.getCtx(), "ItemInsert"));
} // jbInit
/*************************************************************************
* Drag & Drop
*/
protected DragSource dragSource
= DragSource.getDefaultDragSource();
protected DropTarget dropTarget
= new DropTarget(tree, DnDConstants.ACTION_MOVE, this, true, null);
protected DragGestureRecognizer recognizer
= dragSource.createDefaultDragGestureRecognizer(tree, DnDConstants.ACTION_MOVE, this);
/**
* Drag Gesture Interface ** Start **
* @param e event
*/
public void dragGestureRecognized(DragGestureEvent e)
{
if (!m_editable)
return;
//
try
{
m_moveNode = (MTreeNode)tree.getSelectionPath().getLastPathComponent();
}
catch (Exception ex) // nothing selected
{
return;
}
// start moving
StringSelection content = new StringSelection(m_moveNode.toString());
e.startDrag(DragSource.DefaultMoveDrop, // cursor
content, // Transferable
this);
Log.trace(Log.l5_DData, "Drag: " + m_moveNode.toString());
} // dragGestureRecognized
/**
* DragSourceListener interface
* @param e event
*/
public void dragDropEnd(DragSourceDropEvent e) {}
public void dragEnter(DragSourceDragEvent e) {}
public void dragExit(DragSourceEvent e) {}
public void dragOver(DragSourceDragEvent e) {}
public void dropActionChanged(DragSourceDragEvent e) {}
/**
* DropTargetListener interface
* @param e event
*/
public void dragEnter(DropTargetDragEvent e)
{
e.acceptDrag(DnDConstants.ACTION_MOVE);
}
public void dropActionChanged(DropTargetDragEvent e) {}
public void dragExit(DropTargetEvent e) {}
/**
* Drag over ** Between **
* @param e event
*/
public void dragOver(DropTargetDragEvent e)
{
Point mouseLoc = e.getLocation(); // where are we?
TreePath path = tree.getClosestPathForLocation(mouseLoc.x, mouseLoc.y);
tree.setSelectionPath(path); // show it by selecting
MTreeNode toNode = (MTreeNode)path.getLastPathComponent();
//
// Log.trace(Log.l5_DData, "Move: " + toNode);
if (m_moveNode == null // nothing to move
|| toNode == null) // nothing to drop on
e.rejectDrag();
else
e.acceptDrag(DnDConstants.ACTION_MOVE);
} // dragOver
/**
* Drop ** End **
* @param e event
*/
public void drop(DropTargetDropEvent e)
{
Point mouseLoc = e.getLocation(); // where are we?
TreePath path = tree.getClosestPathForLocation(mouseLoc.x, mouseLoc.y);
tree.setSelectionPath(path); // show it by selecting
MTreeNode toNode = (MTreeNode)path.getLastPathComponent();
//
Log.trace(Log.l5_DData, "Drop: " + toNode);
if (m_moveNode == null // nothing to move
|| toNode == null) // nothing to drop on
{
e.rejectDrop();
return;
}
//
e.acceptDrop(DnDConstants.ACTION_MOVE);
moveNode(m_moveNode, toNode);
e.dropComplete(true);
m_moveNode = null;
} // drop
/**
* Move TreeNode
* @param movingNode The node to be moved
* @param toNode The target node
*/
private void moveNode(MTreeNode movingNode, MTreeNode toNode)
{
Log.trace(Log.l1_User, "VTreePanel.moveNode " + movingNode.toString() + " to " + toNode.toString());
if (movingNode == toNode)
return;
// remove
MTreeNode oldParent = (MTreeNode)movingNode.getParent();
movingNode.removeFromParent();
treeModel.nodeStructureChanged(oldParent);
// insert
MTreeNode newParent;
int index;
if (!toNode.isSummary()) // drop on a child node
{
newParent = (MTreeNode)toNode.getParent();
index = newParent.getIndex(toNode) + 1; // the next node
}
else // drop on a summary node
{
newParent = toNode;
index = 0; // the first node
}
newParent.insert(movingNode, index);
treeModel.nodeStructureChanged(newParent);
// *** Save changes to disk
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
Connection conn = DB.getConnectionRW();
try
{
conn.setAutoCommit(false);
Statement stmt = conn.createStatement();
// START TRANSACTION **************
for (int i = 0; i < oldParent.getChildCount(); i++)
{
MTreeNode nd = (MTreeNode)oldParent.getChildAt(i);
StringBuffer sql = new StringBuffer("UPDATE ");
sql.append(m_tableName)
.append(" SET Parent_ID=").append(oldParent.getID())
.append(", SeqNo=").append(i)
.append(", Updated=SysDate")
.append(" WHERE AD_Tree_ID=").append(m_AD_Tree_ID)
.append(" AND Node_ID=").append(nd.getID());
Log.trace(Log.l6_Database, "SQL", sql.toString());
stmt.executeUpdate(sql.toString());
}
if (oldParent != newParent)
for (int i = 0; i < newParent.getChildCount(); i++)
{
MTreeNode nd = (MTreeNode)newParent.getChildAt(i);
StringBuffer sql = new StringBuffer("UPDATE ");
sql.append(m_tableName)
.append(" SET Parent_ID=").append(newParent.getID())
.append(", SeqNo=").append(i)
.append(", Updated=SysDate")
.append(" WHERE AD_Tree_ID=").append(m_AD_Tree_ID)
.append(" AND Node_ID=").append(nd.getID());
Log.trace(Log.l6_Database, "SQL", sql.toString());
stmt.executeUpdate(sql.toString());
}
// COMMIT *********************
try
{
conn.commit(); // may throw exception if nothing to commit
}
catch (Exception e1)
{
Log.error("VTreePanel.moveNode - commit", e1);
}
stmt.close();
conn.close();
}
catch (SQLException e)
{
try
{
conn.rollback();
conn.close();
}
catch (SQLException e2) {}
Log.error("VTreePanel.moveNode", e);
ADialog.error(m_WindowNo, this, "TreeUpdateError", e.getLocalizedMessage());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -