JList/DefaultListModel持续Insert和Remove数据产生ArrayIndexOutOfBoundsException的问题
来源:互联网 发布:中国古代最大版图 知乎 编辑:程序博客网 时间:2024/05/10 11:42
转自:http://blog.csdn.net/swingline/article/details/5496008
有这样一个需求:往一个JList中持续Insert数据,当JList中的数据量大于某个值时(比如大于5行),就开始删除数据,使得JList中的数据量一直为固定值(如5行),下面是测试代码:
- import javax.swing.DefaultListModel;
- import javax.swing.JFrame;
- import javax.swing.JList;
- import javax.swing.SwingUtilities;
- public class ListBoundTestMain extends JFrame {
- JList m_list = null;
- DefaultListModel m_model = null;
- public static void main(String[] args) {
- new ListBoundTestMain().initView();
- }
- public void initView() {
- m_model = new DefaultListModel();
- m_list = new JList(m_model);
- getContentPane().add(m_list);
- m_model.insertElementAt("Test1", 0);
- m_model.insertElementAt("Test2", 0);
- m_model.insertElementAt("Test3", 0);
- m_model.insertElementAt("Test4", 0);
- m_model.insertElementAt("Test5", 0);
- setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
- setSize(600, 600);
- new Thread(){
- private int i = 0;
- public void run() {
- while(true) {
- i++;
- m_model.insertElementAt("Loop"+i, 0);
- System.out.println("Loop"+i);
- System.out.println("Before size="+m_model.getSize());
- m_model.remove(m_model.getSize()-1);
- try {
- Thread.sleep(50);
- }catch (Exception e) {
- // TODO: handle exception
- }
- System.out.println("After size="+m_model.getSize());
- }
- }
- }.start();
- setVisible(true);
- }
- }
上面的测试代码会每隔一段时间就报一个异常:
- Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 5 >= 5
- at java.util.Vector.elementAt(Unknown Source)
- at javax.swing.DefaultListModel.getElementAt(Unknown Source)
- at javax.swing.plaf.basic.BasicListUI.updateLayoutState(Unknown Source)
- at javax.swing.plaf.basic.BasicListUI.maybeUpdateLayoutState(Unknown Source)
- at javax.swing.plaf.basic.BasicListUI.paintImpl(Unknown Source)
- at javax.swing.plaf.basic.BasicListUI.paint(Unknown Source)
- at javax.swing.plaf.ComponentUI.update(Unknown Source)
- at javax.swing.JComponent.paintComponent(Unknown Source)
- at javax.swing.JComponent.paint(Unknown Source)
- at javax.swing.JComponent.paintToOffscreen(Unknown Source)
- at javax.swing.BufferStrategyPaintManager.paint(Unknown Source)
- at javax.swing.RepaintManager.paint(Unknown Source)
- at javax.swing.JComponent._paintImmediately(Unknown Source)
- at javax.swing.JComponent.paintImmediately(Unknown Source)
- at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
- at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
- at javax.swing.RepaintManager.seqPaintDirtyRegions(Unknown Source)
- at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown Source)
- at java.awt.event.InvocationEvent.dispatch(Unknown Source)
- at java.awt.EventQueue.dispatchEvent(Unknown Source)
- at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
- at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
- at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
- at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
- at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
- at java.awt.EventDispatchThread.run(Unknown Source)
经过搜索查找,终于找到问题所在:原来并不是DefaultListModel边界的溢出,而是上面插入/删除数据是在一个新的线程里进行,而界面绘制要求在Event Dispatch Thread中进行,所以当应用程序线程需要更新GUI时,需要把代码包在SwingUtilities.invokeLater()中来处理,使得它们重新回到Event Dispatch Thread中。
看看invokeLater的描述:
public static void invokeLater(Runnable doRun)
Causes doRun.run() to be executed asynchronously on the AWT event dispatching thread. This will happen after all pending AWT events have been processed. This method should be used when an application thread needs to update the GUI. In the following example the invokeLater call queues the Runnable object doHelloWorld on the event dispatching thread and then prints a message.
Runnable doHelloWorld = new Runnable() {
public void run() {
System.out.println("Hello World on " + Thread.currentThread());
}
};
SwingUtilities.invokeLater(doHelloWorld);
System.out.println("This might well be displayed before the other message.");
把上面测试例子稍微改一下:
- public class ListBoundTestMain extends JFrame {
- JList m_list = null;
- DefaultListModel m_model = null;
- public static void main(String[] args) {
- new ListBoundTestMain().initView();
- }
- public void initView() {
- m_model = new DefaultListModel();
- m_list = new JList(m_model);
- getContentPane().add(m_list);
- m_model.insertElementAt("Test1", 0);
- m_model.insertElementAt("Test2", 0);
- m_model.insertElementAt("Test3", 0);
- m_model.insertElementAt("Test4", 0);
- m_model.insertElementAt("Test5", 0);
- setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
- setSize(600, 600);
- new Thread(){
- private int i = 0;
- public void run() {
- while(true) {
- try {
- Thread.sleep(500);
- }catch (Exception e) {
- // TODO: handle exception
- }
- SwingUtilities.invokeLater(new Runnable() {
- public void run() {
- i++;
- m_model.insertElementAt("Loop"+i, 0);
- System.out.println("Loop"+i);
- System.out.println("Before size="+m_model.getSize());
- m_model.remove(m_model.getSize()-1);
- System.out.println("After size="+m_model.getSize());
- }
- });
- }
- }
- }.start();
- setVisible(true);
- }
- }
另外,ArrayIndexOutOfBoundsException也可能是由于数组边界溢出,如果是数组边界溢出,提示应该这个样子的:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 3
参考:http://www.mofeel.net/858-comp-lang-java-gui/5523.aspx
- JList/DefaultListModel持续Insert和Remove数据产生ArrayIndexOutOfBoundsException的问题
- JList/DefaultListModel持续Insert和Remove数据产生ArrayIndexOutOfBoundsException的问题
- JList.removeAll()与((DefaultListModel)JList.getModel).removeAllElements()
- swing JList JScrollPane使用时不显示数据的问题 JList设置可多选
- swing JList JScrollPane使用时不显示数据的问题 JList设置可多选
- JList的问题
- [经验小结]jxl写excel时产生“java.lang.ArrayIndexOutOfBoundsException: 5”问题的解决办法
- Swing 有关JList的问题
- jcombox和jlist的区别
- direct insert下不会产生数据的 UNDO
- 随机数据产生的问题
- C++ list中insert、erase和remove函数的用法
- 对比insert和delete操作产生的undo
- Swing中JList的相关问题(2)
- swing 中的JList的增加和删除
- Java JList的使用和事件响应
- Swing组件JList的列表数据修改了,如何通知JList改变显
- 游标类型产生的数据检索问题
- 让马云说说,我们为什么留不住员工
- 无法向会话状态服务器发出会话状态请求 错误的解决方法
- leetcode:Reverse Words in a String
- openerp,odoo ,CRM,FHsaasCRM(丰和CRM)2.0
- 基于特征的推荐算法
- JList/DefaultListModel持续Insert和Remove数据产生ArrayIndexOutOfBoundsException的问题
- 花生壳2.0教程(解决NAT转换的问题)
- DoEvents是干什么用的?
- IntelliJ idea 中Live Template
- 更改Oracle数据文件、控制文件、日志文件位置
- wget命令详解
- vmware文件夹中,各文件的作用
- Extjs Form 设置初始值的时候确保reset正确值
- I2C驱动之结构体