2015-07-05 56 views
-1

我正在寫一個簡單的遊戲應用程序,我被困在這個問題上。重繪不工作內部行動執行

  • PWAIT和段Pmain是2個面板
  • 幀是主框架

「創造」是一個按鈕,該段Pmain面板的內部,這是它被點擊時所執行的操作:

下面是代碼:

// ACTION: Create new game 
    create.addActionListener(new ActionListener() { 

     public void actionPerformed(ActionEvent e) { 
      if(UA.alreadyOpen()) { 
       JOptionPane.showMessageDialog(null,"already open game!"); 
       return; 
      } 

      int n = 0; 
      String nome = null; 

      try { 
       n = Integer.parseInt(JOptionPane.showInputDialog(null, "Give the max number of guessers")); 
       nome = JOptionPane.showInputDialog(null, "give the name of the game"); 
       if (n < 1 || nome == null) System.out.println("mainInterface: input problems"); // TODO ... 

       frame.setContentPane(pwait); 
       pwait.setVisible(true); 
       pmain.setVisible(false); 
       frame.pack(); 
      } catch (NumberFormatException e1) { 
       // ??? 
       e1.printStackTrace(); 
      } catch (HeadlessException e1) { 
       // ??? 
       e1.printStackTrace(); 
      } 
       // AND HERE IS THE PROBLEM: 
       if(!UA.apriPartita(n, nome)) 
        System.out.println("ERR creazione partita"); // TODO 
       refreshPartite(); 
     } 
    }); 

UA是這種INTERF背後的邏輯級的王牌班。被調用的方法「UA.apripartita(..)」工作正常,它做了很多事情。 問題是: 我希望界面重新繪製並顯示在等待面板時,單擊「創建」按鈕,但它不直到方法UA.apripartita(..)返回(和,我猜, ActionPerformed函數也返回?)。

實際上,我也嘗試刪除該UA.apripartita(..)方法調用,它只是工作正常。 爲什麼它在裏面的方法不起作用?

在此先感謝!

ps。已經嘗試把一些frame.repaint()或frame.invalidate(),但他們似乎什麼都不做。

pps。歡迎任何其他關於此代碼的良好建議!

+1

'frame.setContentPane(pwait);'使用['CardLayout'](http://download.oracle.com/javase/8/docs/api/java/awt/CardLayout.html)來代替[這個答案](http://stackoverflow.com/a/5786005/418556)。 –

+1

我第二@ AndrewThompson建議您使用CardLayout。另外,如果您的問題沒有得到快速解決,請考慮創建併發布[最小示例程序或mcve](http://stackoverflow.com/help/mcve),以便我們確切地看到問題出在哪裏。我幾乎可以保證你'repaint()'調用不是這裏的問題。 –

回答

0

這是因爲actionPerformed(...)方法在UI主事件線程的控制下運行。所以,當UA.apripartita()正在運行時,您的用戶界面無法刷新。如果此方法設計爲運行很長時間(例如超過半秒,用戶不喜歡動作和其效果之間的長時間延遲),則應考慮使用多線程(如果此方法必須與UI交互,請考慮SwingWorker)。

0

是的,這是設計。您可以在「repaint」文檔中清楚地看到它。 基本上,它將一個「事件」插入到擺動事件隊列中 - 與處理點擊等相同的一個 - 所以Swing將依次處理「執行的動作」,然後「重繪」,然後更多的代碼片段(例如mouseClicked或任何獲取隊列)。 這種方法節省了同步頭痛,特別是考慮到擺動部件不是線程安全的。

你可以查找'paintImmediately',但我真的建議在可能的時候使用'repaint'。

+0

什麼是設計?我不可能根據迄今爲止提供的代碼和信息來猜測他的代碼爲什麼不能工作,我當然也不能責怪Swing事件隊列的結構來解決他當前的故障。 –

+0

對不起,如果它不清楚 - 我指的是他原來的問題,報價:「但它不直到... ActionPerformed函數也返回」。正如Sun最初設計和記錄的那樣,這就是「重新繪製」的確切設計。 –

+0

他的問題是關於他用長時間運行的代碼輸入事件隊列。他需要向我們展示代碼,因爲解決方案當然是使用後臺線程,而不是立即考慮使用paint。 –