簡體   English   中英

正確更新擺動組件?

[英]Updating swing components correctly?

我是新手,任何幫助表示感謝。

在這段代碼中,我正在翻牌,如果事實證明他們不匹配,我希望他們再次面朝下。

目前正在發生的事情:1。當點擊時,第一張卡翻過來2.當點擊第二張卡時,發生兩件事情中的任何一件(a)如果他們是相同的他們都熬夜這是我想要的(b)如果他們不一樣我從來沒有看到第二張卡,因為它立即重新顯示卡片的背面(以及前一張卡片的背面也按我的方法定義)。

我認為放入睡眠計時器可能會讓第二張卡顯示一段時間后再轉回,但事實並非如此。

我試圖使用contentPane.revalidate(); &contentPane.repaint(); 但它沒有改變任何東西。

我已經輸入了一些控制台輸出:

Console output:
Card: 0 set
Card: 6 set
Sleeping now
Card: 6 unset
Card: 0 unset

上面是單擊兩張不匹配的卡時產生的控制台輸出

@Override
public void actionPerformed(ActionEvent e) 
{
    String buttonPressed = e.getActionCommand();
    int pos = Integer.valueOf(buttonPressed);
    action = Control.model.ReceiveCardsTurned(pos);

    keypadArray[pos].setIcon(myIcons[pos]);     
    System.out.println("Card: "+pos+" set");
    currentTime.setText("" + Control.model.time);
    currentScore.setText("" + Control.model.score);

    //contentPane.revalidate();
    //contentPane.repaint();        

    if(Control.model.twoCardsTurned == false)
    {
        if (action == "unturn") 
        {
            System.out.println("Sleeping now");

            try 
            {
                Thread.sleep(1000);
            }

            catch (InterruptedException e1) 
            {
                e1.printStackTrace();
            }

            keypadArray[pos].setIcon(back);
            keypadArray[Control.model.lastCard].setIcon(back);
            System.out.println("Card: "+pos+" unset");
            System.out.println("Card: "+Control.model.lastCard+" unset");
        }
    }
}

您無法在事件調度線程中休眠,因為您的GUI將凍結。 你必須使用Swing Timer 對於后續任務,您可能需要擔心將來擔心,請查看SwingWorker

您似乎缺少許多重要概念。

  1. Swing是一個事件驅動的環境。 這意味着沒有辦法(或者至少只有極少數)你可以“等待”用戶輸入,通常,你只需要對他們的交互做出反應。
  2. Swing由單個線程驅動,稱為事件調度線程(AKA EDT)。 此線程負責將進入應用程序的事件分派/處理到應用程序的相應部分,以便它們可以采取措施。
  3. 重新繪制管理器將其更新請求發布到EDT。

您采取的任何阻止EDT執行此工作的操作都會使您的應用程序看起來像是掛起的。

你必須永遠不要在EDT上執行任何耗時的操作(例如I / O,循環或Thread#sleep #sleep),這樣做會使你的應用程序“暫停”,這永遠不會很好。

有關更多信息,請閱讀Swing中的Concurrency

現在,您有很多選擇。 您可以使用Thread在后台“等待”並轉回卡,或者您可以使用SwingWorkerjavax.swing.Timer

您遇到的另一個問題是,您不應該從EDT以外的任何Thread更新任何UI組件。 這意味着如果您使用Thread ,您將負責將該線程與EDT重新同步。 雖然不難,但它變得凌亂。

SwingWorkerjavax.swing.Timer具有使這更容易的功能。

Threads和SwingWorker非常適合執行后台處理,並且對於這個問題只是過度殺傷。 相反, javax.swing.Timer完全適合這里。

if (!Control.model.twoCardsTurned)
    {
        if ("unturn".equals(action)) 
        {
            new Timer(1000, new ActionListener() {
                public void actionPerformed(ActionEvent evt) {
                    keypadArray[pos].setIcon(back);
                    keypadArray[Control.model.lastCard].setIcon(back);
                    System.out.println("Card: "+pos+" unset");
                    System.out.println("Card: "+Control.model.lastCard+" unset");
                }
            }).start();
        }
    }

這是一個非常簡單的例子。 您可能希望放置一些控件,以防止用戶在計時器觸發之前單擊任何內容,例如;)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM