1

我正在尝试编写一个拼图应用程序,其中图像被切成小块,打乱,用户必须通过拖放重新排列它们以重新组合原始图像。(像这样:http ://www.jigzone.com/puzzles/74055D549FF0?z=5 )。我必须用 Graphics2d 用 java 写这个。

所以,起初我正在尝试制作某种组件,它可以显示图像的一部分(现在是一个矩形),并且可以用鼠标拖动。

当只有一个这样的组件时,下面的代码运行良好。问题是,当我添加第二个组件时,第一个组件不再可见。

我真的被困在这里了。我有一种感觉,我错过了一些非常基本的东西。或者我走错路了。任何帮助将不胜感激。

编辑:我根据建议更改了一些代码,但是,仍然没有按预期工作。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.MouseInputAdapter;

public class GraphicDragAndDrop extends JPanel {
    Rectangle rect;
    Image img;

    public GraphicDragAndDrop(String imgFile, int x0, int y0){
        rect = new Rectangle(x0, y0, 150, 75);
        img = new ImageIcon(imgFile).getImage();
    }


    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        Graphics2D g2d = (Graphics2D) g;
        g2d.setClip(rect);
        int x = rect.x;
        int y = rect.y;
        g2d.drawImage(img, x, y, this);
    }

    public void setRect(int x, int y) {
        rect.setLocation(x, y);
        repaint();
    }

    public static void main(String[] args) {
        // first piece
        GraphicDragAndDrop piece1 = new GraphicDragAndDrop("a.png", 0, 0);
        piece1.setRect(0, 0);
        new GraphicDragController(piece1);

        // second piece --> only this will be visible
        GraphicDragAndDrop piece2 = new GraphicDragAndDrop("a.png", 200, 200);
        //GraphicDragAndDrop piece2 = new GraphicDragAndDrop("b.png", 200, 200); // does'n work either
        piece2.setRect(150, 150);
        new GraphicDragController(piece2);

        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(piece1);
        f.add(piece2);
        f.setSize(500,500);
        f.setLocation(300,100);
        f.setVisible(true);
    }
}

class GraphicDragController extends MouseInputAdapter {
    GraphicDragAndDrop component;
    Point offset = new Point();
    boolean dragging = false;

    public GraphicDragController(GraphicDragAndDrop gdad) {
        component = gdad;
        component.addMouseListener(this);
        component.addMouseMotionListener(this);
    }

    public void mousePressed(MouseEvent e) {
        Point p = e.getPoint();
        Rectangle r = component.rect;
        if(r.contains(p)) {
            offset.x = p.x - r.x;
            offset.y = p.y - 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;
            component.setRect(x, y);
        }
    }
}
4

1 回答 1

1

您上面的代码仅用于绘制一张图像:

protected void paintComponent(Graphics g) {
    super.paintComponent(g);

    Graphics2D g2d = (Graphics2D) g;
    g2d.setClip(rect);
    int x = rect.x;
    int y = rect.y;

    // here
    g2d.drawImage(new ImageIcon("a.png").getImage(), x, y, this);
}
  • 如果您需要绘制多个图像,请考虑创建一图像并使用 for 循环遍历 paintComponent 中的集合:
  • 另外,永远不要从 paintComponent 中读取图像,因为这种方法应该是精简、平均和快速的,并且应该只关注绘画。此外,您的程序每次必须绘制图像时都无需读取图像,因为这非常低效并且会不必要地减慢程序的速度。而是在构造函数或类似的 init 方法中读取一次图像。

例如,

protected void paintComponent(Graphics g) {
    super.paintComponent(g);

    Graphics2D g2d = (Graphics2D) g;

    for (Image img: myImageCollection) {
       g2d.drawImage(img, 0, 0, this);
    }
}

编辑
你状态:

另外,我的计划是拥有更多 GraphicDragAndDrop 类的对象,每个对象都显示原始图像的不同部分。我的方法错了吗?

你可以使用组件,但我觉得拖动图像很容易。例如,如果您希望程序具有此功能,我认为旋转它们会更容易。如果没有,虽然那么肯定使用组件,但如果你走这条路,我建议使用 JLabel 并简单地设置它的 ImageIcon 而不是拖动 JPanels。

于 2013-05-07T16:31:02.493 回答