2032092 Java 6 improvements to tree drag and drop
https://sourceforge.net/tracker/index.php?func=detail&aid=2032092&group_id=176962&atid=879335
This commit is contained in:
parent
12697db738
commit
74e91fcb82
|
@ -317,7 +317,6 @@ public final class AMenu extends CFrame
|
|||
mainLayout.setVgap(2);
|
||||
//
|
||||
treePanel.addPropertyChangeListener(VTreePanel.NODE_SELECTION, this);
|
||||
treePanel.addPropertyChangeListener(VTreePanel.NODE_SELECTION_RIGHT, this);
|
||||
//
|
||||
infoPanel.setLayout(infoLayout);
|
||||
infoLayout.setColumns(2);
|
||||
|
@ -575,11 +574,6 @@ public final class AMenu extends CFrame
|
|||
*/
|
||||
public void propertyChange(PropertyChangeEvent e)
|
||||
{
|
||||
if(e.getPropertyName().equals(VTreePanel.NODE_SELECTION_RIGHT)){
|
||||
MTreeNode nd = (MTreeNode)e.getNewValue();
|
||||
progressBar.setString(nd.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
MTreeNode nd = (MTreeNode)e.getNewValue();
|
||||
log.info(nd.getNode_ID() + " - " + nd.toString());
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
/******************************************************************************
|
||||
* 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.util.logging.Level;
|
||||
|
||||
import javax.swing.tree.DefaultTreeModel;
|
||||
import javax.swing.tree.TreeNode;
|
||||
|
||||
import org.compiere.model.MTree;
|
||||
import org.compiere.model.MTreeNode;
|
||||
import org.compiere.util.CLogger;
|
||||
import org.compiere.util.DB;
|
||||
import org.compiere.util.Trx;
|
||||
|
||||
/**
|
||||
* AdempiereTreeModel provides a persistable tree model based on an MTree.
|
||||
*
|
||||
* @author phib 2008/07/30
|
||||
* FR [ 2032092 ] Java 6 improvements to tree drag and drop
|
||||
*/
|
||||
public class AdempiereTreeModel extends DefaultTreeModel {
|
||||
|
||||
/** Logger */
|
||||
private static CLogger log = CLogger.getCLogger(AdempiereTreeModel.class);
|
||||
|
||||
private MTree m_MTree;
|
||||
public AdempiereTreeModel(TreeNode root) {
|
||||
super(root);
|
||||
}
|
||||
|
||||
public AdempiereTreeModel(MTreeNode root, boolean b) {
|
||||
super(root, b);
|
||||
}
|
||||
|
||||
public void setMTree(MTree tree) {
|
||||
|
||||
m_MTree = tree;
|
||||
|
||||
}
|
||||
|
||||
public void saveChangedNodes(MTreeNode from, MTreeNode to) {
|
||||
int AD_Tree_ID = m_MTree.getAD_Tree_ID();
|
||||
Trx trx = Trx.get (Trx.createTrxName("AdempiereTreeModel"), true);
|
||||
try
|
||||
{
|
||||
int no = 0;
|
||||
for (int i = 0; i < from.getChildCount(); i++)
|
||||
{
|
||||
MTreeNode nd = (MTreeNode)from.getChildAt(i);
|
||||
StringBuffer sql = new StringBuffer("UPDATE ");
|
||||
sql.append(m_MTree.getNodeTableName())
|
||||
.append(" SET Parent_ID=").append(from.getNode_ID())
|
||||
.append(", SeqNo=").append(i)
|
||||
.append(", Updated=SysDate")
|
||||
.append(" WHERE AD_Tree_ID=").append(AD_Tree_ID)
|
||||
.append(" AND Node_ID=").append(nd.getNode_ID());
|
||||
no = DB.executeUpdate(sql.toString(),trx.getTrxName());
|
||||
}
|
||||
if (from != to)
|
||||
for (int i = 0; i < to.getChildCount(); i++)
|
||||
{
|
||||
MTreeNode nd = (MTreeNode)to.getChildAt(i);
|
||||
StringBuffer sql = new StringBuffer("UPDATE ");
|
||||
sql.append(m_MTree.getNodeTableName())
|
||||
.append(" SET Parent_ID=").append(to.getNode_ID())
|
||||
.append(", SeqNo=").append(i)
|
||||
.append(", Updated=SysDate")
|
||||
.append(" WHERE AD_Tree_ID=").append(AD_Tree_ID)
|
||||
.append(" AND Node_ID=").append(nd.getNode_ID());
|
||||
log.fine(sql.toString());
|
||||
no = DB.executeUpdate(sql.toString(),trx.getTrxName());
|
||||
}
|
||||
trx.commit(true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
trx.rollback();
|
||||
log.log(Level.SEVERE, "move", e);
|
||||
}
|
||||
trx.close();
|
||||
trx = null;
|
||||
log.config("complete");
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/******************************************************************************
|
||||
* 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.datatransfer.DataFlavor;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.awt.datatransfer.UnsupportedFlavorException;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.compiere.model.MTreeNode;
|
||||
|
||||
/**
|
||||
* TransferableTreeNode wraps an MTreeNode into a Transferable for
|
||||
* use by drag and drop type actions.
|
||||
*
|
||||
*
|
||||
* @author phib 2008/07/30
|
||||
* FR [ 2032092 ] Java 6 improvements to tree drag and drop
|
||||
*/
|
||||
class TransferableTreeNode implements Transferable {
|
||||
|
||||
public static DataFlavor TREE_NODE_FLAVOR = new DataFlavor(MTreeNode.class,
|
||||
"Tree Path");
|
||||
|
||||
DataFlavor flavors[] = { TREE_NODE_FLAVOR };
|
||||
|
||||
MTreeNode node;
|
||||
|
||||
public TransferableTreeNode(MTreeNode node) {
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
public synchronized DataFlavor[] getTransferDataFlavors() {
|
||||
return flavors;
|
||||
}
|
||||
|
||||
public boolean isDataFlavorSupported(DataFlavor flavor) {
|
||||
return (flavor.getRepresentationClass() == MTreeNode.class);
|
||||
}
|
||||
|
||||
public synchronized Object getTransferData(DataFlavor flavor)
|
||||
throws UnsupportedFlavorException, IOException {
|
||||
if (isDataFlavorSupported(flavor)) {
|
||||
return (Object) node;
|
||||
} else {
|
||||
throw new UnsupportedFlavorException(flavor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
/******************************************************************************
|
||||
* 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 *
|
||||
|
@ -23,23 +23,7 @@ import java.awt.Cursor;
|
|||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.awt.dnd.DnDConstants;
|
||||
import java.awt.dnd.DragGestureEvent;
|
||||
import java.awt.dnd.DragGestureListener;
|
||||
import java.awt.dnd.DragGestureRecognizer;
|
||||
import java.awt.dnd.DragSource;
|
||||
import java.awt.dnd.DragSourceDragEvent;
|
||||
import java.awt.dnd.DragSourceDropEvent;
|
||||
import java.awt.dnd.DragSourceEvent;
|
||||
import java.awt.dnd.DragSourceListener;
|
||||
import java.awt.dnd.DropTarget;
|
||||
import java.awt.dnd.DropTargetDragEvent;
|
||||
import java.awt.dnd.DropTargetDropEvent;
|
||||
import java.awt.dnd.DropTargetEvent;
|
||||
import java.awt.dnd.DropTargetListener;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
@ -54,7 +38,10 @@ 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;
|
||||
|
@ -66,11 +53,12 @@ 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.DefaultTreeModel;
|
||||
import javax.swing.tree.DefaultTreeSelectionModel;
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
|
@ -118,12 +106,15 @@ import de.schaeffer.compiere.tools.DocumentSearch;
|
|||
* @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, DragGestureListener, DragSourceListener, DropTargetListener
|
||||
implements ActionListener
|
||||
{
|
||||
|
||||
/******************************************************************************
|
||||
/******************************************************************************
|
||||
* Mouse Clicked
|
||||
*/
|
||||
class VTreePanel_mouseAdapter extends java.awt.event.MouseAdapter
|
||||
|
@ -188,6 +179,8 @@ public final class VTreePanel extends CPanel
|
|||
|
||||
protected boolean m_lookAndFeelChanged = false;
|
||||
|
||||
private VTreeTransferHandler handler = new VTreeTransferHandler();
|
||||
|
||||
/**
|
||||
* Tree Panel for browsing and editing of a tree.
|
||||
* Need to call initTree
|
||||
|
@ -225,12 +218,16 @@ public final class VTreePanel extends CPanel
|
|||
if ("lookAndFeel".equals(evt.getPropertyName()))
|
||||
m_lookAndFeelChanged = true;
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
// base settings
|
||||
if (editable)
|
||||
tree.setDropTarget(dropTarget);
|
||||
if (editable) {
|
||||
tree.setDragEnabled(true);
|
||||
tree.setTransferHandler(handler);
|
||||
tree.setDropMode(DropMode.INSERT);
|
||||
setMappings(tree);
|
||||
}
|
||||
else
|
||||
{
|
||||
popMenuTree.remove(mFrom);
|
||||
|
@ -258,7 +255,8 @@ public final class VTreePanel extends CPanel
|
|||
|
||||
log.config("root=" + m_root);
|
||||
m_nodeTableName = vTree.getNodeTableName();
|
||||
treeModel = new DefaultTreeModel(m_root, true);
|
||||
treeModel = new AdempiereTreeModel(m_root, true);
|
||||
treeModel.setMTree(vTree);
|
||||
tree.setModel(treeModel);
|
||||
|
||||
// Shortcut Bar
|
||||
|
@ -268,7 +266,7 @@ public final class VTreePanel extends CPanel
|
|||
jt.removeAll();
|
||||
toolbarMap = new HashMap<Integer, JToolBar>();
|
||||
Enumeration<?> enTop = m_root.children();
|
||||
JToolBar jt = null;
|
||||
JToolBar jt = null;
|
||||
Map<JToolBar,String> titleMap = new HashMap<JToolBar, String>();
|
||||
while (enTop.hasMoreElements())
|
||||
{
|
||||
|
@ -299,7 +297,7 @@ public final class VTreePanel extends CPanel
|
|||
jt2.setFloatable(false);
|
||||
jt2.setRollover(true);
|
||||
jt2.setBorder(BorderFactory.createEmptyBorder());
|
||||
|
||||
|
||||
JXTaskPane barPart = new JXTaskPane();
|
||||
//Begin - [FR 1953769]
|
||||
barPart.setUI(new AdempiereTaskPaneUI());
|
||||
|
@ -309,7 +307,7 @@ public final class VTreePanel extends CPanel
|
|||
barPart.setLayout(new BorderLayout());
|
||||
barPart.add(jt2, BorderLayout.NORTH);
|
||||
barPart.setTitle(titleMap.get(jt2));
|
||||
|
||||
|
||||
bar.add(barPart);
|
||||
//Begin - [FR 1953769]
|
||||
bar.setBackground(AdempierePLAF.getFormBackground());
|
||||
|
@ -324,7 +322,7 @@ public final class VTreePanel extends CPanel
|
|||
|
||||
private BorderLayout mainLayout = new BorderLayout();
|
||||
private JTree tree = new JTree();
|
||||
private DefaultTreeModel treeModel;
|
||||
private AdempiereTreeModel treeModel;
|
||||
private DefaultTreeSelectionModel treeSelect = new DefaultTreeSelectionModel();
|
||||
private CPanel southPanel = new CPanel();
|
||||
private CCheckBox treeExpand = new CCheckBox();
|
||||
|
@ -337,6 +335,7 @@ public final class VTreePanel extends CPanel
|
|||
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();
|
||||
|
@ -359,7 +358,6 @@ public final class VTreePanel extends CPanel
|
|||
private MTreeNode m_root = null;
|
||||
|
||||
|
||||
private MTreeNode m_moveNode; // the node to move
|
||||
private String m_search = "";
|
||||
private Enumeration<?> m_nodeEn;
|
||||
private MTreeNode m_selectedNode; // the selected model node
|
||||
|
@ -369,8 +367,6 @@ public final class VTreePanel extends CPanel
|
|||
|
||||
/** Property Listener NodeSelected by Left Click */
|
||||
public static final String NODE_SELECTION = "NodeSelected";
|
||||
/** Property Listener NodeSelected by Right Click */
|
||||
public static final String NODE_SELECTION_RIGHT = "NodeSelectedRight";
|
||||
|
||||
/**
|
||||
* Static Component initialization.
|
||||
|
@ -398,12 +394,12 @@ public final class VTreePanel extends CPanel
|
|||
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");
|
||||
|
@ -431,16 +427,22 @@ public final class VTreePanel extends CPanel
|
|||
removeSplitPaneBorder();
|
||||
|
||||
this.add(centerSplitPane, BorderLayout.CENTER);
|
||||
|
||||
|
||||
//
|
||||
mFrom.setText(Msg.getMsg(Env.getCtx(), "ItemMove"));
|
||||
mFrom.setActionCommand("From");
|
||||
mFrom.setActionCommand((String)TransferHandler.getCutAction().
|
||||
getValue(Action.NAME));
|
||||
mFrom.addActionListener(this);
|
||||
mTo.setEnabled(false);
|
||||
mFrom.setAccelerator(
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_X, ActionEvent.CTRL_MASK));
|
||||
mTo.setText(Msg.getMsg(Env.getCtx(), "ItemInsert"));
|
||||
mTo.setActionCommand("To");
|
||||
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);
|
||||
|
@ -452,7 +454,7 @@ public final class VTreePanel extends CPanel
|
|||
popMenuTree.add(mBarAdd);
|
||||
popMenuTree.add(mFrom);
|
||||
if(!m_hasBar){
|
||||
popMenuTree.addSeparator();
|
||||
popMenuTree.addSeparator();
|
||||
}
|
||||
popMenuTree.add(mTo);
|
||||
popMenuBar.setLightWeightPopupEnabled(false);
|
||||
|
@ -469,7 +471,7 @@ public final class VTreePanel extends CPanel
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set Divider Location
|
||||
* @param location location (80 default)
|
||||
|
@ -478,7 +480,7 @@ public final class VTreePanel extends CPanel
|
|||
{
|
||||
centerSplitPane.setDividerLocation(location);
|
||||
} // setDividerLocation
|
||||
|
||||
|
||||
/**
|
||||
* Get Divider Location
|
||||
* @return divider location
|
||||
|
@ -487,223 +489,7 @@ public final class VTreePanel extends CPanel
|
|||
{
|
||||
return centerSplitPane.getDividerLocation();
|
||||
} // getDividerLocation
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* 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.fine( "Drag: " + m_moveNode.toString());
|
||||
} // dragGestureRecognized
|
||||
|
||||
|
||||
/**
|
||||
* DragSourceListener interface - noop
|
||||
* @param e event
|
||||
*/
|
||||
public void dragDropEnd(DragSourceDropEvent e) {}
|
||||
/**
|
||||
* DragSourceListener interface - noop
|
||||
* @param e event
|
||||
*/
|
||||
public void dragEnter(DragSourceDragEvent e) {}
|
||||
/**
|
||||
* DragSourceListener interface - noop
|
||||
* @param e event
|
||||
*/
|
||||
public void dragExit(DragSourceEvent e) {}
|
||||
/**
|
||||
* DragSourceListener interface - noop
|
||||
* @param e event
|
||||
*/
|
||||
public void dragOver(DragSourceDragEvent e) {}
|
||||
/**
|
||||
* DragSourceListener interface - noop
|
||||
* @param e event
|
||||
*/
|
||||
public void dropActionChanged(DragSourceDragEvent e) {}
|
||||
|
||||
/**
|
||||
* DropTargetListener interface
|
||||
* @param e event
|
||||
*/
|
||||
public void dragEnter(DropTargetDragEvent e)
|
||||
{
|
||||
e.acceptDrag(DnDConstants.ACTION_MOVE);
|
||||
}
|
||||
/**
|
||||
* DragSourceListener interface - noop
|
||||
* @param e event
|
||||
*/
|
||||
public void dropActionChanged(DropTargetDragEvent e) {}
|
||||
/**
|
||||
* DragSourceListener interface - noop
|
||||
* @param e event
|
||||
*/
|
||||
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.fine( "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.fine( "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.info(movingNode.toString() + " to " + toNode.toString());
|
||||
|
||||
if (movingNode == toNode)
|
||||
return;
|
||||
|
||||
// remove
|
||||
final MTreeNode oldParent = (MTreeNode)movingNode.getParent();
|
||||
movingNode.removeFromParent();
|
||||
treeModel.nodeStructureChanged(oldParent);
|
||||
|
||||
// insert
|
||||
final 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
|
||||
try
|
||||
{
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
Trx.run(new TrxRunnable() {
|
||||
public void run(String trxName) {
|
||||
for (int i = 0; i < oldParent.getChildCount(); i++)
|
||||
{
|
||||
MTreeNode nd = (MTreeNode)oldParent.getChildAt(i);
|
||||
updateTreeNode(nd.getNode_ID(), oldParent.getNode_ID(), i, trxName);
|
||||
}
|
||||
if (oldParent != newParent)
|
||||
{
|
||||
for (int i = 0; i < newParent.getChildCount(); i++)
|
||||
{
|
||||
MTreeNode nd = (MTreeNode)newParent.getChildAt(i);
|
||||
updateTreeNode(nd.getNode_ID(), newParent.getNode_ID(), i, trxName);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.SEVERE, "move", e);
|
||||
ADialog.error(m_WindowNo, this, "TreeUpdateError", e.getLocalizedMessage());
|
||||
}
|
||||
finally
|
||||
{
|
||||
setCursor(Cursor.getDefaultCursor());
|
||||
}
|
||||
log.config("complete");
|
||||
} // moveNode
|
||||
|
||||
private int updateTreeNode(int Node_ID, int Parent_ID, int SeqNo, String trxName)
|
||||
{
|
||||
// We do not use parametrized statements because we need to log these migration scripts
|
||||
StringBuffer sql = new StringBuffer("UPDATE ");
|
||||
sql.append(m_nodeTableName)
|
||||
.append(" SET Parent_ID=").append(Parent_ID)
|
||||
.append(", SeqNo=").append(SeqNo)
|
||||
.append(", Updated=SysDate")
|
||||
.append(", UpdatedBy=").append(Env.getAD_User_ID(Env.getCtx()))
|
||||
.append(" WHERE AD_Tree_ID=").append(m_AD_Tree_ID)
|
||||
.append(" AND Node_ID=").append(Node_ID);
|
||||
log.fine(sql.toString());
|
||||
int no = DB.executeUpdateEx(sql.toString(), trxName);
|
||||
return no;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* Enter Key
|
||||
|
@ -803,24 +589,22 @@ public final class VTreePanel extends CPanel
|
|||
|
||||
// Right Click for PopUp
|
||||
else if ((m_editable || m_hasBar)
|
||||
&& SwingUtilities.isRightMouseButton(e)
|
||||
&& tree.getSelectionPath() != null) // need select first
|
||||
&& SwingUtilities.isRightMouseButton(e) )
|
||||
{
|
||||
int selRow = tree.getRowForLocation(e.getX(), e.getY());
|
||||
TreePath selPath = tree.getPathForLocation(e.getX(), e.getY());
|
||||
if(selRow != -1){
|
||||
tree.setSelectionPath(selPath);
|
||||
|
||||
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());
|
||||
if(r!=null){
|
||||
popMenuTree.show(tree, (int)r.getMaxX(), (int)r.getY());
|
||||
}else{
|
||||
popMenuTree.show(tree, e.getX(), e.getY());
|
||||
}
|
||||
if(m_hasBar){
|
||||
MTreeNode nd = (MTreeNode)tree.getSelectionPath().getLastPathComponent();
|
||||
firePropertyChange(NODE_SELECTION_RIGHT, null, nd);
|
||||
}
|
||||
popMenuTree.show(tree, (int)r.getMaxX(), (int)r.getY());
|
||||
}
|
||||
}
|
||||
} // JTree
|
||||
|
@ -879,14 +663,14 @@ public final class VTreePanel extends CPanel
|
|||
{
|
||||
if (m_root == null)
|
||||
return false;
|
||||
log.config("NodeID=" + nodeID
|
||||
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
|
||||
log.config("Node=" + node
|
||||
+ ", Path=" + treePath.toString());
|
||||
tree.setSelectionPath(treePath);
|
||||
if (show)
|
||||
|
@ -913,7 +697,7 @@ public final class VTreePanel extends CPanel
|
|||
firePropertyChange(NODE_SELECTION, null, nd);
|
||||
} // setSelectedNode
|
||||
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Node Changed - synchronize Node
|
||||
*
|
||||
|
@ -928,13 +712,13 @@ public final class VTreePanel extends CPanel
|
|||
String name, String description, boolean isSummary, String imageIndicator)
|
||||
{
|
||||
log.config("Save=" + save + ", KeyID=" + keyID
|
||||
+ ", Name=" + name + ", Description=" + description
|
||||
+ ", Name=" + name + ", Description=" + description
|
||||
+ ", IsSummary=" + isSummary + ", ImageInd=" + imageIndicator
|
||||
+ ", root=" + m_root);
|
||||
// if ID==0=root - don't update it
|
||||
if (keyID == 0)
|
||||
return;
|
||||
|
||||
return;
|
||||
|
||||
// try to find the node
|
||||
MTreeNode node = m_root.findNode(keyID);
|
||||
|
||||
|
@ -1000,13 +784,16 @@ public final class VTreePanel extends CPanel
|
|||
// popup menu commands
|
||||
else if (e.getSource() instanceof JMenuItem)
|
||||
{
|
||||
if (e.getActionCommand().equals("From"))
|
||||
moveFrom();
|
||||
else if (e.getActionCommand().equals("To"))
|
||||
moveTo();
|
||||
else if (e.getActionCommand().equals("BarAdd"))
|
||||
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 (e.getActionCommand().equals("BarRemove"))
|
||||
else if (action.equals("BarRemove"))
|
||||
barRemove();
|
||||
}
|
||||
|
||||
|
@ -1017,35 +804,6 @@ public final class VTreePanel extends CPanel
|
|||
}
|
||||
} // actionPerformed
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* Copy Node into buffer
|
||||
*/
|
||||
private void moveFrom()
|
||||
{
|
||||
m_moveNode = (MTreeNode)tree.getSelectionPath().getLastPathComponent();
|
||||
if (m_moveNode != null)
|
||||
mTo.setEnabled(true); // enable menu
|
||||
} // mFrom_actionPerformed
|
||||
|
||||
/**
|
||||
* Move Node
|
||||
*/
|
||||
private void moveTo()
|
||||
{
|
||||
mFrom.setEnabled(true);
|
||||
mTo.setEnabled(false);
|
||||
if (m_moveNode == null)
|
||||
return;
|
||||
|
||||
MTreeNode toNode = (MTreeNode)tree.getSelectionPath().getLastPathComponent();
|
||||
moveNode(m_moveNode, toNode);
|
||||
// cleanup
|
||||
m_moveNode = null;
|
||||
} // mTo_actionPerformed
|
||||
|
||||
/**
|
||||
* Add selected TreeNode to Bar
|
||||
*/
|
||||
|
@ -1057,9 +815,9 @@ public final class VTreePanel extends CPanel
|
|||
else if (CLogger.retrieveException().getMessage().indexOf("ORA-00001")!=-1)
|
||||
ADialog.error(0, this, "BookmarkExist", null);
|
||||
} // barAdd
|
||||
|
||||
|
||||
/**
|
||||
* Returns the top level parent JToolBar for the given MTreenode. If the parent is not on
|
||||
* 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
|
||||
|
@ -1168,7 +926,7 @@ public final class VTreePanel extends CPanel
|
|||
bar.remove(parentPanel);
|
||||
//remove from toolBarMap..
|
||||
toolbarMap.values().remove(parentBar);
|
||||
|
||||
|
||||
}
|
||||
bar.validate();
|
||||
bar.repaint();
|
||||
|
@ -1231,8 +989,16 @@ public final class VTreePanel extends CPanel
|
|||
}
|
||||
super.paint(g);
|
||||
}
|
||||
|
||||
//CHANGED - SET BUSY ADDED
|
||||
|
||||
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
|
||||
|
@ -1256,8 +1022,9 @@ public final class VTreePanel extends CPanel
|
|||
treeSearch.setCursor(Cursor.getDefaultCursor());
|
||||
}
|
||||
} // set Busy
|
||||
|
||||
|
||||
|
||||
} // VTreePanel
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
/******************************************************************************
|
||||
* 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.datatransfer.Transferable;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.TransferHandler;
|
||||
import javax.swing.tree.DefaultTreeModel;
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
import org.compiere.model.MTreeNode;
|
||||
|
||||
/**
|
||||
* VTreeTransferHandler provides the TransferHandler for dragging and dropping
|
||||
* within a tree. See VTreePanel.
|
||||
*
|
||||
*
|
||||
* @author phib 2008/07/30
|
||||
* FR [ 2032092 ] Java 6 improvements to tree drag and drop
|
||||
*/
|
||||
public class VTreeTransferHandler extends TransferHandler {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public int getSourceActions(JComponent c) {
|
||||
return TransferHandler.MOVE;
|
||||
}
|
||||
|
||||
protected Transferable createTransferable(JComponent c) {
|
||||
JTree tree = (JTree) c;
|
||||
MTreeNode node = (MTreeNode) tree.getSelectionPath().getLastPathComponent();
|
||||
return new TransferableTreeNode(node);
|
||||
}
|
||||
|
||||
protected void exportDone(JComponent c, Transferable t, int action) {
|
||||
if (action == MOVE) {
|
||||
JTree tree = (JTree) c;
|
||||
MTreeNode node = null;
|
||||
try {
|
||||
node = (MTreeNode) t.getTransferData(TransferableTreeNode.TREE_NODE_FLAVOR);
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
if ( node != null )
|
||||
((DefaultTreeModel) tree.getModel()).removeNodeFromParent(node);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canImport(TransferSupport info) {
|
||||
// Check for flavor
|
||||
if (!info.isDataFlavorSupported(TransferableTreeNode.TREE_NODE_FLAVOR)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean importData(TransferHandler.TransferSupport info) {
|
||||
if (!canImport(info))
|
||||
return false;
|
||||
|
||||
JTree tree = (JTree) info.getComponent();
|
||||
AdempiereTreeModel model = (AdempiereTreeModel) tree.getModel();
|
||||
Transferable t = info.getTransferable();
|
||||
MTreeNode to = null;
|
||||
MTreeNode from = null;
|
||||
int index;
|
||||
try {
|
||||
from = (MTreeNode)t.getTransferData(TransferableTreeNode.TREE_NODE_FLAVOR);
|
||||
}
|
||||
catch (Exception e) { return false; }
|
||||
|
||||
if (info.isDrop()) {
|
||||
JTree.DropLocation dl = (JTree.DropLocation)info.getDropLocation();
|
||||
to = (MTreeNode) dl.getPath().getLastPathComponent();
|
||||
|
||||
if (from == to)
|
||||
return false;
|
||||
|
||||
index = dl.getChildIndex();
|
||||
if ( index == -1 )
|
||||
index = 0; // insert as first child
|
||||
|
||||
}
|
||||
else { // it's a paste
|
||||
MTreeNode selected = (MTreeNode) tree.getSelectionPath().getLastPathComponent();
|
||||
if ( selected.isLeaf() ) {
|
||||
to = (MTreeNode) selected.getParent();
|
||||
index = to.getIndex(selected) + 1; // insert after selected
|
||||
}
|
||||
else {
|
||||
to = selected;
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
model.insertNodeInto(from, to, index);
|
||||
tree.scrollPathToVisible(new TreePath(from.getPath())); // display from's new location
|
||||
model.saveChangedNodes(from, to);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue