【问题标题】:Dynamically removing component from JPanel从 JPanel 中动态删除组件
【发布时间】:2012-02-28 11:21:33
【问题描述】:

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

我可以删除 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));

    }
}

【问题讨论】:

    标签: java swing miglayout concurrency event-dispatch-thread


    【解决方案1】:

    在最后一个f.validate()之后调用:

    f.repaint(50L);
    

    由于最后的验证不会改变布局。

    【讨论】:

    • 谢谢。有用! (+1)。你能详细说明一下吗?为什么最后一个验证不改变布局,而所有之前的验证都做了? (显然我没有做太多的摇摆开发!)
    • 最后一次验证确实改变了布局——你只是看不到它。实际上,在调用 validate 之后,最后一个组件已被移除,但您需要重新绘制该组件才能看到此次移除的可视化证明。
    • 感谢气垫船 (+1)。为什么不需要重绘来反映早期移除(s1 和 s2)的视觉变化?
    【解决方案2】:

    首先,Swing GUI 对象应该event dispatch thread 上构造和操作,但您不能在 EDT 上睡觉。而是使用javax.swing.Timer来标记时间,如图here

    【讨论】:

    • @amol:同级组件受到影响,调整大小,必须在验证中重新绘制。最后一个组件没有触发这样的重绘。 (对不起,此评论的错误位置)
    猜你喜欢
    • 1970-01-01
    • 2016-11-15
    • 2012-09-10
    • 1970-01-01
    • 2014-03-07
    • 2012-08-03
    • 2010-10-09
    • 2019-10-14
    相关资源
    最近更新 更多