I have a swing app. with a jframe开发者_如何学运维 with lots of internal frames containing large JTable. Those jtables get updated continuously so there is lots of repainting going on.
in some circumstances I can simply keep the JFrame invisible. (frame.setVisible(false))
I was wondering if anybody knows if I will gain something in terms of performance (something considerable or not)
such as 50% gain or you would only get 2% gain...
and maybe some sort of explaination on what to expect.
thanks
p.s. Another way to rephrase the question is: Are swing components clever enough not to repaint/reflow theirselves if not visible ???
Take a look at the Swing Painting Guidelines which have some useful tips on painting efficiency. For example:
On components with complex output, repaint() should be invoked with arguments which define only the rectangle that needs updating, rather than the no-arg version, which causes the entire component to be repainted.
Components which render complex output should make smart use of the clip rectangle to narrow the drawing operations to those which intersect with the clip area.
It's also quite easy to prove that non-visible components are not painted. The following code hides a panel and prints out if paint is called.
public static void main(String args[]) throws Exception {
JFrame f = new JFrame();
final JPanel p = new JPanel(){
public void paint(Graphics g){
super.paint(g);
System.out.println("IN PAINT");
g.fillRect(10, 10, 20, 20);
}
};
f.setLayout(new BorderLayout());
f.add(p, BorderLayout.CENTER);
JButton b = new JButton("OK");
b.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("PRESSED");
p.setVisible(!p.isVisible());
}
});
f.add(b, BorderLayout.SOUTH);
f.setSize(100,100);
f.setVisible(true);
}
I believe you should temporarily disconnect the TableModel from the JTable while you are not displaying the JTable.
The biggest problem you face is that the JTable reacts to model change events and continuously repaints itself.
It is also possible that the JTable is intelligent enough to not repaint itself while not visible (but has model changes) but I wouldn't put my money on this.
The best way to solve this question is to test both. If you profile both options and see no gain then you try a different route like sola suggested. Just make sure you are not optimizing the wrong part of your application.
I can't give you any numbers on how much performance gain you will see, this depends on too many factors and is best left up to your own profiling. However, if your component is not visible, then the paintComponent() (or repaint()) method won't be called either as far as I know.
If your JTable is in a JScrollPane it seems it will repaint at each line adition (and call to fireTableRowsInserted of your model). Thus because the scrollpane will update it scollbars and then its contained component (JTable). If your table is not in a scrollpane then it will redraw only the shown lines. Therefore if your lines are not shown you will not trigger a repaint... Stupide. I'm looking for a way to avoid this.
精彩评论