从JPanel动态删除组件

Amo*_*are 5 java concurrency swing miglayout event-dispatch-thread

这是可运行的一段代码解释问题 -

我可以删除s1和s2但不删除s3.
这似乎与MigLayout无关(我碰巧使用它),因为我也看到了与默认布局相同的行为.


import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;

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

import net.miginfocom.swing.MigLayout;

public class MyFrame2 extends JFrame {
    private JPanel main;
    private JPanel s1;
    private JPanel s2;
    private JPanel s3;

    public static void main(String[] args) throws InterruptedException {
        MyFrame2 f = new MyFrame2();
        f.setVisible(true);
        Thread.sleep(2000); //you can see all three panels for two seconds

        f.main.remove(f.s1);
        f.main.validate();
        Thread.sleep(2000);
        f.main.remove(f.s2);
        f.main.validate();
        Thread.sleep(2000);
        f.main.remove(f.s3);
        f.main.validate();
    }

    public MyFrame2() {
        main = new JPanel();

        main.setLayout(new MigLayout());

        main.add(new JLabel("Why does s3 not disappear?"),"w 200, h 100, wrap");

        s1 = new JPanel();
        s1.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.GRAY,1),"s1"));
        main.add(s1,"w 90%, h 300, wrap");

        s2 = new JPanel();
        s2.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.GRAY,1),"s2"));
        main.add(s2,"w 90%, h 300, wrap");

        s3 = new JPanel();
        s3.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.GRAY,1),"s3"));
        main.add(s3,"w 90%, h 300, wrap");

        getContentPane().setLayout(new BorderLayout());
        getContentPane().add(main, BorderLayout.CENTER);

        setSize(new Dimension(800, 600));

    }
}

Run Code Online (Sandbox Code Playgroud)

Joo*_*gen 11

最后打电话到最后f.validate():

f.repaint(50L);
Run Code Online (Sandbox Code Playgroud)

由于最后一次验证不会更改布局.

  • 最后一次验证*确实*改变了布局 - 你只是看不到它.事实上,在调用validate之后,最后一个组件已被删除,但您需要重新绘制组件以查看此删除的可视证据. (2认同)

tra*_*god 5

首先,应该事件派发线程上构造和操作Swing GUI对象,但是您不能在EDT上休眠.而是使用javax.swing.Timer原地踏步,如图所示这里.