JList 重新填充非常慢
我有一个 JList 组件,应该清空并重新填充它。以下代码(基于我的原始代码)显示了一个带有 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 );
}
}
如果我按下按钮,插入(10000 个项目)会非常快。如果我一次又一次地按下它,它仍然很快。
如果我选择第三项并按下按钮,结果是相同的,插入速度非常快。
如果我选择第一项并按下按钮,程序会变得非常慢(实际上我必须停止它)。
为什么选择第一项会减慢执行速度?
我已经使用 JDK 1.5 和 1.6 对其进行了测试。
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();
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我建议编写您自己的模型,它允许一次添加一堆值。我想这不是对模型的添加,而是由此触发的 GUI 东西导致了性能的下降。
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:
This way events are not fired as every new item is added.
您不应该在这样的事件循环中向模型中添加大量元素。更好的方法是让您的操作侦听器生成一个线程来添加项目,并让该线程调用 SwingUtilities.invokeLater() 来向列表触发更改事件。
请注意,根据下面的注释,您需要创建一个 AbstractListModel(或其子类)并使其成为模型,然后在 invokeLater 中对其调用
fireContentsChanged
。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.