Thread.sleep() 在我的 JButton 文本更改之前开始(动画太长)如何防止这种情况发生?

Thread.sleep() starts before my JButton text changes (The animation is too long) How to prevent this?

我这里有一个方法可以循环创建 52 个 JButton。单击按钮时,将显示相应的文本。两个按钮的文本发生变化后,程序会休眠 1 秒(让用户有时间查看它们)。但是,程序在按钮文本更改动画完成之前进入休眠状态,最终没有在第二个按钮上显示文本:

for(int i=0; i<52; i=i+1){
        //button creation
        final int a=i;
        JButton button_one=new JButton();
        buttons[a]=button_one;
        
        mainpanel.add(button_one);
        button_one.addActionListener(new ActionListener(){
            // what happens when the button is clicked
            @Override
            public void actionPerformed(ActionEvent button_picked){
                amount_of_cards_picked=amount_of_cards_picked+1;
                cardamountcheck();
                String selectedcard=null;
                if(twocardspicked==true){
                    userpick2=a;
                    selectedcard=setoutcards[userpick2];
                    System.out.println(selectedcard);
                    // button shows name of card
                    buttons[a].setText(selectedcard);
                    pairdetermination();
                    pairprobability();
                    
                    
                }
                else if(twocardspicked==false){
                    userpick1=a;
                    selectedcard=setoutcards[userpick1];
                    System.out.println(selectedcard);
                    System.out.println(cardspritesmap.get(selectedcard));
                    buttons[a].setText(selectedcard);
                // the two changed text buttons are stored in an array
                }
                if(twocardspicked==true){
                pickedcardbuttons[1]=buttons[a];
                
                }
                else if(twocardspicked==false){
                pickedcardbuttons[0]=buttons[a];
                }
                // sleep method is called
                oncardflipped(selectedcard);
                
            }
        });
    }

这是启动 Thread.sleep() 的方法:

public void oncardflipped(String card){
    if(twocardspicked==true){
        // if there are two cards picked, the sleep is activated
        try{
            Thread.sleep(1000);
        }
        catch(InterruptedException ex){
            Thread.currentThread().interrupt();
        }
        // once the sleep finishes, the text from the JButtons is removed.
        pickedcardbuttons[0].setText("");
        pickedcardbuttons[1].setText("");
        

    }
}

该程序完全符合我的要求,唯一的问题是该程序没有足够的时间来实际显示文本。

事情是这样的: The buttons before they are clicked

After one button is clicked (ok so far)

After two buttons are clicked (this is what you see during the sleep), as you can see, the animation is cut halfway through

然后按钮 return 没有任何文本。

通过在 Swing 事件线程上调用 Thread.sleep,您将使整个 GUI 进入休眠状态,这意味着在休眠时间结束之前它无法执行任何更新 GUI 或与用户交互的关键操作。解决方案是永远不要这样做。如果您需要在 Swing GUI 中设置时间延迟,可以使用专门为此创建的 Swing 工具,即 Swing 计时器:Swing Timer Tutorial

底层机制是给定时器一个以微秒为单位的延迟时间作为它的第一个构造函数参数,并给它一个回调方法作为它的第二个参数ActionListener。将其设置为非重复,并对其调用 .start()。回调应该在延迟时间结束后执行您想要的操作。

例如:

public void oncardflipped(String card) {
    if (twocardspicked) {
        int delay = 1000;
        Timer timer = new Timer(delay, e -> {
            // the actionPerformed call-back code
            pickedcardbuttons[0].setText("");
            pickedcardbuttons[1].setText("");
        });
        timer.setRepeats(false);
        timer.start();
    }
}

注意你应该使用一个java.util.Timer,另一个主要Java定时器class,因为虽然这种方法有效,但它不是 Swing 线程安全的。