使用invalidate,验证和重绘时,JPanel不会更新

时间:2014-04-11 20:50:42

标签: java swing jframe jpanel updates

我遇到一个问题,我的JPanels之一根据窗口也不会自动更新。我将尝试简要解释发生的事情。一个字符列表被送入另一个类的arraylist(名为lookReply)(这就像我测试过的那样)然后使用2 iterations将每个字符分配给一个方形表中的坐标来自JLabels。这些JLabels位于lookReplyGUIPanel JPanel中。按下按钮后,新字符将加载到arraylist并重复自身。但是,窗口不显示此更新。我知道他们正在通过一些测试进入JLabels,但只是更新窗口似乎没有用。我正在使用invalidate, validate and repaint,但它仍然不起作用。请参阅下面的代码,了解所需的部件。

第一个方法叫做 - 处理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;
}

如果这有帮助的话,可以更详细地概述所有内容。调用的第一个方法是使用JPanels将所有JFrame添加到gridBagConstraints的正确位置。 JFrame是在方法外创建的,因此所有其他方法都可以看到它。如有需要,所有人都非常感谢并乐意提供更多详细信息!感谢

这是一段简单的可编译代码,它演示了同样的问题。忽略窗口必须调整大小的事实 - 每次按下button按钮会增加1,并且应该更新以显示m的5X5表的lookReply方法。但事实并非如此。

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;
}

}

2 个答案:

答案 0 :(得分:2)

因此,根据您的示例,lookReply会创建一个新的JPanel,但您不会对其执行任何操作。因此组件永远不会添加到屏幕上,因此所有尝试进行刷新都不起作用......

答案 1 :(得分:1)

使用javax.swing.Timer更新您的GUI元素,如herehere所示。