如何在Java中移动Shape?

时间:2013-01-07 11:33:59

标签: java multithreading shape graphics2d

我在一个单独的线程中在JPanel上绘制形状。我想通过调用方法move()移动这些形状,但图中没有改变它的位置。

这是我的CustomShape

public class CustomShape {
    private static final int Y_STEP = 5;
    private static final int X_STEP = 5;
    public String name;
    public Shape shape;
    public Color color;
    private Point newLocation;

    public void move() {
        newLocation.x += X_STEP;
        newLocation.y += Y_STEP;
        //How set new location ?
        //It doesn't work
        this.shape.getBounds().setLocation(newLocation);        
        System.out.println(String.format("New location is [%d,%d]",newLocation.x, newLocation.y));
        System.out.println(String.format("Move to [%d,%d]", this.shape.getBounds().getLocation().x, this.shape.getBounds().getLocation().y));       
    }

    public CustomShape(Shape shape, Color color, String name) {
        this.shape = shape;
        this.color = color;
        this.name = name;
        newLocation = this.shape.getBounds().getLocation();
    }

控制台上的示例输出

New location is [15,15]
Move to [10,10]
New location is [20,20]
Move to [10,10]
New location is [25,25]
Move to [10,10]

我的JPanel

public class ViewPanel extends JPanel {
    private static final long serialVersionUID = 5252479726227082794L;
    private List<CustomShape> shapeList = new ArrayList<CustomShape>();
    private Map<String, Thread> threads = new HashMap<String, Thread>();
    private Timer timer;
    private static final int TIMER_SPEED = 1000;

    public ViewPanel() {
        super();
        this.setDoubleBuffered(true);
        timer = new Timer(TIMER_SPEED, null);

        timer.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                testMove();
            }
        });
    }
    private void testMove() {
        for (CustomShape shape : shapeList) {
            shape.move();
        }
    }

    public void startMove() {
        timer.start();
    }

    public void stopMove() {
        timer.stop();
    }

    public void addShape(CustomShape shape) {
        shapeList.add(shape);
        if (!threads.containsKey(shape.getName())) {
            Thread t = new Thread(new DrawThread(shape, this.getGraphics()),
                    shape.getName());
            threads.put(shape.getName(), t);
            t.start();
        }
        this.repaint();
    }

    public void removeShape(CustomShape shape) {
        if (threads.containsKey(shape.getName())) {
            Thread t = threads.remove(shape.getName());
            t.interrupt();
            shapeList.remove(shape);
        }
        this.repaint();
    }
}

绘制形状的线程

public class DrawThread implements Runnable {
    private static final int THREAD_SLEEP = 100;
    private CustomShape shape;
    private Graphics2D g2d;
    private boolean interrupted = false;

    public DrawThread(CustomShape shape, Graphics g) {
        this.shape = shape;
        this.g2d = (Graphics2D)g;
    }

    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(THREAD_SLEEP);
                g2d.setColor(this.shape.getColor());
                g2d.draw(this.shape.getShape());
            } catch (InterruptedException e) {
                System.out.println(String.format("interrupt %s", Thread
                        .currentThread().getName()));
                interrupted = true;
            } finally {
                if (interrupted)
                    break;
                }
        }
    }
}

1 个答案:

答案 0 :(得分:2)

它需要阅读很多代码,很难找到错误,所以最好为此发布一个SSCCE。但是,这是一个镜头EG,展示如何通过箭头键移动形状,{{1专注于鼠标单击。如果您不想使用箭头键,则可以实现鼠标移动。 有关更好的理解,请参阅该计划中的JApplet

move rect

enter image description here

以下是代码:

comments