java 实现从一个 JPanel 到另一个 JPanel 的拖放
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10498927/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Implementing drag-and-drop from one JPanel to another
提问by Pieter
I'm new to drag-and-drop in Swing. I have a JPanel
that draws an image with a caption superimposed on it. I want to implement drag and drop on this JPanel
, but after going through some documentation and tutorials I didn't find any usable pointers on how it's done for this type of component. For starters, it doesn't have a setDragEnabled
function.
我不熟悉 Swing 中的拖放操作。我有一个JPanel
图像,上面叠加了一个标题。我想在 this 上实现拖放JPanel
,但是在浏览了一些文档和教程之后,我没有找到任何关于如何为此类组件完成的可用指针。对于初学者来说,它没有setDragEnabled
功能。
Can I make a JPanel
draggable? I want to use this DnD maneuver to pass a reference to a certain object from one panel to another.
我可以做一个JPanel
可拖动的吗?我想使用此 DnD 操作将某个对象的引用从一个面板传递到另一个面板。
采纳答案by John John Pichler
回答by Robin
You can implement drag-and-drop behavior on any JComponent
. See the setTransferHandler
method.
您可以在任何JComponent
. 见setTransferHandler
方法。
The setDragEnabled
method is typically provided on components where a good default D&D behavior can be implemented in the JDK. In such cases you can just activate the default D&D by calling that method.
该setDragEnabled
方法通常在可以在 JDK 中实现良好的默认 D&D 行为的组件上提供。在这种情况下,您可以通过调用该方法来激活默认的 D&D。
On a JPanel
they (=the Swing developers) could probably not think of any decent default D&D behavior, so you will have to implement your own TransferHandler
. I strongly suggest to read the Drag-and-drop tutorialbefore starting
在JPanel
他们(=的Swing开发者)很可能不会想到的任何像样的默认d&d的行为,所以你必须实现自己的TransferHandler
。我强烈建议在开始之前阅读拖放教程
回答by porfiriopartida
I don't know how viable sounds but when I needed to drag and drop panels I did it this way:
我不知道听起来如何可行,但是当我需要拖放面板时,我是这样做的:
Firstable I implemented action events for dragable panels and containers, it can be both
首先我为可拖动面板和容器实现了动作事件,它可以同时是
I used a static variables for selected parent, selected child and current panel
我为选定的父级、选定的子级和当前面板使用了静态变量
when the mouse is over a panel you set it as the current panel
当鼠标悬停在面板上时,您将其设置为当前面板
when you click , mouse down, whatever, you check if currentpanel is the clicked one and set is as child panel
当你点击,鼠标按下,无论如何,你检查当前面板是否是被点击的面板并设置为子面板
when the mouse is over a panel and child panel is not null, then it seems that you're dragging, current panel will turn into parent panel once you release the mouse
当鼠标悬停在一个面板上并且子面板不为空时,那么您似乎在拖动,一旦您松开鼠标,当前面板将变成父面板
you have to add some validation.
你必须添加一些验证。
If a panel is being dragged you can use your own implementation, it could be follow the mouse coords or just highlight it and highlight the parent, I used this last option to simulate the drag
如果正在拖动面板,您可以使用自己的实现,它可以跟随鼠标坐标或只是突出显示它并突出显示父级,我使用最后一个选项来模拟拖动
ok I wrote this, is so buggy but this is the idea:
好的,我写了这个,太有问题了,但这就是想法:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JTextField;
/**
*
* @author porfiriopartida
*/
public class DraggablePanel extends JDesktopPane implements ContainerPanel{
public ContainerPanel parent;
static DraggablePanel over;
static ContainerPanel overParent;
static DraggablePanel dragging;
static ContainerPanel draggingParent;
public DraggablePanel(){
this(null);
}
public DraggablePanel(ContainerPanel parent){
this.parent = parent;
setBorder(BorderFactory.createLineBorder(Color.black));
setBounds(0,0,100,100);
if(parent != null)
addMouseListener(new MouseAdapter(){
@Override
public void mouseEntered(MouseEvent me) {
DraggablePanel src = (DraggablePanel) me.getSource();
DraggablePanel.over = src;
DraggablePanel.overParent = DraggablePanel.over.parent;
}
@Override
public void mouseExited(MouseEvent me) {
}
@Override
public void mouseReleased(MouseEvent me) {
if(DraggablePanel.over != null && DraggablePanel.dragging != null && DraggablePanel.overParent != null){
Rectangle bounds = DraggablePanel.dragging.getBounds();
bounds.x = me.getX();
bounds.y = me.getY();
//Remove child from parent
DraggablePanel.dragging.parent.removePanel(DraggablePanel.dragging);
if(DraggablePanel.dragging.parent != DraggablePanel.overParent){
//add child to new parent
DraggablePanel.overParent.addPanel(DraggablePanel.dragging, bounds);
}
else{
//same parent selected
DraggablePanel.dragging.parent.addPanel(DraggablePanel.dragging, bounds);
};
DraggablePanel.dragging.parent = DraggablePanel.overParent;
}
//cleaning variables
DraggablePanel.dragging = null;
DraggablePanel.over = null;
DraggablePanel.draggingParent = null;
DraggablePanel.overParent = null;
}
@Override
public void mousePressed(MouseEvent me) {
DraggablePanel.dragging = (DraggablePanel) me.getSource();
DraggablePanel.draggingParent = DraggablePanel.dragging.parent;
}
});
addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent me) {
super.mouseEntered(me);
ContainerPanel src = (ContainerPanel) me.getSource();
DraggablePanel.overParent = src;
if (DraggablePanel.draggingParent == null || DraggablePanel.draggingParent == src) {
setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
} else {
setBorder(BorderFactory.createLineBorder(Color.blue, 2));
}
}
@Override
public void mouseExited(MouseEvent me) {
}
@Override
public void mouseReleased(MouseEvent me) {
}
});
}
@Override
public void addPanel(DraggablePanel panel) {
panel.parent = this;
add(panel);
repaint();
revalidate();
try {
getParent().repaint();
} catch (Exception e) {
}
}
@Override
public void addPanel(DraggablePanel panel, Rectangle bounds) {
setBounds(bounds);
addPanel(panel);
}
@Override
public void removePanel(DraggablePanel panel) {
remove(panel);
}
public static void main(String args[]){
JFrame frame = new JFrame();
frame.setLayout(new GridLayout(1,1));
JTextField tf = new JTextField("textfield");
JButton btn = new JButton("Button");
DraggablePanel desktop = new DraggablePanel();
frame.add(desktop);
DraggablePanel p1 = new DraggablePanel(desktop);
p1.setLayout(new GridLayout(2,1));
p1.add(tf);
p1.setBounds(0,0,100,50);
tf.setBounds(5,5,80,30);
DraggablePanel p2 = new DraggablePanel(desktop);
p2.setLayout(new GridLayout(2,1));
p2.add(btn);
p2.setBounds(50,50,50,30);
btn.setBounds(5,5,30,20);
desktop.add(p1);
desktop.add(p2);
frame.setPreferredSize(new Dimension(600,400));
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}