2013-08-26 28 views
1

所以我的代碼基本上有一個JPanel與一些文本字段和一個JButton,當用戶單擊按鈕它將轉到按鈕偵聽器,然後從文本字段中的數據並處理它,創建JLabels它增加了另一個看不見的JPanel。然後我使第一個JPanel不可見,並使第二個面板可見,顯示出我生成的「結果」。JButton文本不變

這一切都有效,但問題是,當我的程序處理從文本字段獲得的數據時,我想讓JButton更改它所說的內容,並且我已經嘗試使用event.getSource().setText(),並且我能夠發現它正在更改按鈕文本(通過打印到控制檯),但它不更新具有更改的文本的按鈕。

我嘗試了所有形式的重新驗證並重新繪製,並在此之後進行驗證,但沒有任何工作。有任何想法嗎?謝謝!

//entryPanel is the first panel, and picksPanel is the second panel 
button.addActionListener(new ActionListener() 
          { 

    public void actionPerformed(ActionEvent event) 
    { 
    ((JButton)event.getSource()).setText("Thinking..."); 
    revalidate(); 
    repaint(); 
    try 
    {  
     CriticPick picks = new CriticPick(cityfield.getText(),statefield.getText()); 
     LinkedList<Movie> pickslist = picks.getList(); 
     glayout.setRows(pickslist.size()+2+thepicks.movnum); 
     picksPanel.add(new JLabel("The Results:")); 

     //In my actual code I do a bunch of processing and looping that results in jlabels being added to picksPanel 
     for (int i=0;i<pickslist.size();i++) 
     { 
      JLabel label = new JLabel(pickslist.get(i).title); 
      picksPanel.add(label); 
     } 
    } 
    catch (Exception exc) 
    { 
     System.out.println(exc); 
    } 

    entryPanel.setVisible(false); 
    picksPanel.setVisible(true); 

    }}); 

    guiFrame.add(entryPanel); 
    guiFrame.add(picksPanel); 
    guiFrame.setLayout(new FlowLayout(FlowLayout.LEFT)); 
    guiFrame.setVisible(true); 
} 
+0

我希望你不要執行長時間運行的任務,這會阻止EDT進行必要的更新......爲什麼不使用[CardLayout](http://docs.oracle.com/javase/tutorial/uiswing/layout/card .html),而不是用'revalidate()/ repaint()'拉你的頭髮? –

回答

4

的原因是,完成你的工作之前被處理沒有油漆的事件,所以,當你認爲它會在setText的效果將不會顯示。

repaint()只承諾重繪「儘快」(每個文檔),但由於油漆事件在同一個線程按鈕點擊事件(「事件分派線程」)上進行處理,您的處理有效地使setText呼叫和麪板隱藏/顯示在同一時間發生(可以這麼說),工作完成。

如果您的工作需要大量時間,阻止EDT執行數據處理工作的效果顯而易見 - 由於EDT沒有任何重繪,處理調整大小/鼠標點擊事件的機會,UI將完全無響應等。

重處理應該在後臺線程中完成,最好是藉助SwingWorker。這使EDT免費處理油漆(和其他)事件。

+0

+1有關信息,EDT堵塞:-) –