我希望能够在一个组件上显示两个 BufferedImage,然后可以使用鼠标拖动在组件周围移动,并且如果拖动到另一个图像的顶部也可以相互重叠。
到目前为止,我已经能够通过简单地将它们放在自己的 JLabels 中然后将它们放在同一个 JPanel 上来将两个 BufferedImages 相互叠加显示,但是我担心我可能没有以正确的方式考虑这一点。
对此的任何帮助、建议或示例将不胜感激。
我希望能够在一个组件上显示两个 BufferedImage,然后可以使用鼠标拖动在组件周围移动,并且如果拖动到另一个图像的顶部也可以相互重叠。
到目前为止,我已经能够通过简单地将它们放在自己的 JLabels 中然后将它们放在同一个 JPanel 上来将两个 BufferedImages 相互叠加显示,但是我担心我可能没有以正确的方式考虑这一点。
对此的任何帮助、建议或示例将不胜感激。
对于这种情况,我通常使用 a JLayeredPane
(它使用无布局,这意味着您必须调用自己setBounds()
或setSize()/setLocation()
),但它可以很好地处理分层并且似乎非常适合自由拖动组件。
这是一个小演示示例(显示 10 个可拖动图像(始终相同))。代码可以改进,但它已经给你一个很好的印象,你可以做什么。
import java.awt.Color;
import java.awt.Component;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.SwingUtilities;
public class TestComponentDragging {
private JLayeredPane contentPane;
protected void initUI() throws MalformedURLException {
JFrame frame = new JFrame(TestComponentDragging.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane = new JLayeredPane();
contentPane.setBackground(Color.WHITE);
contentPane.setOpaque(true);
frame.setContentPane(contentPane);
frame.setSize(Toolkit.getDefaultToolkit().getScreenSize());
frame.setExtendedState(frame.getExtendedState() | JFrame.MAXIMIZED_BOTH);
frame.setVisible(true);
ImageIcon image = new ImageIcon(new URL("http://www.lemondedemario.fr/images/dossier/bowser/bowser.png"));
MouseDragger dragger = new MouseDragger();
Random random = new Random();
for (int i = 0; i < 10; i++) {
JLabel draggableImage = new JLabel(image);
draggableImage.setSize(draggableImage.getPreferredSize());
draggableImage.setLocation(random.nextInt(contentPane.getWidth() - draggableImage.getWidth()),
random.nextInt(contentPane.getHeight() - draggableImage.getHeight()));
dragger.makeDraggable(draggableImage);
contentPane.add(draggableImage);
}
contentPane.repaint();
}
public static class MouseDragger extends MouseAdapter {
private Point lastLocation;
private Component draggedComponent;
@Override
public void mousePressed(MouseEvent e) {
draggedComponent = e.getComponent();
lastLocation = SwingUtilities.convertPoint(draggedComponent, e.getPoint(), draggedComponent.getParent());
}
@Override
public void mouseDragged(MouseEvent e) {
Point location = SwingUtilities.convertPoint(draggedComponent, e.getPoint(), draggedComponent.getParent());
if (draggedComponent.getParent().getBounds().contains(location)) {
Point newLocation = draggedComponent.getLocation();
newLocation.translate(location.x - lastLocation.x, location.y - lastLocation.y);
newLocation.x = Math.max(newLocation.x, 0);
newLocation.x = Math.min(newLocation.x, draggedComponent.getParent().getWidth() - draggedComponent.getWidth());
newLocation.y = Math.max(newLocation.y, 0);
newLocation.y = Math.min(newLocation.y, draggedComponent.getParent().getHeight() - draggedComponent.getHeight());
draggedComponent.setLocation(newLocation);
lastLocation = location;
}
}
@Override
public void mouseReleased(MouseEvent e) {
lastLocation = null;
draggedComponent = null;
}
public void makeDraggable(Component component) {
component.addMouseListener(this);
component.addMouseMotionListener(this);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
new TestComponentDragging().initUI();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
结果(每个“Bowser”都可以用鼠标在框架内自由移动/拖动):
我不会使用JLabel
s 来显示图像并与之交互。你可以做一些事情,但是你突然受到了限制。
我宁愿定义一个JPanel
,覆盖它的方法并使用该对象paintComponent(Graphics g)
绘制图像。Graphics
这样,您可以轻松地应用所有类型的变换,处理鼠标事件以拖动、调整大小、旋转……它们。