JLabel图形在错误的时间发生变化

时间:2014-04-30 23:16:47

标签: java swing if-statement jframe jlabel

我有一个带有一些图形的老虎机程序,当你拉动杠杆时图形应该会改变,并且由于某种原因它会在首先完成所有其他代码后更改图形。看看:

声明图片:

static ImageIcon jImage = new ImageIcon("C:\\Users\\Harry\\Desktop\\jackpotLeverNotPulled.png");
static ImageIcon jackpot1 = new ImageIcon("C:\\Users\\Harry\\Desktop\\jackpotimage1.png");
static ImageIcon jackpotPulled = new ImageIcon("C:\\Users\\Harry\\Desktop\\jackpotLeverPulled.png");

现在我添加到面板:

static JLabel jlb = new JLabel(jImage);

现在我希望在我的面板上点击某个区域时更改图像,但主要的累积奖金代码首先运行,然后图像发生变化:

public void mousePressed(MouseEvent e) {

        // Returns the X coordinate of where the mouse was click on the panel
        System.out.println("X Coordinate: " + e.getX() );


        //  Returns the Y coordinate of where the mouse was click on the panel
        System.out.println("Y Coordinate: " + e.getY() );    
        System.out.println();

        Scanner ansr = new Scanner(System.in);
        String yesno;

        int random =  (int)(Math.random() * 21 );
        int percentCheck =  (int)(Math.random() * 10 );

        if (e.getX ()>975 && e.getX ()<1159 && e.getY ()>82 && e.getY ()<218){
            jlb.setIcon(jackpotPulled);
            if (cashMoneyz<1) {

                System.out.println("Insufficient funds");
                image1.setIcon(jackpot1);
            } else {

                System.out.println("One dollar has been removed from you slot machine balance");
                cashMoneyz--;
                try {
                    System.out.println("Spinning...");
                    Thread.sleep(1000);
                    System.out.println("Spinning...");
                    Thread.sleep(1000);
                    System.out.println("SPINNINGGGGG...OMG SOOO INTENSE");
                    Thread.sleep(1000);
                } catch (InterruptedException ie)
                {
                }

            }   
            System.out.println("You have this much money (in dollars) left in your slot machine balance: " + cashMoneyz);
            System.out.println("");
            System.out.println("----------------------------------------------------------------------------------");
        }

它执行if语句并尝试捕获并且仅在所有内容的末尾将图形更改为jackpotPulled。 在此先感谢:)

2 个答案:

答案 0 :(得分:1)

您的代码中基本上存在两个问题:

<强> 1)label.setImage()的调用不会立即更新,因为对于AWT和Swing中的所有内容都是如此。每次触发重绘请求时,只需将其添加到重绘队列,该队列将耐心等待在EDT(事件调度线程)中完成的所有其他任务完成。但是,由于您在mousePressed()中执行其他操作,因此它们将首先运行。一个简单的解决方案是在mouseReleased()中进行计算。但是存在更大的问题。

<强> 2) 你目前正在做的是“挨饿”EDT - 一个糟糕的编程习惯 - 因为必须立即执行所有与屏幕相关的调用。睡觉EDT不允许在跑步时进行任何重新涂抹。对于任何长时间运行的任务也是如此。 它的解决方案是在不同的线程中运行非绘制调用:

private volatile boolean isComputing = false;

public void mousePressed(MouseEvent evt) {
    if(isComputing)
        return;
    isComputing = true;

    // .
    // .
    // .
    // change icon here, or any
    // other swing related change.
    // .
    // .

    // run game
    new Thread(){
        public void run(){
           // all non-swing computations

           SwingUtilities.invokeLater(new Runnable() {
               public void run() {
                   // change back icons,
                   // and some other swing updates
               }
           }
           isComputing = false;
        }
    }.start();
}

答案 1 :(得分:0)

事件处理程序(mousePressed)不需要很长时间才能完成,其中应该没有sleep。只要它运行(或睡觉),就不会发生任何其他事情。运行时正在等待处理程序返回并在此之后显示图像。我将大部分代码移动到一个由计时器调用的函数,并使用状态变量来跟踪轮子旋转的强度。