问题
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