java - JPanel 不会重新验证

标签 java swing

我有一个名为 BigPanel 的 JPanel 子类作为 JFrame 的内容 Pane ,BigPanel 对象内有一个嵌套的 JPanel 子类。单击按钮时,嵌套面板应从一个 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. 避免使用 null 布局,像素完美布局是现代 UI 设计中的一种幻觉。影响组件个体尺寸的因素太多,您无法控制其中任何一个。 Swing 的设计目的是与核心的布局管理器一起工作,放弃这些将导致无休止的问题和问题,您将花费越来越多的时间来尝试纠正
  2. 使用 CardLayout 来实现您想要做的事情,这就是它的设计目的。请参阅How to Use CardLayout了解更多详情

核心问题似乎是缺乏对变量引用如何工作的理解......

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

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

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

invalidaterevalidatevalidate 都与布局管理 API 相关。如果您选择忽略它们,它们确实没有什么意义。

关于java - JPanel 不会重新验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29313868/

相关文章:

java - 在 Java Swing 应用程序中导入 Excel (.xls)

java - 需要使用 swing 在 Java 列表之间移动项目的帮助

java - <absolute-ordering> 在 tomcat 7 中不起作用

java - 带有 redisson 的 Tomcat session 管理器

java - 检查 CardLayout 中是否存在带有名称的卡片

java - JPanel 已添加到切换按钮单击上的其他 Jpanel 上

java - 将 SQL 数据库中的信息写入列表

java - Onejar和资源加载

java - 如何使用 JPA 以并发安全的方式获取非重叠日期范围中的间隙?

java - JUnit测试用@SpringApplicationConfiguration自动启动Job