Very slow JList repopulation

I have a JList component that needs to be emptied and re-populated. The following code (based on my source code) shows a simple window with JList and 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();
                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 click the button, the insertion (10000 elements) is very fast. If I click it again and again, it is still very fast.

If I select the third item and click the button, the result will be the same, the insert is very fast.

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

Why does selecting the first item slow me down?

I tested it with JDK 1.5 and 1.6.

+3
source share
3 answers

, . , , GUI, , .

+2

. , , , SwingUtilities.invokeLater(), .

, AbstractListModel ( ) fireContentsChanged invokeLater.

+1

I'm not sure why selecting an item causes performance issues. But every time you add an item, an event is fired that tells the list to recolor it. Therefore, it is possible that the fact that the item is selected causes additional redrawing.

In any case, the best 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);
        }
    });

Thus, events are not triggered when each new item is added.

+1
source

Source: https://habr.com/ru/post/1761738/


All Articles