2013-01-08 40 views
0

我的代碼使用Card Layout來向用戶顯示(預定義)帶有JButtons的JPanel,然後在繼續下一個預定義的JPanel之前顯示一個動態生成的JPanel,其中包含響應的反饋。然而,我無法獲得動態生成的JPanel來顯示,並且像revalidate()和repaint()這樣的命令混淆了一下,我不知道接下來要做什麼。我可能犯了一個相當簡單的錯誤,但嘗試了很多事情的組合,我有點卡住了!動態更新CardLayout不起作用

編輯:對不起,這是我以前發佈的一個相當無用的代碼!我花時間編寫了一個更好的SSCCE,它看起來好像是使用Thread.sleep,但我並不擅長使用Thread.sleep,所以不太確定我需要做些什麼才能使它正常工作。這是我的例子:

public class ExampleClass implements ActionListener{ 

public void doStuff(){ 
    ExampleClass ec = new ExampleClass(); 
    startExperiment(); 

} 

public static void main(String[] args){ 

    ExampleClass e = new ExampleClass(); 
    e.doStuff(); 
} 


JPanel j; 
int count = 0; 
CardLayout cards = new CardLayout(); 
JButton button; 

public void startExperiment(){ 

    // Create frame and JFrames 
    JFrame trial = new JFrame(); 

    trial.setSize(800,600); 

    JPanel j1 = new JPanel(); 
    JPanel j2 = new JPanel(); 
    j1.setSize(800,600); 
    button = new JButton("Click me!"); 
    button.addActionListener(this); 

    j2.setSize(800,600); 
    j1.add(new JLabel("A Panel")); 
    j1.add(button); 
    j2.add(new JLabel("Another Panel")); 
    JPanel[] pans = {j1,j2}; 


    j = new JPanel(); 
    j.setLayout(cards); 

    for(int i=0;i<pans.length;i++){ 
     j.add(pans[i], "Card"+i); 
    } 

    JPanel end = new JPanel(); 
    end.add(new JLabel("The end!")); 
    j.add(end,"End"); 
    trial.add(j); 
    trial.setVisible(true); 
} 



public void nextTrial(){ 

    JPanel ps = new JPanel(); 
    ps.add(new JLabel("This panel won't display!")); 
    j.add(ps,"Pause"+count); 
    cards.show(j,"Pause"+count); 

} 

class aThread extends Thread { 
    public aThread(int duration){ 
     dur=duration; 
    } 
    int dur; 
    public void run() { 
     try { 
      Thread.sleep(dur); 
     } 
     catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

public void pause(int dur){ 
    aThread myThread = new aThread(dur); 
    myThread.start(); 
    try { 
     myThread.join(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 


} 

@Override 
public void actionPerformed(ActionEvent e) { 
    if(e.getSource()==button){ 
     System.out.println("Ow!"); 
     nextTrial(); 
     pause(500); 
     cards.show(j,"Card1"); 
    } 

} 

} 

我意識到,這是一個類似的問題,一個我問大約12個月前在這裏(http://stackoverflow.com/questions/9200072/jpanel-not-updating-cardlayout-正確使用睡眠?rq = 1),但我錯誤地認爲使用Thread.join()可以解決我提到的問題。

+0

爲了更好地幫助,請發佈[SSCCE](http://sscce.org/)。 –

回答

2

添加通話

revalidate(); 
repaint(); 

如果您已經從容器

1

添加/刪除組件/後「周圍有點混亂與像重新驗證命令()和重繪()」,然後,如果這樣的話

pause(500); 

與Thread.sleep()有什麼關係,這很可能是問題所在。

它會阻止繪畫,然後立即顯示下一張牌。

可以肯定,發佈一個樣本可編譯程序,如前所述。

0

感謝大家的回答,爲我指出了正確的方向。我最終發現,這是因爲我對線程和同步性的理解不夠。如果其他人有類似的問題,我通過更改我的代碼的最後一位來解決這個問題:

public void actionPerformed(ActionEvent e) { 
    if(e.getSource()==button){ 

     nextTrial(); 

     SwingUtilities.invokeLater(new Runnable() { 
       public void run() { 
        pause(500); 
        cards.show(j,"Card1"); 

       } 
       }); 
    } 
} 
+0

這是怎麼回事?我同意這個計時器是一個更好,更整潔的解決方案,但是這個仍然沒有問題,我可以看到,除非我錯過了一些東西(這很可能!)? – thisisnic

+0

我沒有仔細看它(哎呀!)。評論已刪除。 –