我在创建JTree时遇到困难,该JTree允许通过将节点拖放到JTree中进行重组。看来应该比较简单。我在网上看过示例,但似乎无法在自己的代码中实现它。
例如,sun提供的这种功能允许在不同组件之间拖动到树中,但不能从树本身内部拖动。
而且我也发现了这一点,它允许您将文本拖到JTree中,但不能拖到树中。
导入java.awt。*;
导入java.awt.datatransfer。*;
导入java.awt.event。*;
导入java.io. *;
导入javax.swing。*;
导入javax.swing.tree。*;
公共类DndTree {
公共静态void main(String args []){
可运行的亚军=新的可运行(){
公共无效run(){
JFrame f = new JFrame(“ DnD JTree”);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel顶部= new JPanel(new BorderLayout());
JLabel dragLabel =新的JLabel(“ Drag me:”);
JTextField文本=新的JTextField();
text.setDragEnabled(true);
top.add(dragLabel,BorderLayout.WEST);
top.add(text,BorderLayout.CENTER);
f.add(top,BorderLayout.NORTH);
最终的JTree树= new JTree();
最终的DefaultTreeModel模型=(DefaultTreeModel)tree.getModel();
tree.setTransferHandler(new TransferHandler(){
public boolean canImport(TransferHandler.TransferSupport support){
如果(!support.isDataFlavorSupported(DataFlavor.stringFlavor)
|| !support.isDrop()){
返回false;
}
JTree.DropLocation dropLocation =
(JTree.DropLocation)support.getDropLocation();
return dropLocation.getPath()!= null;
}
public boolean importData(TransferHandler.TransferSupport支持){
如果(!canImport(support)){
返回false;
}
JTree.DropLocation dropLocation =
(JTree.DropLocation)support.getDropLocation();
TreePath路径= dropLocation.getPath();
可转让可转让= support.getTransferable();
字符串transferData;
尝试{
transferData =(String)transferable.getTransferData(
DataFlavor.stringFlavor);
} catch(IOException e){
返回false;
} catch(UnsupportedFlavorException e){
返回false;
}
int childIndex = dropLocation.getChildIndex();
如果(childIndex == -1){
childIndex = model.getChildCount(path.getLastPathComponent());
}
DefaultMutableTreeNode newNode =
新的DefaultMutableTreeNode(transferData);
DefaultMutableTreeNode parentNode =
(DefaultMutableTreeNode)path.getLastPathComponent();
model.insertNodeInto(newNode,parentNode,childIndex);
TreePath newPath = path.pathByAddingChild(newNode);
tree.makeVisible(newPath);
tree.scrollRectToVisible(tree.getPathBounds(newPath));
返回true;
}
});
JScrollPane窗格=新的JScrollPane(tree);
f.add(窗格,BorderLayout.CENTER);
JPanel bottom =新的JPanel();
JLabel comboLabel =新的JLabel(“ DropMode”);
字符串选项[] = {“ USE_SELECTION”,
“ ON”,“ INSERT”,“ ON_OR_INSERT”
};
最终的DropMode模式[] = {DropMode.USE_SELECTION,
DropMode.ON,DropMode.INSERT,DropMode.ON_OR_INSERT};
最终的JComboBox组合=新的JComboBox(选项);
combo.addActionListener(new ActionListener(){
公共无效actionPerformed(ActionEvent e){
int selectedIndex = combo.getSelectedIndex();
tree.setDropMode(mode [selectedIndex]);
}
});
bottom.add(comboLabel);
bottom.add(combo);
f.add(底部,BorderLayout.SOUTH);
f.setSize(300,400);
f.setVisible(true);
}
};
EventQueue.invokeLater(runner);
}
}
任何参考或建议将是巨大的。谢谢
之前没有做过,但是谷歌快速搜索在这里出现了同样的问题:http : //www.coderanch.com/t/346509/GUI/java/JTree-drag-
drop-inside-one
它可以正常工作您可以查看的实现。
这是Craig Wood发布的相关代码:
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.dnd.*;
import java.util.*;
import java.util.List;
import javax.swing.*;
import javax.swing.tree.*;
public class TreeDragAndDrop {
private JScrollPane getContent() {
JTree tree = new JTree();
tree.setDragEnabled(true);
tree.setDropMode(DropMode.ON_OR_INSERT);
tree.setTransferHandler(new TreeTransferHandler());
tree.getSelectionModel().setSelectionMode(
TreeSelectionModel.CONTIGUOUS_TREE_SELECTION);
expandTree(tree);
return new JScrollPane(tree);
}
private void expandTree(JTree tree) {
DefaultMutableTreeNode root =
(DefaultMutableTreeNode)tree.getModel().getRoot();
Enumeration e = root.breadthFirstEnumeration();
while(e.hasMoreElements()) {
DefaultMutableTreeNode node =
(DefaultMutableTreeNode)e.nextElement();
if(node.isLeaf()) continue;
int row = tree.getRowForPath(new TreePath(node.getPath()));
tree.expandRow(row);
}
}
public static void main(String[] args) {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new TreeDragAndDrop().getContent());
f.setSize(400,400);
f.setLocation(200,200);
f.setVisible(true);
}
}
class TreeTransferHandler extends TransferHandler {
DataFlavor nodesFlavor;
DataFlavor[] flavors = new DataFlavor[1];
DefaultMutableTreeNode[] nodesToRemove;
public TreeTransferHandler() {
try {
String mimeType = DataFlavor.javaJVMLocalObjectMimeType +
";class=\"" +
javax.swing.tree.DefaultMutableTreeNode[].class.getName() +
"\"";
nodesFlavor = new DataFlavor(mimeType);
flavors[0] = nodesFlavor;
} catch(ClassNotFoundException e) {
System.out.println("ClassNotFound: " + e.getMessage());
}
}
public boolean canImport(TransferHandler.TransferSupport support) {
if(!support.isDrop()) {
return false;
}
support.setShowDropLocation(true);
if(!support.isDataFlavorSupported(nodesFlavor)) {
return false;
}
// Do not allow a drop on the drag source selections.
JTree.DropLocation dl =
(JTree.DropLocation)support.getDropLocation();
JTree tree = (JTree)support.getComponent();
int dropRow = tree.getRowForPath(dl.getPath());
int[] selRows = tree.getSelectionRows();
for(int i = 0; i < selRows.length; i++) {
if(selRows[i] == dropRow) {
return false;
}
}
// Do not allow MOVE-action drops if a non-leaf node is
// selected unless all of its children are also selected.
int action = support.getDropAction();
if(action == MOVE) {
return haveCompleteNode(tree);
}
// Do not allow a non-html" target="_blank">leaf node to be copied to a level
// which is less than its source level.
TreePath dest = dl.getPath();
DefaultMutableTreeNode target =
(DefaultMutableTreeNode)dest.getLastPathComponent();
TreePath path = tree.getPathForRow(selRows[0]);
DefaultMutableTreeNode firstNode =
(DefaultMutableTreeNode)path.getLastPathComponent();
if(firstNode.getChildCount() > 0 &&
target.getLevel() < firstNode.getLevel()) {
return false;
}
return true;
}
private boolean haveCompleteNode(JTree tree) {
int[] selRows = tree.getSelectionRows();
TreePath path = tree.getPathForRow(selRows[0]);
DefaultMutableTreeNode first =
(DefaultMutableTreeNode)path.getLastPathComponent();
int childCount = first.getChildCount();
// first has children and no children are selected.
if(childCount > 0 && selRows.length == 1)
return false;
// first may have children.
for(int i = 1; i < selRows.length; i++) {
path = tree.getPathForRow(selRows[i]);
DefaultMutableTreeNode next =
(DefaultMutableTreeNode)path.getLastPathComponent();
if(first.isNodeChild(next)) {
// Found a child of first.
if(childCount > selRows.length-1) {
// Not all children of first are selected.
return false;
}
}
}
return true;
}
protected Transferable createTransferable(JComponent c) {
JTree tree = (JTree)c;
TreePath[] paths = tree.getSelectionPaths();
if(paths != null) {
// Make up a node array of copies for transfer and
// another for/of the nodes that will be removed in
// exportDone after a successful drop.
List<DefaultMutableTreeNode> copies =
new ArrayList<DefaultMutableTreeNode>();
List<DefaultMutableTreeNode> toRemove =
new ArrayList<DefaultMutableTreeNode>();
DefaultMutableTreeNode node =
(DefaultMutableTreeNode)paths[0].getLastPathComponent();
DefaultMutableTreeNode copy = copy(node);
copies.add(copy);
toRemove.add(node);
for(int i = 1; i < paths.length; i++) {
DefaultMutableTreeNode next =
(DefaultMutableTreeNode)paths[i].getLastPathComponent();
// Do not allow higher level nodes to be added to list.
if(next.getLevel() < node.getLevel()) {
break;
} else if(next.getLevel() > node.getLevel()) { // child node
copy.add(copy(next));
// node already contains child
} else { // sibling
copies.add(copy(next));
toRemove.add(next);
}
}
DefaultMutableTreeNode[] nodes =
copies.toArray(new DefaultMutableTreeNode[copies.size()]);
nodesToRemove =
toRemove.toArray(new DefaultMutableTreeNode[toRemove.size()]);
return new NodesTransferable(nodes);
}
return null;
}
/** Defensive copy used in createTransferable. */
private DefaultMutableTreeNode copy(TreeNode node) {
return new DefaultMutableTreeNode(node);
}
protected void exportDone(JComponent source, Transferable data, int action) {
if((action & MOVE) == MOVE) {
JTree tree = (JTree)source;
DefaultTreeModel model = (DefaultTreeModel)tree.getModel();
// Remove nodes saved in nodesToRemove in createTransferable.
for(int i = 0; i < nodesToRemove.length; i++) {
model.removeNodeFromParent(nodesToRemove[i]);
}
}
}
public int getSourceActions(JComponent c) {
return COPY_OR_MOVE;
}
public boolean importData(TransferHandler.TransferSupport support) {
if(!canImport(support)) {
return false;
}
// Extract transfer data.
DefaultMutableTreeNode[] nodes = null;
try {
Transferable t = support.getTransferable();
nodes = (DefaultMutableTreeNode[])t.getTransferData(nodesFlavor);
} catch(UnsupportedFlavorException ufe) {
System.out.println("UnsupportedFlavor: " + ufe.getMessage());
} catch(java.io.IOException ioe) {
System.out.println("I/O error: " + ioe.getMessage());
}
// Get drop location info.
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();
// Configure for drop mode.
int index = childIndex; // DropMode.INSERT
if(childIndex == -1) { // DropMode.ON
index = parent.getChildCount();
}
// Add data to model.
for(int i = 0; i < nodes.length; i++) {
model.insertNodeInto(nodes[i], parent, index++);
}
return true;
}
public String toString() {
return getClass().getName();
}
public class NodesTransferable implements Transferable {
DefaultMutableTreeNode[] nodes;
public NodesTransferable(DefaultMutableTreeNode[] nodes) {
this.nodes = nodes;
}
public Object getTransferData(DataFlavor flavor)
throws UnsupportedFlavorException {
if(!isDataFlavorSupported(flavor))
throw new UnsupportedFlavorException(flavor);
return nodes;
}
public DataFlavor[] getTransferDataFlavors() {
return flavors;
}
public boolean isDataFlavorSupported(DataFlavor flavor) {
return nodesFlavor.equals(flavor);
}
}
}
我想知道如何实现这个功能: 我有一个可编辑的JTree,可以编辑节点的名称。如果我有一个节点是分支节点(其中有一些叶节点),并且该分支节点在编辑时展开,编辑后,该节点将折叠。 编辑完成后,如果分支节点打开,我想让它保持打开状态,如果分支节点折叠,我想让它折叠。 我试图查看TreeWireExpandListener,但它似乎无法解决我的问题,因为在调用这些方法之前,我需要识别实际节点是否处于编辑模
所以,我有一个contenteditable div--我正在制作一个所见即所得编辑器:粗体、斜体、格式化,什么都行,最近的是:插入花哨的图像(在花哨的框中,加上标题)。 用户通过一个对话框添加这些精美的图像:他们填写细节,上传图像,然后和其他编辑器函数一样,我使用按用户的选择将其插入。 所以,现在我的用户可以在一个漂亮的图像中扑通一声--他们需要能够移动它。用户需要能够单击和拖动图像(花式框和所
我在Windows JVM 7_25中测试了此代码,它运行良好。 当我用JVM在Linux测试相同的代码时7_25我得到了这个错误堆栈: (以及更多) < code > int incoming index = integer . parse int(drag board . getstring())的内容;为空 你能告诉我如何解决这个问题或重写代码吗?
问题内容: 如何设置JTable以便能够将行拖到表中的其他索引。例如,如果我有5行,并且想将第4行拖到第2个位置? 问题答案: 查看Java教程的拖放部分。有关如何实现此功能的示例有一些。
问题内容: 我最近开始使用Swift来构建OS X应用程序,我想知道如何实现拖放区域。 更具体地说,我构建了一个处理图像的应用程序,但目前,用户必须手动输入输入图像的路径或使用文件选择器(这很烦人)。我想改进我的应用程序,允许用户通过简单的拖放输入图像(我只需要检索表示图像路径的String即可)。 我怎样才能做到这一点? 问题答案: 这是我在应用程序中使用的示例。 如有必要,将一致性添加到子类声
我试图将JTree节点可视化为JButton,我已经尝试使用JButton对象创建一个默认可变树节点,并将其添加到JTree中: 这些只显示带有黑色参数的错误行。 搜索网络我只发现我需要一个类,但没有一个结果显示如何使用它。 是否有一些教程可以让我找到一些示例来完成任务?