1

我在单独的线程中在 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;
                }
        }
    }
}
4

1 回答 1

2

它有很多代码要阅读,很难找到错误,所以最好为此发布一个 SSCCE。但是,这里有一个镜头 EG,展示如何通过箭头键移动形状,JApplet重点是鼠标点击.如果不想使用方向键,可以实现鼠标移动。请参阅comments程序以获得更好的理解。

向右移动

在此处输入图像描述

这是代码:

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


public class EgToMove extends JApplet
              implements KeyListener, FocusListener, MouseListener {

static final int SQUARE_SIZE = 40;
int squareTop, squareLeft;

boolean focussed = false; 
DisplayPanel canvas;

public void init() {


  squareTop = getSize().height / 2 - SQUARE_SIZE / 2;
  squareLeft = getSize().width / 2 - SQUARE_SIZE / 2;


  canvas = new DisplayPanel();  
  setContentPane(canvas);     

  canvas.setBackground(Color.BLACK);
  canvas.addFocusListener(this);   // Set up the applet to listen for events
  canvas.addKeyListener(this);   
  canvas.addMouseListener(this);

  } 

 public void keyTyped(KeyEvent e) {
  //do nothing, if u want something
 }

class DisplayPanel extends JPanel {

  public void paintComponent(Graphics g) {

     super.paintComponent(g);  

     if (focussed)
        g.setColor(Color.cyan);
     else
        g.setColor(Color.lightGray);

     int width = getSize().width;  
     int height = getSize().height; 
     g.drawRect(0,0,width-1,height-1);
     g.drawRect(1,1,width-3,height-3);
     g.drawRect(2,2,width-5,height-5);
     g.fillRect(squareLeft, squareTop, SQUARE_SIZE, SQUARE_SIZE);



     if (!focussed) {
        g.setColor(Color.magenta);
        g.drawString("Click to activate",7,20);
     }
  }  
  }

  // --------- Event handling methods

  public void focusGained(FocusEvent evt) {

  focussed = true;
  canvas.repaint();  // redraw with cyan border ///may b u had problem here
  }

  public void focusLost(FocusEvent evt) {

  focussed = false;
  canvas.repaint();  // redraw without cyan border///may b u had problem here
  }



  public void keyPressed(KeyEvent evt) {


  int key = evt.getKeyCode();  // keyboard code for the key that was pressed

  if (key == KeyEvent.VK_LEFT) {
     squareLeft -= 8;
     if (squareLeft < 3)
        squareLeft = 3;
     canvas.repaint();
  }
  else if (key == KeyEvent.VK_RIGHT) {
     squareLeft += 8;
     if (squareLeft > getSize().width - 3 - SQUARE_SIZE)
        squareLeft = getSize().width - 3 - SQUARE_SIZE;
     canvas.repaint();
  }
  else if (key == KeyEvent.VK_UP) {
     squareTop -= 8;
     if (squareTop < 3)
        squareTop = 3;
     canvas.repaint();
  }
  else if (key == KeyEvent.VK_DOWN) {
     squareTop += 8;
     if (squareTop > getSize().height - 3 - SQUARE_SIZE)
        squareTop = getSize().height - 3 - SQUARE_SIZE;
     canvas.repaint();
  }

  } 


 public void keyReleased(KeyEvent evt) {
  // empty method, required by the KeyListener Interface
 }


 public void mousePressed(MouseEvent evt) {
    // Request that the input focus be given to the
    // canvas 
  canvas.requestFocus();
 }


 public void mouseEntered(MouseEvent evt) { }
 public void mouseExited(MouseEvent evt) { }
 public void mouseReleased(MouseEvent evt) { }
 public void mouseClicked(MouseEvent evt) { }


 }
于 2013-01-07T13:41:43.420 回答