问题
I have two jlabels with an image.. I try to change the image in a label when the other is clicked.. (such as a game).. I have a problem..When i write the Thread.sleep the image is not change..See the code:
public class Game extends JFrame{
private JLabel l1,l2;;
private boolean isClicked = false ,isClicked2 = false;
public Game(){
setLayout(new FlowLayout());
l1 = new JLabel(new ImageIcon(getClass().getResource("image1.png")));
add(l1);
l2 = new JLabel(new ImageIcon(getClass().getResource("image1.png")));
add(l2);
l1.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {}
@Override
public void mousePressed(MouseEvent e) {}
@Override
public void mouseReleased(MouseEvent e) {
if(isClicked2){
l1.setIcon(new ImageIcon(getClass().getResource("image2.png")));
try {
Thread.sleep(1000);
l1.setIcon(new ImageIcon(getClass().getResource("image1.png")));
l2.setIcon(new ImageIcon(getClass().getResource("image1.png")));
isClicked2 = false;
isClicked = false;
}catch(InterruptedException ex){}
}
else{
l1.setIcon(new ImageIcon(getClass().getResource("image2.png")));
isClicked = true;
}
}@Override public void mouseEntered(MouseEvent e){}@Override public void mouseExited(MouseEvent e){}
});
l2.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {}
@Override
public void mousePressed(MouseEvent e) {}
@Override
public void mouseReleased(MouseEvent e) {
if(isClicked){
try {
l2.setIcon(new ImageIcon(getClass().getResource("image2.png")));
Thread.sleep(1000);
l2.setIcon(new ImageIcon(getClass().getResource("image1.png")));
l1.setIcon(new ImageIcon(getClass().getResource("image1.png")));
isClicked = false;
isClicked2 = false;
}catch(InterruptedException ex){}
}
else{
l2.setIcon(new ImageIcon(getClass().getResource("image2.png")));
isClicked2 = true;
}
}@Override public void mouseEntered(MouseEvent e){}@Override public void mouseExited(MouseEvent e){}
});
}
public static void main(String[] args) {
Game g = new Game();
g.setTitle("Fint the same");
g.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
g.pack();
g.setVisible(true);
}
}
Run it and first click the fisrt label.. After click the second label and the first will change image in 1 second but the seconf label NEVER!!
回答1:
The changing of the images has to be done on the event thread (the thread used to process graphics events). Therefore setting the image will queue an appropriate event to be processed after your method returns. At that time though, the image has already changed back, because sleep()ing on the event thread doesn't allow any other events to be processed. As dashrb said, don't sleep() the main thread, but schedule the flip back in a Timer:
if (isClicked) {
l2.setIcon(new ImageIcon(getClass().getResource("image2.png")));
new javax.swing.Timer(1000, new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
l2.setIcon(new ImageIcon(getClass().getResource("image1.png")));
l1.setIcon(new ImageIcon(getClass().getResource("image1.png")));
isClicked = false;
isClicked2 = false;
}
}).start();
} catch (final Exception ex) {
ex.printStackTrace();
}
} else {
...
回答2:
You should not sleep() in these methods--they are invoked from the "event dispatch" thread, which handles all drawing events. If you're sleeping, then the thread can't be repainting your labels.
Rather than sleeping, change your image, then create a javax.swing.Timer task which will fire 1-second-from-now to change the images again as desired. The sample from koljaTM above uses a java.util.Timer, which runs in the "wrong" thread. This is his code, modified to use a SWING timer:
if (isClicked) {
try {
l2.setIcon(new ImageIcon(getClass().getResource("image2.png")));
javax.swing.Timer timer = new javax.swing.Timer(1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
l2.setIcon(new ImageIcon(getClass().getResource("image1.png")));
System.out.println("image2 gone");
l1.setIcon(new ImageIcon(getClass().getResource("image1.png")));
isClicked = false;
isClicked2 = false;
}
});
timer.setRepeats(false);
timer.start();
} catch (final Exception ex) {
ex.printStackTrace();
}
} else {
...
来源:https://stackoverflow.com/questions/13823601/thread-sleep-change-image-java