2012-02-07 80 views
5

这里是可运行的一段代码来解释问题 -从JPanel动态删除组件

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

    } 
} 

回答

11

呼叫末,最后f.validate()后:

f.repaint(50L); 

当最后验证不改变布点。

+0

谢谢。有用! (+1)。你能否详细说明一下?为什么最后一次验证不会更改布局,而以前的所有验证都是这样做的? (很明显,我没有做太多的摇摆发展!) – 2012-02-07 00:43:40

+2

最后一次验证*会改变布局 - 你只是看不到它。在调用验证之后,最后一个组件实际上已被删除,但您需要重新绘制组件,以便查看此删除的可视证明。 – 2012-02-07 00:56:50

+0

@HovercraftFullOfEels:谢谢。 – 2012-02-07 01:02:28

5

首先,Swing GUI的对象应当建立并在操作event dispatch thread,但你不能在美国东部时间睡觉。请使用javax.swing.Timer来标记时间,如图所示here

+0

谢谢。这只是一个简单的黑客来演示问题 – 2012-02-07 00:37:43

+1

@amol:兄弟组件受到影响,调整大小,并且必须在验证中重绘。最后一个组件没有触发这种重绘。 (对不起这个评论的错误点) – 2012-02-07 18:35:59