2012-06-27 23 views
0

我有一个AWT容器有一个直接的孩子,并添加一个新的孩子在索引0,使其可见,验证父框架和重绘。 (孩子是扩展Panel的类,但看起来并不相关)。一切都很好,并且容器按预期包含2个直接孩子。Java 7的bug Container.remove()删除所有组件

然后,我隐瞒孩子并从孩子那里调用Container.remove(this),然后验证和重新绘制容器,从而解雇孩子。在1.7之前的所有以前的JRE中,这工作正常,并且原始的孩子留在容器中。然而,在1.7上,remove(this)也移除了原始的孩子,即它清空了容器。拨打Container.remove(0)具有同样的效果。有没有人有任何想法如何解决这个问题?它看起来像一个可怕的JVM错误。

即 - 开始时:Container包含子[A]。 - 添加B后,Container包含子[B,A]。 - 在调用remove(this)或remove(0)之后,Container不包含任何内容:[]。

虽然我可以在remove()之前找回原来的孩子,然后add()它回来,这不可避免地会导致重大重绘和不可接受的性能。

+3

你看过Java错误报告,看看是否有报告?你可以发布一个小测试程序来显示这个问题吗?如果其他人在这里验证,那么也许应该报告它是否尚未完成。 –

+0

尽管可能,但你碰到一个可怕的JVM错误是不太可能的。请发布我们一些代码来验证您的声明。 –

回答

2

我觉得不是真的,我不能来模拟这个问题,

的Win7,JDK7_04在我身边

enter image description here

enter image description here

enter image description here

打印

run: 
Components Count after Adds :2 
Components Count after Adds :3 
Components Count after Adds :4 
Components Count after Adds :5 
Components Count after Adds :6 
Components Count after Adds :7 
Components Count after Removes :6 
Components Count after Removes :5 
Components Count after Removes :4 
Components Count after Removes :3 
Components Count after Removes :2 
Components Count after Removes :1 
BUILD SUCCESSFUL (total time: 2 minutes 14 seconds) 

从代码

import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JButton; 
import javax.swing.JCheckBox; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.border.LineBorder; 

public class AddComponentsAtRuntime { 

    private JFrame f; 
    private Container panel; 
    private JCheckBox checkValidate, checkReValidate, checkRepaint, checkPack; 

    public AddComponentsAtRuntime() { 
     JButton b = new JButton(); 
     b.setBackground(Color.red); 
     b.setBorder(new LineBorder(Color.black, 2)); 
     b.setPreferredSize(new Dimension(600, 10)); 
     panel = new Container(); 
     panel.setLayout(new GridLayout(0, 1)); 
     panel.add(b); 
     f = new JFrame(); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(panel, "Center"); 
     f.add(getCheckBoxPanel(), "South"); 
     f.setLocation(200, 200); 
     f.pack(); 
     f.setVisible(true); 
    } 

    private JPanel getCheckBoxPanel() { 
     checkValidate = new JCheckBox("validate"); 
     checkValidate.setSelected(false); 
     checkReValidate = new JCheckBox("revalidate"); 
     checkReValidate.setSelected(false); 
     checkRepaint = new JCheckBox("repaint"); 
     checkRepaint.setSelected(false); 
     checkPack = new JCheckBox("pack"); 
     checkPack.setSelected(false); 
     JButton addComp = new JButton("Add New One"); 
     addComp.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       JButton b = new JButton(); 
       b.setBackground(Color.red); 
       b.setBorder(new LineBorder(Color.black, 2)); 
       b.setPreferredSize(new Dimension(600, 10)); 
       panel.add(b); 
       makeChange(); 
       System.out.println(" Components Count after Adds :" + panel.getComponentCount()); 
      } 
     }); 
     JButton removeComp = new JButton("Remove One"); 
     removeComp.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       int count = panel.getComponentCount(); 
       if (count > 0) { 
        panel.remove(0); 
       } 
       makeChange(); 
       System.out.println(" Components Count after Removes :" + panel.getComponentCount()); 
      } 
     }); 
     JPanel panel2 = new JPanel(); 
     panel2.add(checkValidate); 
     panel2.add(checkReValidate); 
     panel2.add(checkRepaint); 
     panel2.add(checkPack); 
     panel2.add(addComp); 
     panel2.add(removeComp); 
     return panel2; 
    } 

    private void makeChange() { 
     if (checkValidate.isSelected()) { 
      panel.validate(); 
     } 
     if (checkReValidate.isSelected()) { 
      panel.revalidate(); 
     } 
     if (checkRepaint.isSelected()) { 
      panel.repaint(); 
     } 
     if (checkPack.isSelected()) { 
      f.pack(); 
     } 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       AddComponentsAtRuntime makingChanges = new AddComponentsAtRuntime(); 
      } 
     }); 
    } 
} 
+0

我的代码是纯AWT:它根本不使用Swing。 – user1486577

+0

和最新的区别,任何更改? – mKorbel

0

此异常可能会发生,因为当一个组件被删除时触发事件,并在你仍引用组件此事件处理方法。 例如,当您在代码中删除某处(除了actionPeformed())之外,最后一个组件仍然是事件actionPerformed将被触发/执行。但是actionPerformed()方法经常包含对用户操作作出反应的代码(用户在组件上的某个地方单击)。因此,当最后一个组件被删除时,对actionPerformed()中的组件的任何引用都将导致异常。

解决方法是将代码从actionPerformed()移动到例如mouseClicked()或另一个事件处理程序,具体取决于你想要做什么。