我有两个JTree,其中有一些模拟数据,我要做的是能够获取每个'Job'(15663-1,15663-2等)并为每个创建一个节点,它下面每个部分的节点以及连接到它下面每个部分的组件。在两棵树上,像这样:
+------------------------------+------------------------------+
| PARTS TO BE SHIPPED | SHIPPING BOX |
+------------------------------+------------------------------+
|[JOB] |[JOB] |
|+------[part] |+------[part] |
| +------[component] | +------[component] |
| +------[component] | +------[component] |
|+------[part] |+------[part] |
| +------[component] | +------[component] |
|[JOB] |[JOB] |
|+------[part] |+------[part] |
| +------[component] | +------[component] |
| +------[component] | +------[component] |
|+------[part] |+------[part] |
| +------[component] | +------[component] |
+------------------------------+------------------------------+
因此,假设我在'要装运的零件'中的作业A中有两个螺丝,我在装运箱中没有任何东西,当我将螺丝拖到装运箱时应该为jobA创建一个条目,为A部分创建一个条目并为该组件创建一个条目,然后我希望它提示该组件的数量并从要运送的部件中减去该数量jtree。
因此,如果我有一个名为1553-4的工作,并且它有一个带有四个螺丝的盖子,我将螺丝拖入装运箱,那么它应该在装运箱中输入一个条目,“x螺丝”然后提示用户输入他们刚刚打包的螺丝数,如果他们打包两个螺丝,那么jtree应该改变以反映该工作剩余的2个螺丝。
我已经阅读了一些不同的拖放教程,我有一些例子,但我似乎无法得到它。任何建议或帮助将不胜感激。
我知道我需要实现一个TranferHandler,但我不确定如何,似乎有太多的界面“魔法”正在进行,我真的不理解它。
这就是我所拥有的,我理解制作节点等等,这就是我所拥有的:
package com.protocase.examples;
import java.awt.Dimension;
import java.awt.HeadlessException;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
/**
* @author DavidH
*/
public class JTreeExample {
public static void main(String[] args) {
addTreesAndDisplay();
}
private static void addTreesAndDisplay() throws HeadlessException {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JTree tree = new JTree(getTreeModel());
tree.setDragEnabled(true);
tree.setPreferredSize(new Dimension(200,400));
JScrollPane scroll = new JScrollPane();
scroll.setViewportView(tree);
panel.add(scroll);
JTree secondTree = new JTree(getTreeModel());
secondTree.setPreferredSize(new Dimension(200,400));
secondTree.setDragEnabled(true);
JScrollPane secondScroll = new JScrollPane();
secondScroll.setViewportView(secondTree);
panel.add(secondScroll);
frame.setContentPane(panel);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private static DefaultTreeModel getTreeModel() {
MutableTreeNode root = new DefaultMutableTreeNode("15663-1");
DefaultMutableTreeNode cover = new DefaultMutableTreeNode("Cover");
DefaultMutableTreeNode base = new DefaultMutableTreeNode("Base");
root.insert(cover, 0);
root.insert(base, 0);
cover.insert(new DefaultMutableTreeNode("2x PEMS"), 0);
cover.insert(new DefaultMutableTreeNode("2x SCREWS"), 0);
base.insert(new DefaultMutableTreeNode("4x SCREWS"), 0);
base.insert(new DefaultMutableTreeNode("4x HANDLES"), 0);
DefaultTreeModel model = new DefaultTreeModel(root);
return model;
}
}
我正在寻找一个简洁的拖放示例,拖动到JTree并从JTree中拖出。
答案 0 :(得分:3)
使用我自己的经验(基于我自己的经验(主要是在JDK1.5中进行拖放,因此可能已经存在新功能),简单简单地介绍了Swing中的Drag and Drop。 / p>
拖放操作分为两部分。首先是来自源组件的拖动。 TransferHandler
of the source component创建一个Transferable
,它是将在拖放操作中交换的数据的容器。根据数据的不同,可能会有不同的数据表示形式(称为DataFlavor
)。例如,如果将URL拖放到文本编辑器,则很可能会将URL添加到当前文档中。但是如果你把它放到网络浏览器上,你希望它打开那个URL。因此,第一个只是对纯文本感兴趣,第二个可能对更复杂的对象感兴趣。
第二部分是下降。首先,确定当前位置是否是良好的下降目标。由目标组件的传输处理程序决定是否接受丢弃。通常,这是通过向Transferable
询问特定Transferable
的数据来检查它是否可以处理DataFlavor
中包含的数据来实现的(注意:Flavor
必须是已知是源和目标组件)。当它接受drop并且用户释放鼠标时,它可以继续处理Transferable
中的数据,并希望用它做一些有用的事情。
但与往常一样,Swing tutorials是一个非常好的起点。在你完成它们之后,你可能会提出一个更详细的问题(如果你还有任何问题,因为你的要求相当简单)
答案 1 :(得分:2)
理论上,我认为罗宾很好地回答了你的问题。以下是我所做的实施。总而言之,实现包括前两个标签和底部两个滚动窗格,从左向右拖动。在导入之前还有一些小问题,应该出现一个对话框并询问用户要丢弃多少数量(然后进行算术运算),但我认为这可能是你的功课? ;-)如果您需要进一步的帮助,请告诉我。
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.TransferHandler;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreePath;
public class JTreeExample extends JPanel
{
private JTree tree;
private DefaultTreeModel treeModel;
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
createAndShowGUI();
}
});
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("My Warehouse");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTreeExample newContentPane = new JTreeExample();
newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);
frame.pack();
frame.setVisible(true);
}
public JTreeExample()
{
setLayout(new GridLayout(1, 3));
JLabel lbl_parts = new JLabel("PARTS TO BE SHIPPED");
tree = new JTree(getTreeModel());
tree.setDragEnabled(true);
tree.setPreferredSize(new Dimension(200,400));
JScrollPane scroll = new JScrollPane();
scroll.setViewportView(tree);
JLabel lbl_ship = new JLabel("SHIPPING BOX");
treeModel = getTreeModel();
JTree secondTree = new JTree(treeModel);
secondTree.setPreferredSize(new Dimension(200,400));
secondTree.setTransferHandler(new TransferHandler() {
@Override
public boolean importData(TransferSupport support)
{
if (!canImport(support))
{
return false;
}
JTree.DropLocation dl = (JTree.DropLocation) support.getDropLocation();
TreePath path = dl.getPath();
int childIndex = dl.getChildIndex();
String data;
try
{
data = (String) support.getTransferable().getTransferData(DataFlavor.stringFlavor);
}
catch (UnsupportedFlavorException e)
{
return false;
}
catch (IOException e)
{
return false;
}
if (childIndex == -1)
{
childIndex = tree.getModel().getChildCount(path.getLastPathComponent());
}
DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(data);
DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode) path.getLastPathComponent();
treeModel.insertNodeInto(newNode, parentNode, childIndex);
tree.makeVisible(path.pathByAddingChild(newNode));
tree.scrollRectToVisible(tree.getPathBounds(path.pathByAddingChild(newNode)));
return true;
}
public boolean canImport(TransferSupport support)
{
if (!support.isDrop())
{
return false;
}
support.setShowDropLocation(true);
if (!support.isDataFlavorSupported(DataFlavor.stringFlavor))
{
System.err.println("only string is supported");
return false;
}
JTree.DropLocation dl = (JTree.DropLocation) support.getDropLocation();
TreePath path = dl.getPath();
if (path == null)
{
return false;
}
return true;
}
});
JScrollPane secondScroll = new JScrollPane();
secondScroll.setViewportView(secondTree);
JPanel topPanel = new JPanel(new BorderLayout());
topPanel.add(lbl_parts, BorderLayout.NORTH);
topPanel.add(scroll, BorderLayout.CENTER);
JPanel btmPanel = new JPanel(new BorderLayout());
btmPanel.add(lbl_ship, BorderLayout.NORTH);
btmPanel.add(secondScroll, BorderLayout.CENTER);
add(topPanel);
add(btmPanel);
}
private static DefaultTreeModel getTreeModel()
{
MutableTreeNode root = new DefaultMutableTreeNode("15663-1");
DefaultMutableTreeNode cover = new DefaultMutableTreeNode("Cover");
cover.insert(new DefaultMutableTreeNode("2x PEMS"), 0);
cover.insert(new DefaultMutableTreeNode("2x SCREWS"), 0);
root.insert(cover, 0);
DefaultMutableTreeNode base = new DefaultMutableTreeNode("Base");
base.insert(new DefaultMutableTreeNode("4x SCREWS"), 0);
base.insert(new DefaultMutableTreeNode("4x HANDLES"), 0);
root.insert(base, 0);
DefaultTreeModel model = new DefaultTreeModel(root);
return model;
}
}