简体   繁体   English

JList重新填充非常慢

[英]Very slow JList repopulation

I have a JList component which should be emptied and repopulated. 我有一个JList组件,应该将其清空并重新填充。 The following code (based on my original code) shows a simple window with a JList and a JButton: 以下代码(基于我的原始代码)显示了一个带有JList和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 press the button the insertion (10000 items) is very fast. 如果按下按钮,插入(10000个项目)非常快。 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. 我已经使用JDK 1.5和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. 我猜这不是对模型的补充,而是由此触发的GUI问题会影响性能。

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. 最好是让您的动作侦听器产生一个线程来添加项目,并让该线程调用SwingUtilities.invokeLater()以将change事件激发到列表中。

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. 请注意,按照下面的注释,您需要创建一个AbstractListModel(或它的子类)并使其成为模型,然后在invokeLater中对其调用fireContentsChanged

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM