Reputation: 4869
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.
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
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;
}
}
}
}
Upvotes: 1
Views: 16217
Reputation: 3566
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.
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) { }
}
Upvotes: 2