拖放 TransferHandler 问题 Java
Drag and Drop TransferHandler Problems Java
我在两个 JTree
之间进行拖放以移动一些节点。我已将其设置为当 JTree
上的节点移动到另一个节点时将删除这些节点。但是每次我测试它时,我的操作值都是 0。代码有什么问题?
protected void exportDone(JComponent source, Transferable data, int action)
{
if(action == MOVE)
{
JTree tree = (JTree)source;
TreePath [] paths = tree.getSelectionPaths();
DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
for(TreePath temp : paths)
{
model.removeNodeFromParent((MutableTreeNode) temp.getLastPathComponent());
}
}
}
public int getSourceActions(JComponent c)
{
return MOVE;
}
从DefaultTreeModel#removeNodeFromParent(...)
方法的使用推测,你对如何使用DefaultTreeModel#insertNodeInto(...)
有疑问:
@Override public boolean importData(TransferSupport support) {
if (!canImport(support)) {
return false;
}
DefaultMutableTreeNode[] nodes = null;
try {
Transferable t = support.getTransferable();
nodes = (DefaultMutableTreeNode[]) t.getTransferData(flavor);
} catch (UnsupportedFlavorException | IOException ex) {
ex.printStackTrace();
}
JTree.DropLocation dl = (JTree.DropLocation) support.getDropLocation();
int childIndex = dl.getChildIndex();
TreePath dest = dl.getPath();
DefaultMutableTreeNode parent = (DefaultMutableTreeNode) dest.getLastPathComponent();
JTree tree = (JTree) support.getComponent();
DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
int index = childIndex;
if (childIndex == -1) {
index = parent.getChildCount();
}
for (DefaultMutableTreeNode node: nodes) {
//BAD: model.insertNodeInto(node, parent, index++);
//Need to use clone of DefaultMutableTreeNode
DefaultMutableTreeNode clone = new DefaultMutableTreeNode(node.getUserObject());
//if !node.isLeaf(): clone = somethingDeepCopyTreeNode(node, clone);
model.insertNodeInto(clone, parent, index++);
}
return true;
}
SSCCE
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.util.*;
import java.util.List;
import javax.activation.*;
import javax.swing.*;
import javax.swing.tree.*;
public class TreeDragAndDropTest {
private JComponent makeUI() {
TreeTransferHandler handler = new TreeTransferHandler();
JPanel p = new JPanel(new GridLayout(1, 2));
p.add(new JScrollPane(makeTree(handler)));
p.add(new JScrollPane(makeTree(handler)));
return p;
}
private static JTree makeTree(TransferHandler hanlder) {
JTree tree = new JTree();
tree.setRootVisible(false);
tree.setDragEnabled(true);
tree.setTransferHandler(hanlder);
tree.setDropMode(DropMode.INSERT);
tree.getSelectionModel().setSelectionMode(
TreeSelectionModel.SINGLE_TREE_SELECTION);
expandTree(tree);
return tree;
}
public static void expandTree(JTree tree) {
for (int i = 0; i < tree.getRowCount(); i++) {
tree.expandRow(i);
}
}
public static void main(String... args) {
EventQueue.invokeLater(() -> {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new TreeDragAndDropTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
class TreeTransferHandler extends TransferHandler {
private static final DataFlavor localObjectFlavor = new ActivationDataFlavor(
DefaultMutableTreeNode[].class,
DataFlavor.javaJVMLocalObjectMimeType,
"Array of DefaultMutableTreeNode");
private JTree source;
@Override protected Transferable createTransferable(JComponent c) {
source = (JTree) c;
TreePath[] paths = source.getSelectionPaths();
DefaultMutableTreeNode[] nodes = new DefaultMutableTreeNode[paths.length];
for (int i = 0; i < paths.length; i++) {
nodes[i] = (DefaultMutableTreeNode) paths[i].getLastPathComponent();
}
return new DataHandler(nodes, localObjectFlavor.getMimeType());
}
@Override public int getSourceActions(JComponent c) {
return MOVE;
}
@Override public boolean canImport(TransferSupport support) {
if (!support.isDrop()) {
return false;
}
if (!support.isDataFlavorSupported(localObjectFlavor)) {
return false;
}
JTree.DropLocation dl = (JTree.DropLocation) support.getDropLocation();
JTree tree = (JTree) support.getComponent();
return !tree.equals(source);
}
@Override public boolean importData(TransferSupport support) {
if (!canImport(support)) {
return false;
}
DefaultMutableTreeNode[] nodes = null;
try {
Transferable t = support.getTransferable();
nodes = (DefaultMutableTreeNode[]) t.getTransferData(localObjectFlavor);
} catch (UnsupportedFlavorException | IOException ex) {
ex.printStackTrace();
}
JTree.DropLocation dl = (JTree.DropLocation) support.getDropLocation();
int childIndex = dl.getChildIndex();
TreePath dest = dl.getPath();
DefaultMutableTreeNode parent =
(DefaultMutableTreeNode) dest.getLastPathComponent();
JTree tree = (JTree) support.getComponent();
DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
int idx = childIndex < 0 ? parent.getChildCount() : childIndex;
//DefaultTreeModel sm = (DefaultTreeModel) source.getModel();
for (DefaultMutableTreeNode node : nodes) {
//sm.removeNodeFromParent(node);
//model.insertNodeInto(node, parent, idx++);
DefaultMutableTreeNode clone = new DefaultMutableTreeNode(node.getUserObject());
model.insertNodeInto(deepCopyTreeNode(node, clone), parent, idx++);
}
return true;
}
private static DefaultMutableTreeNode deepCopyTreeNode(
DefaultMutableTreeNode src, DefaultMutableTreeNode tgt) {
for (int i = 0; i < src.getChildCount(); i++) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) src.getChildAt(i);
DefaultMutableTreeNode clone = new DefaultMutableTreeNode(node.getUserObject());
tgt.add(clone);
if (!node.isLeaf()) {
deepCopyTreeNode(node, clone);
}
}
return tgt;
}
@Override protected void exportDone(JComponent source, Transferable data, int action) {
if (action == MOVE) {
JTree tree = (JTree) source;
DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
for (TreePath path : tree.getSelectionPaths()) {
model.removeNodeFromParent((MutableTreeNode) path.getLastPathComponent());
}
}
}
}
我在两个 JTree
之间进行拖放以移动一些节点。我已将其设置为当 JTree
上的节点移动到另一个节点时将删除这些节点。但是每次我测试它时,我的操作值都是 0。代码有什么问题?
protected void exportDone(JComponent source, Transferable data, int action)
{
if(action == MOVE)
{
JTree tree = (JTree)source;
TreePath [] paths = tree.getSelectionPaths();
DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
for(TreePath temp : paths)
{
model.removeNodeFromParent((MutableTreeNode) temp.getLastPathComponent());
}
}
}
public int getSourceActions(JComponent c)
{
return MOVE;
}
从DefaultTreeModel#removeNodeFromParent(...)
方法的使用推测,你对如何使用DefaultTreeModel#insertNodeInto(...)
有疑问:
@Override public boolean importData(TransferSupport support) {
if (!canImport(support)) {
return false;
}
DefaultMutableTreeNode[] nodes = null;
try {
Transferable t = support.getTransferable();
nodes = (DefaultMutableTreeNode[]) t.getTransferData(flavor);
} catch (UnsupportedFlavorException | IOException ex) {
ex.printStackTrace();
}
JTree.DropLocation dl = (JTree.DropLocation) support.getDropLocation();
int childIndex = dl.getChildIndex();
TreePath dest = dl.getPath();
DefaultMutableTreeNode parent = (DefaultMutableTreeNode) dest.getLastPathComponent();
JTree tree = (JTree) support.getComponent();
DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
int index = childIndex;
if (childIndex == -1) {
index = parent.getChildCount();
}
for (DefaultMutableTreeNode node: nodes) {
//BAD: model.insertNodeInto(node, parent, index++);
//Need to use clone of DefaultMutableTreeNode
DefaultMutableTreeNode clone = new DefaultMutableTreeNode(node.getUserObject());
//if !node.isLeaf(): clone = somethingDeepCopyTreeNode(node, clone);
model.insertNodeInto(clone, parent, index++);
}
return true;
}
SSCCE
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.util.*;
import java.util.List;
import javax.activation.*;
import javax.swing.*;
import javax.swing.tree.*;
public class TreeDragAndDropTest {
private JComponent makeUI() {
TreeTransferHandler handler = new TreeTransferHandler();
JPanel p = new JPanel(new GridLayout(1, 2));
p.add(new JScrollPane(makeTree(handler)));
p.add(new JScrollPane(makeTree(handler)));
return p;
}
private static JTree makeTree(TransferHandler hanlder) {
JTree tree = new JTree();
tree.setRootVisible(false);
tree.setDragEnabled(true);
tree.setTransferHandler(hanlder);
tree.setDropMode(DropMode.INSERT);
tree.getSelectionModel().setSelectionMode(
TreeSelectionModel.SINGLE_TREE_SELECTION);
expandTree(tree);
return tree;
}
public static void expandTree(JTree tree) {
for (int i = 0; i < tree.getRowCount(); i++) {
tree.expandRow(i);
}
}
public static void main(String... args) {
EventQueue.invokeLater(() -> {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new TreeDragAndDropTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
class TreeTransferHandler extends TransferHandler {
private static final DataFlavor localObjectFlavor = new ActivationDataFlavor(
DefaultMutableTreeNode[].class,
DataFlavor.javaJVMLocalObjectMimeType,
"Array of DefaultMutableTreeNode");
private JTree source;
@Override protected Transferable createTransferable(JComponent c) {
source = (JTree) c;
TreePath[] paths = source.getSelectionPaths();
DefaultMutableTreeNode[] nodes = new DefaultMutableTreeNode[paths.length];
for (int i = 0; i < paths.length; i++) {
nodes[i] = (DefaultMutableTreeNode) paths[i].getLastPathComponent();
}
return new DataHandler(nodes, localObjectFlavor.getMimeType());
}
@Override public int getSourceActions(JComponent c) {
return MOVE;
}
@Override public boolean canImport(TransferSupport support) {
if (!support.isDrop()) {
return false;
}
if (!support.isDataFlavorSupported(localObjectFlavor)) {
return false;
}
JTree.DropLocation dl = (JTree.DropLocation) support.getDropLocation();
JTree tree = (JTree) support.getComponent();
return !tree.equals(source);
}
@Override public boolean importData(TransferSupport support) {
if (!canImport(support)) {
return false;
}
DefaultMutableTreeNode[] nodes = null;
try {
Transferable t = support.getTransferable();
nodes = (DefaultMutableTreeNode[]) t.getTransferData(localObjectFlavor);
} catch (UnsupportedFlavorException | IOException ex) {
ex.printStackTrace();
}
JTree.DropLocation dl = (JTree.DropLocation) support.getDropLocation();
int childIndex = dl.getChildIndex();
TreePath dest = dl.getPath();
DefaultMutableTreeNode parent =
(DefaultMutableTreeNode) dest.getLastPathComponent();
JTree tree = (JTree) support.getComponent();
DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
int idx = childIndex < 0 ? parent.getChildCount() : childIndex;
//DefaultTreeModel sm = (DefaultTreeModel) source.getModel();
for (DefaultMutableTreeNode node : nodes) {
//sm.removeNodeFromParent(node);
//model.insertNodeInto(node, parent, idx++);
DefaultMutableTreeNode clone = new DefaultMutableTreeNode(node.getUserObject());
model.insertNodeInto(deepCopyTreeNode(node, clone), parent, idx++);
}
return true;
}
private static DefaultMutableTreeNode deepCopyTreeNode(
DefaultMutableTreeNode src, DefaultMutableTreeNode tgt) {
for (int i = 0; i < src.getChildCount(); i++) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) src.getChildAt(i);
DefaultMutableTreeNode clone = new DefaultMutableTreeNode(node.getUserObject());
tgt.add(clone);
if (!node.isLeaf()) {
deepCopyTreeNode(node, clone);
}
}
return tgt;
}
@Override protected void exportDone(JComponent source, Transferable data, int action) {
if (action == MOVE) {
JTree tree = (JTree) source;
DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
for (TreePath path : tree.getSelectionPaths()) {
model.removeNodeFromParent((MutableTreeNode) path.getLastPathComponent());
}
}
}
}