2

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.

user1459976
  • 207
  • 6
  • 14
  • Use a [`CardLayout`](http://docs.oracle.com/javase/7/docs/api/java/awt/CardLayout.html) instead! E.G. [here](http://stackoverflow.com/questions/5665156/calling-awt-frame-methods-from-subclass/5786005#5786005). – Andrew Thompson Jan 24 '13 at 02:23
  • @MadProgrammer im not sure what you mean by "what JVM", but im using eclipse at a 1.6 compiler compliance level and im running windows 7 64 bit – user1459976 Jan 24 '13 at 02:24
  • 1) Add @MadProgrammer to notify them of a comment. 2) E.G. of [useful properties](http://pscode.org/prop/?prop=java.vendor%2Cjava.version%2Cos.arch%2Cos.name%2Cos.version&format=TSV). 3) For better help sooner, post an [SSCCE](http://sscce.org/). – Andrew Thompson Jan 24 '13 at 02:26
  • @user1459976 "JVM" Java Virtual Machine, generally means what version of Java are you using ;) – MadProgrammer Jan 24 '13 at 02:29
  • @MadProgrammer when i created the project in eclipse i had it set up with JavaSE-1.7, but like i mentioned earlier the java compiler compliance level is set to 1.6. i just tested it and it can compile with 1.7 features – user1459976 Jan 24 '13 at 02:33
  • @user1459976 And your example compiles? I've not stuck into a IDE yet and I can see one error already ;) – MadProgrammer Jan 24 '13 at 02:45
  • @MadProgrammer yes now it compiles – user1459976 Jan 24 '13 at 02:48
  • @user1459976 I tested your code (under Java 7) and it took 0 milliseconds for `remove` to return. However, `//do some computation` scares the willies out me. I'll also gravely concerned over your design, allowing a component the ability to remove components from anther container and replace itself with it stinks of bad design to me - IMHO – MadProgrammer Jan 24 '13 at 02:52
  • @MadProgrammer ya i thought about that, but the alternative isnt that much different, the method would be in the Main class instead. ya i have no idea whats wrong, it takes no time at all in this example. but in my actual program, its just that remove method thats slowing everything down. – user1459976 Jan 24 '13 at 02:54
  • 1
    @user1459976: then it looks like you need to do some debugging to isolate the problem. You can't find a solution until the problem has been isolated and identified. – Hovercraft Full Of Eels Jan 24 '13 at 03:17
  • ok so i found the problem. i had some buttons i was putting into the frame through a Panel. i guess JFrames dont like these very much or something. so i changed it to a JPanel and now things are running more smoothly. thanks for all your help. – user1459976 Jan 24 '13 at 03:30
  • This is sounding stranger all the time. When you add or remove things from a JFrame, you are actually adding and removing them from a *JPanel*, so you are essentially already doing what you said "fixed" the problem. That is most definitely not the cause of your problem, and since it fixed it, there's more going on that you may not be aware of. – Hovercraft Full Of Eels Jan 24 '13 at 03:39

2 Answers2

4

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("https://i.stack.imgur.com/XUmOD.png");
        final Icon icon1 = new ImageIcon(url1);
        URL url2 = new URL("https://i.stack.imgur.com/zKyiD.png");
        final Icon icon2 = new ImageIcon(url2);
        URL url3 = new URL("https://i.stack.imgur.com/4maMm.png");
        final Icon icon3 = new ImageIcon(url3);
        URL url4 = new URL("https://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
..
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
1

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

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • 1
    I meant the latter. The former was 42 (obviously). – Andrew Thompson Jan 24 '13 at 02:41
  • I added timing code in - in my tests, it took 0 milliseconds - assuming we're only interested in the time the method call takes and not the time it takes to have that change actually rendered on the screen (which is pretty close to 0 anyway :P) – MadProgrammer Jan 24 '13 at 02:43
  • I'm getting 150 FPS+ using `CardLayout` in my small example. I'm also getting a head-ache watching the 'gibbering fish'. – Andrew Thompson Jan 24 '13 at 03:23