Reputation: 1530
I am totally a newbie in Java. And I want to create an animation. But I did not succeed. mouseClicked()
will be executed in the event dispatching thread. Why doesn't it work? Will the event dispatching be occupied by other threads, what other threads?
public class DemoThreadGUI {
public static void main(String [] args) {
DemoThreadGUI app = new DemoThreadGUI();
app.go();
}
public void go() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
generateGUI();
}
});
}
public void generateGUI() {
JFrame frame = new JFrame("Demo");
frame.add(new MyPanel());
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
class MyPanel extends JPanel implements MouseListener {
private int x,y;
private int r;
public MyPanel() {
this.setPreferredSize(new Dimension(100,100));
this.addMouseListener(this);
x = 50;
y = 50;
r = 25;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.fillOval(x-r,y-r,r*2,r*2);
}
public void mouseClicked(MouseEvent event) {
int targetX = event.getX();
int targetY = event.getY();
for(int i=0;i<10;++i) {
x = (x+targetX)/2;
y = (y+targetY)/2;
repaint();
try {
Thread.sleep(100);
} catch (InterruptedException e) { }
}
}
public void mouseEntered(MouseEvent event) {}
public void mouseExited(MouseEvent event) {}
public void mousePressed(MouseEvent event) {}
public void mouseReleased(MouseEvent event) {}
}
}
Upvotes: 1
Views: 209
Reputation: 6077
As Holger said, You can’t expect a thread to paint your UI when you told it to sleep.
Use this instead:
Make targetX
and targetY
global variables, and make a new java.util.Thread
object t
.
private int x,y;
private int r;
Thread t;
int targetX, targetY;
modify your mouseClicked
method as:
public void mouseClicked(final MouseEvent event) {
targetX = event.getX();
targetY = event.getY();
t = new Thread(new Runnable(){public void run(){anim();}});
t.start();
}
Put your code of the mouseClicked
method into the anim
method as:
public void anim()
{
for(int i=0;i<10;++i) {
try{
x = (x+targetX)/2;
y = (y+targetY)/2;
repaint();
Thread.sleep(100);
}catch(Exception e){}
}
t.stop();
}
This works perfectly.
Upvotes: 0
Reputation: 57381
In your mouseClicked() start a new Thread and place the code in the thread
for(int i=0;i<10;++i) {
x = (x+targetX)/2;
y = (y+targetY)/2;
repaint();
try {
Thread.sleep(100);
} catch (InterruptedException e) { }
}
The repaint()
call should be wrapped into SwingUtilities.invokeAndWait()
to pass control to EDT
Upvotes: 1