JPanel不会重新验证

时间:2015-03-28 05:02:48

标签: java swing

我有一个名为BigPanel的JPanel子类作为JFrame的内容窗格,BigPanel对象中有一个嵌套的JPanel子类。在单击按钮时,嵌套面板应从一个JPanel子类更改为另一个。嵌套面板没有重置,正确的子类将打印到控制台,但实际的面板不会更新     包com.grantbroadwater;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

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

public class BigPanel extends JPanel {

private static final long serialVersionUID = 1L;
public static final int DIM = GUIFrame.DIM;
private JPanel pnl1;

public BigPanel() {
    super(null);
    setSize(new Dimension(DIM, DIM));
    setBackground(Color.WHITE);

    JLabel lbl = new JLabel("Big Panel");
    lbl.setBounds(20, 20, 100, 20);
    add(lbl);

    JButton btn = new JButton("Change");
    btn.setBounds(140, 20, 100, 20);
    btn.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            if(pnl1 instanceof SubPanelOne){
                update(new SubPanelTwo());
            }else if(pnl1 instanceof SubPanelTwo){
                update(new SubPanelOne());
            }
        }

    });
    add(btn);

    pnl1 = new SubPanelOne();
    pnl1.setLocation(20, 100);
    add(pnl1);

}

private void update(JPanel pnl){
    SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
            System.out.print("Pnl1 is of type "+pnl1.getClass());

            pnl1 = pnl;
            revalidate();
            repaint();
            pnl1.revalidate();
            pnl1.repaint();

            System.out.println(" changing to " + pnl1.getClass());
        }

    });
}
}

1 个答案:

答案 0 :(得分:2)

  1. 避免使用null布局,像素完美布局是现代ui设计中的错觉。影响组件个体大小的因素太多,您无法控制。 Swing旨在与布局管理器一起工作,放弃这些将导致问题和问题的结束,您将花费越来越多的时间来纠正
  2. 使用CardLayout来实现您的目标,这就是它的设计目标。有关详细信息,请参阅How to Use CardLayout
  3. 核心问题似乎是缺乏对变量引用如何工作的理解......

    pnl1 = pnl;
    revalidate();
    repaint();
    pnl1.revalidate();
    pnl1.repaint();
    

    所有这一切都会将pnl1在内存中指向的内容更改为pnl在内存中指向的内容。它不会影响屏幕上的任何内容。您实际上必须删除pnl1并添加pnl才能进行任何更改。

    随着布局管理器的丢弃,这会增加复杂性,因为每次尝试切换时都需要更新每个组件的大小和位置。

    invalidaterevalidatevalidate都与布局管理API相关。如果你要选择忽略它,它们真的没什么意义。