【发布时间】:2010-10-26 20:07:24
【问题描述】:
我在网上搜索了可拖动 Swing 组件的示例, 但我发现了不完整或无效的示例。
我需要的是一个可以被鼠标拖动的Swing组件 在另一个组件内。在被拖动时,它应该已经 改变它的位置,而不仅仅是“跳”到它的目的地。
我希望能在没有非标准 API 的情况下工作的示例。
谢谢。
【问题讨论】:
标签: java swing drag-and-drop draggable
我在网上搜索了可拖动 Swing 组件的示例, 但我发现了不完整或无效的示例。
我需要的是一个可以被鼠标拖动的Swing组件 在另一个组件内。在被拖动时,它应该已经 改变它的位置,而不仅仅是“跳”到它的目的地。
我希望能在没有非标准 API 的情况下工作的示例。
谢谢。
【问题讨论】:
标签: java swing drag-and-drop draggable
我提出了一个简单但运行良好的解决方案,我自己发现了;)
我该怎么办?
在 Linux(OpenSuse、KDE3)下使用最新的 JDK 6 进行测试,
但是,嘿,它是 Java Swing,应该在任何地方都能正常工作。
代码如下:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class MyDraggableComponent
extends JComponent {
private volatile int screenX = 0;
private volatile int screenY = 0;
private volatile int myX = 0;
private volatile int myY = 0;
public MyDraggableComponent() {
setBorder(new LineBorder(Color.BLUE, 3));
setBackground(Color.WHITE);
setBounds(0, 0, 100, 100);
setOpaque(false);
addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) { }
@Override
public void mousePressed(MouseEvent e) {
screenX = e.getXOnScreen();
screenY = e.getYOnScreen();
myX = getX();
myY = getY();
}
@Override
public void mouseReleased(MouseEvent e) { }
@Override
public void mouseEntered(MouseEvent e) { }
@Override
public void mouseExited(MouseEvent e) { }
});
addMouseMotionListener(new MouseMotionListener() {
@Override
public void mouseDragged(MouseEvent e) {
int deltaX = e.getXOnScreen() - screenX;
int deltaY = e.getYOnScreen() - screenY;
setLocation(myX + deltaX, myY + deltaY);
}
@Override
public void mouseMoved(MouseEvent e) { }
});
}
}
public class Main {
public static void main(String[] args) {
JFrame f = new JFrame("Swing Hello World");
// by doing this, we prevent Swing from resizing
// our nice component
f.setLayout(null);
MyDraggableComponent mc = new MyDraggableComponent();
f.add(mc);
f.setSize(500, 500);
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setVisible(true);
}
}
【讨论】:
MouseAdapter 和MouseMotionAdapter 代替侦听器,则无需覆盖这些额外的方法。
另外,我发现可以在 JFrame 中创建 JInternalFrame, 但问题是:你总是得到一个烦人的窗口标题栏。
遗憾的是,要禁用标题栏,需要一个肮脏的解决方法:
public class MyDraggableComponent extends JInternalFrame {
public MyDraggableComponent() {
InternalFrameUI thisUI = getUI();
if (thisUI instanceof BasicInternalFrameUI) {
((BasicInternalFrameUI) thisUI).setNorthPane(null);
}
}
我真的很怀念像“someInternalFrame.setWindowTitleBar(false)”这样的方法...
:'(
【讨论】:
setWindowTitleBar()方法!