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

问题描述

我在这里有一个方法可以在循环中创建 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

然后按钮返回没有任何文本。

解决方法

通过在 Swing 事件线程上调用 Thread.sleep,您将整个 GUI 置于休眠状态,这意味着它无法执行任何更新 GUI 或与用户交互的关键操作,直到休眠时间结束。解决方案是永远不要这样做。如果您需要在 Swing GUI 中设置时间延迟,有一个明确为此创建的 Swing 工具,一个 Swing Timer: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 Timer 类,因为虽然这种工作有效,但它不是 Swing 线程- 安全。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...