开发者

Very slow JList repopulation

I have a JList component which should be emptied and repopulated. The following code (based on my original code) shows a simple window with a JList and a JButton:

import java.awt.BorderLayout;
import javax.swing.*;

public class JListTest extends javax.swing.JFrame{
    JList jList;
    JButton button;
    DefaultListModel model;

    public JListTest() {
        jList = new JList();
        model = new DefaultListModel();
        jList.setModel( model );
        button = new JButton();

        getContentPane().add(jList, java.awt.BorderLayout.CENTER);

        button.setText("add 10000 items");
        button.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                model.clear();
             开发者_Go百科   for( int i=0; i<10000; ++i ) {
                    model.addElement( "aaaa");
                }
            }
        });
        getContentPane().add(button, BorderLayout.PAGE_START);        
        pack();        
    }

    public static void main(String args[]) {
        JListTest jlt =new JListTest();
        jlt.setSize(300, 300);
        jlt.setVisible( true );
    }
}

If I press the button the insertion (10000 items) is very fast. If I press it again and again it is still very fast.

If I select the third item and press the button, the result is the same, the insertion is very fast.

If I select the first item and press the button, the program becomes very slow (actually I have to stop it).

Why the selection of the first item slows down the execution?

I've tested it using JDK 1.5 and 1.6.


I'd suggest to write your own model which allows to add a bunch of values at once. I guess it's not the addition to the model but the GUI things triggered by this that kill the performance.


I'm not sure why selecting an item causes the performance problem. But everytime you add an item an event is fired which tells the list to repaint itslef. So maybe the fact that an item is selected causes extra repainting.

Anyway a better way to do this would be to create a new model and then just add it to the list:

    button.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            DefaultListModel dlm = new DefaultListModel();
            for( int i=0; i<10000; ++i ) {
                dlm.addElement( "aaaa");
            }
            jList.setModel(dlm);
        }
    });

This way events are not fired as every new item is added.


You should not be adding lots of elements into the model in a the event loop like that. Far better would be to have your action listener spawn off a thread to add the items, and have that thread invoke a SwingUtilities.invokeLater() to fire the change event to the list.

Note that as per the comment below, you need to make an AbstractListModel (or a subclass of it) and make it the model, and call fireContentsChanged on it in the invokeLater.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜