2014-04-11 57 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