Java 从JFrame中删除JPanel太慢了

Java 从JFrame中删除JPanel太慢了,java,swing,jframe,jpanel,layout-manager,Java,Swing,Jframe,Jpanel,Layout Manager,这是代码的样子: class Main extends JFrame { public MyPanel panel; public Main() { //all the frame init stuff panel = new MyPanel(this); Panel badPanel = new Panel();//this makes the remove method go veryy slow //add(badPanel,

这是代码的样子:

class Main extends JFrame {
   public MyPanel panel;

   public Main() {
      //all the frame init stuff
      panel = new MyPanel(this);
      Panel badPanel = new Panel();//this makes the remove method go veryy slow
      //add(badPanel, BorderLayout.SOUTH);//
      JPanel goodPanel = new JPanel();
      add(goodPanel, BorderLayout.SOUTH); // this fixes the slowness of the remove method in calculate()
      add(panel, BorderLayout.CENTER);
   }

    public static void main(String[] args) {
       SwingUtilities.invokeLater(new Runnable() {
          public void run() {
             Main main = new Main();
          }
       });
    }
}

class MyPanel extends JPanel {

   Main main;

   public MyPanel(Main main) {
       this.main = main;
       //init everything
   }

   public void calculate() {
       MyPanel newPanel = new MyPanel(main);      
       //do some computation
      main.remove(main.panel);
      main.add(newPanel, BorderLayout.CENTER);
      main.panel = newPanel;
      main.revalidate();
   }
}
所以一切都正常,只是出于某种原因,当它到达
remove()
方法时,执行时间非常慢,它暂停至少5秒钟,然后完成其余的行。我试着注释出来,所以我知道这是导致问题的原因

有人知道发生了什么吗

编辑:所以基本上就是这样的。。老实说,我不知道我还需要向您展示什么,代码中的其他内容与我遇到的问题没有任何关系。如果我注释掉remove方法,一切都会很快工作,但是当它出现时,它会非常缓慢

我没有问题

public class BadPaint10 {

    public static void main(String[] args) {
        new BadPaint10();
    }

    public BadPaint10() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                }

                final JPanel panel = new JPanel();
                panel.setBackground(Color.RED);

                final JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(panel);

                JButton change = new JButton("Switch");
                change.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        long start = System.currentTimeMillis();
                        frame.remove(panel);
                        long end = System.currentTimeMillis();
                        JPanel newPanel = new JPanel();
                        newPanel.setBackground(Color.BLUE);
                        frame.add(newPanel);
                        frame.validate();
                    }
                });
                frame.add(change, BorderLayout.SOUTH);
                frame.setSize(100, 100);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}
我想你需要提供一个例子来说明你的问题

我没有问题

public class BadPaint10 {

    public static void main(String[] args) {
        new BadPaint10();
    }

    public BadPaint10() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                }

                final JPanel panel = new JPanel();
                panel.setBackground(Color.RED);

                final JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(panel);

                JButton change = new JButton("Switch");
                change.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        long start = System.currentTimeMillis();
                        frame.remove(panel);
                        long end = System.currentTimeMillis();
                        JPanel newPanel = new JPanel();
                        newPanel.setBackground(Color.BLUE);
                        frame.add(newPanel);
                        frame.validate();
                    }
                });
                frame.add(change, BorderLayout.SOUTH);
                frame.setSize(100, 100);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}

我认为您需要提供一个示例来说明您的问题

SSCCE速度测试,用于
CardLayout
显示4幅图像(一系列6幅)


CardLayout
的SSCCE速度测试显示4幅图像(一系列6幅)


用一个新的来代替!例如,..@MadProgrammer我不确定你所说的“什么JVM”是什么意思,但我在1.6编译器遵从性级别上使用eclipse,并且运行windows 7 64位1)Add@MadProgrammer来通知他们一条评论。2) 例如,关于。3) 为了更快地获得更好的帮助,请发布一个@user1459976“JVM”Java虚拟机,通常指您使用的Java版本;)@user1459976:那么看起来您需要进行一些调试来隔离问题。在问题被隔离和识别之前,您无法找到解决方案。请改用解决方案!例如,..@MadProgrammer我不确定你所说的“什么JVM”是什么意思,但我在1.6编译器遵从性级别上使用eclipse,并且运行windows 7 64位1)Add@MadProgrammer来通知他们一条评论。2) 例如,关于。3) 为了更快地获得更好的帮助,请发布一个@user1459976“JVM”Java虚拟机,通常指您使用的Java版本;)@user1459976:那么看起来您需要进行一些调试来隔离问题。在问题被隔离和识别之前,你无法找到解决方案。我指的是后者。前者是42(显然)。我在中添加了计时代码-在我的测试中,它花费了0毫秒-假设我们只对方法调用所花费的时间感兴趣,而不是对在屏幕上实际呈现更改所花费的时间感兴趣(这非常接近于0:P)。在我的小示例中,我使用
CardLayout
获得了150 FPS+的速度。我看《乱叫的鱼》时也头疼。我是说后者。前者是42(显然)。我在中添加了计时代码-在我的测试中,它花费了0毫秒-假设我们只对方法调用所花费的时间感兴趣,而不是对在屏幕上实际呈现更改所花费的时间感兴趣(这非常接近于0:P)。在我的小示例中,我使用
CardLayout
获得了150 FPS+的速度。我看《乱叫的鱼》时也头疼。
run:
54.82
123.43
556.57
170.96
170.80
170.18
170.84
171.09
169.93
169.03
173.09
170.05
170.75
171.20
170.35
170.91
170.17
146.58
170.44
170.61
171.01
170.73
170.14
171.13
126.81
208.12
170.40
169.97
170.83
171.55
170.39
..