2

我有两个带有图像的jlabels..我尝试在单击另一个标签时更改标签中的图像..(例如游戏)..我有问题..当我写Thread.sleep时,图像不是更改..查看代码:

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);
}

}

运行它并首先单击第一个标签。单击第二个标签后,第一个标签将在 1 秒内更改图像,但 seconf 标签永远不会!

4

2 回答 2

0

您不应该在这些方法中使用 sleep() ——它们是从处理所有绘图事件的“事件调度”线程调用的。如果您正在睡觉,则线程无法重新绘制您的标签。

与其睡觉,不如更改您的图像,然后创建一个 javax.swing.Timer 任务,该任务将在 1 秒后触发以根据需要再次更改图像。上面的 koljaTM 示例使用了 java.util.Timer,它在“错误”线程中运行。这是他的代码,修改为使用 SWING 计时器:

            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 {
           ...
于 2012-12-11T16:29:08.747 回答
0

图像的更改必须在事件线程(用于处理图形事件的线程)上完成。因此,设置图像将在您的方法返回后将要处理的适当事件排队。不过,那时图像已经变回了,因为事件线程上的 sleep() 不允许处理任何其他事件。正如 dashrb 所说,不要 sleep() 主线程,而是在 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 {
               ...
于 2012-12-11T16:44:04.047 回答