如何在 Java 中移动形状?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14195071/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to move Shape in Java?
提问by BILL
I draw shapes on JPanel in a separate thread. I want to move these shapes via calling method move()
but the figure does not change its location.
我在单独的线程中在 JPanel 上绘制形状。我想通过调用方法移动这些形状,move()
但图形不会改变其位置。
This my 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();
}
Sample output on the console
控制台上的示例输出
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]
My JPanel
我的 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();
}
}
Thread for draw shape
绘制形状的螺纹
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;
}
}
}
}
回答by joey rohan
Its a lot of code to read,difficult to find the bug,so its better to post an SSCCE for this.However, here is a shot EG to show how you can move shapes through an arrow key, the JApplet
is focused on a mouse click.If you don't want to use an arrow key, you can implement mouse motion.
See comments
in the program for better understanding.
它有很多代码要阅读,很难找到错误,所以最好为此发布一个 SSCCE。但是,这里有一个镜头 EG 来展示如何通过箭头键移动形状,JApplet
重点是单击鼠标.如果不想使用方向键,可以实现鼠标移动。请参阅comments
程序以更好地理解。
Here is the code:
这是代码:
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) { }
}