2014-04-11 100 views
0

我有一個問題,即我的JPanels其中一個JPanels沒有根據窗口更新自己的設置。我將嘗試並簡要解釋發生了什麼。將字符列表從另一個類(這是我測試過的這個工程)中輸入到arraylist(名爲lookReply)中,然後使用將每個字符分配給由JLabels製成的方形表中的座標。這些JLabels看起來很快就被GUIPanel JPanel。按下按鈕後,新的字符會被加載到arraylist中,並且它會自行重複。但該窗口不顯示此更新。我知道他們正在通過一些測試進入JLabels,但它只是窗口的更新似乎沒有工作。我正在使用invalidate, validate and repaint,但它仍然不起作用。請參閱下面的代碼,瞭解所需的部件。JPanel使用invalidate時無法更新,驗證並重新繪製

第一種方法稱爲 - 處理arraylist然後調用另一種方法。

private void look() 
{ 
    //clear arrayList then add new lookReply to it 
    lookReply.clear(); 
    while (HumanUser.lookReply==null) 
    { 
    } 
    for(int n = 0; n<HumanUser.lookReply.length(); n++) 
    { 
     lookReply.add(HumanUser.lookReply.charAt(n));     
    } 
    lookReply(); 
//UP TO HERE WORKS FINE 

    screen.invalidate(); 
    screen.validate(); 
    screen.repaint(); 
} 

處理有問題的JPanel的方法。

/** 
* Made up of several smaller JPanels each relate to 1 map position from the lookReply command. 
*/ 
private JPanel lookReply() 
{ 
    JPanel lookReplyGUIPanel = new JPanel(new GridBagLayout()); 
    GridBagConstraints c = new GridBagConstraints(); 
    Border blackline = BorderFactory.createLineBorder(Color.black); 


    //Create a square table dependent on the radius of view. 
    //Then fill each cell with the block retrieved from the lookReply arrayList. 
    for(int y = lookReplyY; y>0; y--) 
    { 
     for(int x = lookReplyX; x>0; x--) 
     {wall... 
      //Then assign it to a variable which is used in the JLabel. 
      String item = null; 
      if (lookReply.size()!=0) 
      { 
       item = lookReply.get(x*y-1) + ""; 
      } 
      //ADD TO CHECK WHAT EACH ITEM IS AND USE THE RELEVENT PICTURE 
      JLabel lookx = new JLabel(item); 
      int width = (2*screenHeight/(5*lookReplyX)-10); 
      lookx.setPreferredSize(new Dimension(width, width)); 
      lookx.setBorder(blackline); 
      c.gridx = x; 
      c.gridy = y; 
      lookReplyGUIPanel.add(lookx, c); 
     } 
    } 
    return lookReplyGUIPanel; 
} 

如果這有幫助,一切的概述的一些更多的細節。所調用的第一種方法使用gridBagConstraints將所有JPanels添加到JFrame的正確位置。 JFrame是在方法之外創建的,所以其他所有方法都可以看到它。所有幫助非常感謝和高興提供更多的細節,如果需要的話!謝謝

這是一個簡單的可編譯的代碼段,它演示了同樣的問題。忽略窗口必須調整大小 - 每個按鈕點擊button m增加1,並且應該更新以顯示m的5X5表的lookReply方法。但事實並非如此。使用javax.swing.Timer

import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 

public class temp 
{ 
JFrame screen = new JFrame("temp"); 
int m = 1; 


public static void main(String[] args) 
{ 
    temp g = new temp(); 
    g.create(); 
} 

private void create() 
{  
    screen.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    screen.setLayout(new GridBagLayout()); 
    GridBagConstraints c = new GridBagConstraints(); 

    c.gridy = 0; 
    screen.add(lookReply(), c); 


    c.gridy = 1; 
    screen.add(button(), c); 

    screen.setVisible(true); 
} 

private JPanel lookReply() 
{ 
    JPanel lookReplyGUIPanel = new JPanel(new GridBagLayout()); 
    GridBagConstraints c = new GridBagConstraints(); 

    for(int y = 5; y>0; y--) 
    { 
     for(int x = 5; x>0; x--) 
     { 
      JLabel lookx = new JLabel((m + "")); 
      c.gridx = x; 
      c.gridy = y; 
      lookReplyGUIPanel.add(lookx, c); 
     } 
    } 

    screen.invalidate(); 
    screen.validate(); 
    screen.repaint(); 
    return lookReplyGUIPanel; 
} 

private JPanel button() 
{ 
    JPanel button = new JPanel(new GridBagLayout()); 
    GridBagConstraints c = new GridBagConstraints(); 

    JButton b = new JButton("button"); 
    b.setBorder(null); 
    c.gridx = 2; 
    c.gridy = 2; 
    button.add(b, c); 
    b.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      m++; 
      lookReply();     
     } 
    }); 

    return button; 
} 

}

+0

沒有完全可運行的示例,無法確切知道發生了什麼,但是, while(HumanUser.lookReply == null)'是非常可怕的,這意味着你在一個單獨的線程中運行這段代碼,這很糟糕,因爲你在同一段代碼中更新UI,或者你正在運行它在美國東部時間,這是不好的,因爲這會導致你的程序看起來像是「掛起」(導致它)。你是否將'lookReplyGUIPanel'添加到任何東西? – MadProgrammer

+0

你的'SSCCE'在哪裏?爲什麼你需要每次都要問你的SSCCE? MadProgrammer和我都要求您在最後一個問題中發佈SSCCE/MCVE:http://stackoverflow.com/q/22849557/131872。爲什麼我們每次都要重複自己? – camickr

+0

@MadProgrammer我已經使用while語句作爲「暫停」,而另一個線程更新用於添加字符到數組列表的變量。是的,我正在使用多個線程。初次運行程序時會添加'lookReplyGUIPanel',但不會在每次更新後添加。我認爲那是在閱讀其他問題後無效,驗證和重繪的結果。 – pokeairguy

回答

2

因此,根據您的示例,lookReply創建了一個新的JPanel,但您對此無能爲力。因此,組件永遠不會添加到屏幕上,所以所有嘗試刷新它都不會產生任何效果...

+0

+1,並在將組件添加到使用'screen.revalidate()'和'screen.repaint()'的屏幕後刷新「屏幕」。 – camickr

+0

謝謝,經過一些調整,工作。 @camickr當我編譯'screen.revalidate()'它說'找不到符號符號:方法revalidate()'。在查看其他帖子後,人們建議使用'invalidate'和'validate'這就是你可以看到我已經使用過的,並且它工作正常 – pokeairguy

+0

@pokeairguy,'在看過其他帖子後,人們建議......這是舊的建議和在使用AWT時使用。使用Swing時,應該使用'revalidate()'。 revalidate()方法已添加到JDK7中的JFrame中,因此您使用的是舊版本。但是,revalidate()適用於所有Swing組件,如JPanel。通常,人們將包含其組件的JPanel添加到框架,而不是直接將框架添加到框架中。這樣你可以輕鬆訪問面板,並可以使用revalidate()。 – camickr