⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vtreepanel.java

📁 Java写的ERP系统
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************
 * 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 + -