Removing a JPanel from a JFrame, so slow

你离开我真会死。 提交于 2019-12-11 11:35:03

问题


This is what the code looks like:

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();
   }
}

So everything works fine, it's just for some reason when it gets to the remove() method, the execution time is so slow, it pauses for at least 5 seconds and then finishes the rest of the lines. I tried commenting it out so I know that's the line causing the problem.

Anyone know what is going on?

edit: so this is basically whats going on.. i honestly dont know what else i need to show you, nothing else in the code has anything to do with the problem im experiencing. if i comment out the remove method, everything works quickly, but when its there it goes very slowly.


回答1:


SSCCE speed test for CardLayout showing 4 images (in a series of 6).

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
import java.text.DecimalFormat;
import javax.swing.*;
import javax.swing.border.EmptyBorder;

public class CardLayoutAnimation {

    public static void main(String[] args) throws Exception {
        URL url1 = new URL("http://i.stack.imgur.com/XUmOD.png");
        final Icon icon1 = new ImageIcon(url1);
        URL url2 = new URL("http://i.stack.imgur.com/zKyiD.png");
        final Icon icon2 = new ImageIcon(url2);
        URL url3 = new URL("http://i.stack.imgur.com/4maMm.png");
        final Icon icon3 = new ImageIcon(url3);
        URL url4 = new URL("http://i.stack.imgur.com/wn9V5.png");
        final Icon icon4 = new ImageIcon(url4);
        Runnable r = new Runnable() {

            @Override
            public void run() {
                final CardLayout cards = new CardLayout();
                final JPanel gui = new JPanel(cards);
                gui.setBorder(new EmptyBorder(100,300,100,300));
                gui.setBackground(Color.WHITE);

                gui.add(new JLabel(icon1), "label " + 1);
                gui.add(new JLabel(icon2), "label " + 2);
                gui.add(new JLabel(icon3), "label " + 3);
                gui.add(new JLabel(icon4), "label " + 4);
                gui.add(new JLabel(icon3), "label " + 5);
                gui.add(new JLabel(icon2), "label " + 6);

                ActionListener animate = new ActionListener(){

                    long lastTime = -1;
                    int frameCount = 0;
                    String timeString;
                    DecimalFormat format = new DecimalFormat("0.00");

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        long time = System.nanoTime();
                        //if (frameCount%100==0) {
                          //  System.out.println("animate! " + (time - lastTime) + "  \t#: " + frameCount);
                        //}
                        if (lastTime<0) {
                            lastTime = time;
                            timeString = "00.00";
                        } else if(time-lastTime>1000) {
                            long duration = time-lastTime;
                            double fps = 1000000000d*(double)frameCount/(double)duration;
                            timeString = format.format(fps);
                            frameCount = 0;
                            lastTime = time;
                            System.out.println(timeString);
                        }
                        frameCount++;
                        cards.next(gui);
                    }
                };
                Timer timer = new Timer(5,animate);
                timer.start();

                JOptionPane.showMessageDialog(null, gui);
                timer.stop();;
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
        SwingUtilities.invokeLater(r);
    }
}

Results in 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
..



回答2:


I have no issue...

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);
            }
        });
    }
}

I think you need to provide an example showing your problem



来源:https://stackoverflow.com/questions/14492848/removing-a-jpanel-from-a-jframe-so-slow

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!