将多个可拖动图像添加到JFrame

时间:2015-11-25 06:43:45

标签: java swing drag-and-drop draggable

以下代码可以工作并创建可拖动图像(DI)。我已经创建了2个类型DI,test和test1的实例。这两个都有效,但我无法弄清楚如何同时将它们包含在JFrame中。当我尝试添加两者时,我只会添加最后一个。

我在这里做了很多阅读,我知道我需要创建一个Jpanel并将每个图像添加到Jpanel然后添加到JFrame,但在这种情况下,DI是一个JPanel。

我希望有人可以提供帮助,我经历了大量的试验和错误以及大量的互联网搜索,但我没有接近答案。

这是代码 - >

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.*;

public class DI extends JPanel
{
    private BufferedImage image;
    Rectangle r;

    public DI(BufferedImage image) {
        super();
        this.image = image;
        r = new Rectangle(10, 10, image.getWidth(), image.getHeight());
        this.setFocusable(true);
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;

        g2.drawImage(image, r.x, r.y, this);

        //Add a border, red if picture currently has focus
        if (isFocusOwner()) {
            g.setColor(Color.RED);
        } else {
            g.setColor(Color.BLACK);
        }
        g2.draw(r);
    }

    public void setRect(int x, int y) {
        r.x = x;
        r.y = y;
        repaint();
    }

    public BufferedImage getImage() {
        return image;
    }

    public void setImage(BufferedImage image) {
        this.image = image;
        r.setSize(image.getWidth(), image.getHeight());
    }

    public static void main(String[] args) throws IOException {
        File file = new File("happy.png");
        BufferedImage image = ImageIO.read(file);
        DI test = new DI(image);
        DragHandler handler = new DragHandler(test);
        test.addMouseListener(handler);
        test.addMouseMotionListener(handler);

        File file2 = new File("sad.png");
        BufferedImage image2 = ImageIO.read(file2);
        DI test2 = new DI(image2);
        DragHandler handler2 = new DragHandler(test2);
        test2.addMouseListener(handler2);
        test2.addMouseMotionListener(handler2);

        JFrame f = new JFrame("This is a Draggable Icon");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setContentPane(test);
        f.setContentPane(test2);
        f.setSize(400,400);
        f.setLocation(200,200);
        f.setVisible(true);
    }
}

class DragHandler extends MouseInputAdapter {
    DI di;
    Point offset;
    boolean dragging;

    public DragHandler(DI di) {
        this.di = di;
        offset = new Point();
        dragging = false;
    }

    public void mousePressed(MouseEvent e) {
        Point p = e.getPoint();
        if(di.r.contains(p)) {
            offset.x = p.x - di.r.x;
            offset.y = p.y - di.r.y;
            dragging = true;
        }
    }

    public void mouseReleased(MouseEvent e) {
        dragging = false;
    }

    public void mouseDragged(MouseEvent e) {
        if(dragging) {
            int x = e.getX() - offset.x;
            int y = e.getY() - offset.y;
            di.setRect(x, y);
        }
    }
}

2 个答案:

答案 0 :(得分:0)

当您调用setContentPane方法时,整个框架将填充您提供的容器。当您执行两次时,第一个面板(test)将被第二个面板(test2)替换。

f.setContentPane(test);
f.setContentPane(test2);

使用现有内容窗格并指定布局管理器时,可以同时显示两个面板。您可以为面板设置尺寸甚至背景颜色(这些背景颜色可用于查看面板所覆盖的区域):

f.getContentPane().setLayout(new FlowLayout());
f.getContentPane().add(test);
f.getContentPane().add(test2);
test.setPreferredSize(new Dimension(200, 160));
test2.setPreferredSize(new Dimension(200, 160));
test.setBackground(Color.BLUE);
test2.setBackground(Color.RED);

答案 1 :(得分:0)

你的基本概念是错误的。您正在尝试创建一个大型组件,然后在组件边界内的某处绘制图像。问题是你不能将多个组件堆叠在一起。

相反,您只想拥有一个简单的面板,并在此面板中添加组件。然后使用setLocation()方法移动组件。所以不需要定制绘画。所有拖动代码都会改变组件的位置。执行此操作时,面板需要使用“空布局”,因此还负责设置添加到面板的组件的大小。

要显示图像,您应该只使用带有ImageIcon的JLabel并将图像添加到面板。

代码的基本结构是:

JLabel image1 = new JLabel( new ImageIcon(...) );
image1.setSize( image1.getPreferredSize() );
image1.addMouseListener(...);
image1.addMouseMotionListener(...);

JPanel dragPanel = new JPanel();
dragPanel.setLayout(null);
dragPanel.add( image1 );

frame.add(dragPanel, BorderLayout.CENTER);