首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java7bug Container.remove()删除所有组件

Java7bug Container.remove()删除所有组件
EN

Stack Overflow用户
提问于 2012-06-28 02:39:44
回答 2查看 520关注 0票数 0

我有一个AWT容器,有一个直接的子节点,在索引0处添加一个新的子节点,使其可见,验证父框架并重新绘制。(子类是扩展Panel的类,但这似乎并不相关。)一切都很好,并且Container如预期的那样包含两个直接子对象。

然后,我将孩子隐藏起来,从孩子那里调用Container.remove(this),然后验证并重新绘制容器,从而消除了孩子。在1.7之前的所有JRE上,这都可以正常工作,并且原始子文件留在Container中。然而,在1.7版本中,remove(this)也删除了原始子容器,即清空容器。调用Container.remove(0)也有同样的效果。有没有人有办法解决这个问题?它看起来像是一个可怕的JVM错误。

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

虽然我可以在remove()之前检索原始子对象,然后再add()它,但这不可避免地会导致重大的重新绘制和不可接受的性能。

EN

回答 2

Stack Overflow用户

发布于 2012-06-28 02:58:38

我认为不是真的,我不能模拟这个问题,

Win7,JDK7_04站在我这边

打印输出

代码语言:javascript
复制
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)

来自代码

代码语言:javascript
复制
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();
            }
        });
    }
}
票数 2
EN

Stack Overflow用户

发布于 2013-01-12 23:20:43

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

这个问题的解决方案是将代码从actionPerformed()移到mouseClicked()或其他事件处理程序中,这取决于您想要做什么。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11232907

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档