无法从Future<?>获取ArrayIndexOutOfBoundsException如果线程启动Executor,则为SwingWorker [英] Can't get ArrayIndexOutOfBoundsException from Future<?> and SwingWorker if thread starts Executor

查看:1179
本文介绍了无法从Future<?>获取ArrayIndexOutOfBoundsException如果线程启动Executor,则为SwingWorker的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Executor播放SwingWorker的多线程,并且我错误地从Vector中识别出错误的元素,看起来像这个代码很不理解Vector中的元素不存在



我的问题 - >如何/有可能以某种方式捕获此异常



简单输出

 运行:
线程状态名称:StartShedule,SwingWorker状态为STARTED
线程状态名称:StartShedule,SwingWorker状态为DONE
具有名称的线程状态:StartShedule,SwingWorker状态为STARTED
具有名称的线程状态:StartShedule,SwingWorker状态为DONE
具有名称的线程状态:StartShedule,SwingWorker状态为STARTED
线程状态为名称:StartShedule,SwingWorker状态为DONE
BUILD SUCCESSFUL(总时间:11秒)

通过取消注释

  // changeTableValues1(); //取消注释获取ArrayIndexOutOfBoundsException 

一切正确,我得到ArrayIndexOutOfBoundsException,输出是

  run:
线程中的异常AWT-EventQueue-0java.lang.ArrayIndexOutOfBoundsException:数组索引超出范围:2
在java.util.Vector.get(Vector.java:694)
在KondorExport.Util.Help.Table.TableWithExecutor.changeTableValues1(TableWithExecutor.java:70)
在KondorExport.Util .Help.Table.TableWithExecutor.access $ 100(TableWithExecutor.java:18)
在KondorExport.Util.Help.Table.TableWithExecutor $ 2.actionPerformed(TableWithExecutor.java:61)
在javax.swing.Timer .fireActionPerformed(Timer.java:271)
在javax.swing.Timer $ DoPostEvent.run(Timer.java:201)
在java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209 )
在java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
在java.awt.EventD ispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
在java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
在java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
在java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
在java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
在java.awt.EventDispatchThread.run(EventDispatchThread .java:122)
具有名称的线程状态:StartShedule,SwingWorker状态为STARTED
线程状态名称:StartShedule,SwingWorker状态为DONE
BUILD SUCCESSFUL(总时间:10秒)

从代码

  import java.awt.BorderLayout; 
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import javax.swing。*;
import javax.swing.table。*;

public class TableWithExecutor extends JFrame {

private static final long serialVersionUID = 1L;
private String [] columnNames = {Narrative,Description};
private Object [] [] data = {{关于,关于},{添加,添加}};
私人JTable表;
private执行者executor = Executors.newCachedThreadPool();
私人定时器timerRun;
private int delay = 3000;
private Vector< String> fwDeals;
private Vector< String> fwDeals1;

public TableWithExecutor(){
DefaultTableModel model = new DefaultTableModel(data,columnNames);
table = new JTable(model){

private static final long serialVersionUID = 1L;

@Override
public Class getColumnClass(int column){
return getValueAt(0,column).getClass();
}
};
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scrollPane = new JScrollPane(table);
add(scrollPane,BorderLayout.CENTER);
prepareStartShedule();
}

private void prepareStartShedule(){
timerRun = new javax.swing.Timer(delay,startCycle());
timerRun.setRepeats(true);
timerRun.start();
}

private Action startCycle(){
return new AbstractAction(Start Shedule){

private static final long serialVersionUID = 1L;

@Override
public void actionPerformed(ActionEvent e){
executor.execute(new TableWithExecutor.MyTask(StartShedule)); // non on EDT
// changeTableValues1(); // un-comment for get ArrayIndexOutOfBoundsException
}
};
}

private void changeTableValues1(){
fwDeals1 = new Vector< String>();
fwDeals1.add(First); // ElementAt(0)
fwDeals1.add(Second); // ElementAt(1)
checkDealsInDb1(fwDeals1.get(1),fwDeals1.get(2));
}

private void checkDealsInDb1(String Str,String Str1){
table.getModel()。setValueAt(Str,0,1);
table.getModel()。setValueAt(Str1,1,1);
}

private void changeTableValues(){
fwDeals = new Vector< String>();
fwDeals.add(First); // ElementAt(0)
fwDeals.add(Second); // ElementAt(1)
checkDealsInDb(fwDeals.get(1),fwDeals.get(2));
}

private void checkDealsInDb(String Str,String Str1){
table.getModel()。setValueAt(Str,0,1);
table.getModel()。setValueAt(Str1,1,1);
}

public static void main(String [] args){
TableWithExecutor frame = new TableWithExecutor();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setLocation(150,150);
frame.pack();
frame.setVisible(true);
}

私有类MyTask扩展SwingWorker< Void,Integer> {

private String str;
private String namePr;

MyTask(String str){
this.str = str;
addPropertyChangeListener(new SwingWorkerCompletionWaiter(str,namePr));
}

@Override
protected Void doInBackground()throws异常{
if(str.equals(StartShedule)){
changeTableValues() ;
}
返回null;
}

@Override
protected void process(List< Integer> progress){
}

@Override
protected void done(){
if(str.equals(StartShedule)){
}
}
}

私有类SwingWorkerCompletionWaiter实现PropertyChangeListener {

private String str;
private String namePr;

SwingWorkerCompletionWaiter(String str,String namePr){
this.str = str;
this.namePr = namePr;
}

SwingWorkerCompletionWaiter(String namePr){
this.namePr = namePr;
}

@Override
public void propertyChange(PropertyChangeEvent event){
if(state.equals(event.getPropertyName())&& SwingWorker .StateValue.DONE == event.getNewValue()){
System.out.println(Thread Status with Name:+ str +,SwingWorker Status is+ event.getNewValue());
} else if(state.equals(event.getPropertyName())&& SwingWorker.StateValue.PENDING == event.getNewValue()){
System.out.println(Thread状态为Mame:+ str +,SwingWorker状态为+ event.getNewValue());
} else if(state.equals(event.getPropertyName())&& SwingWorker.StateValue.STARTED == event.getNewValue()){
System.out.println(Thread状态名称:+ str +,SwingWorker状态为+ event.getNewValue());
} else {
System.out.println(SomeThing Wrong Happend with Thread Status with Name:+ str);
}
}
}
}

编辑:$(






$ b

  @Override 
protected void done(){
if(str.equals(StartShedule)){
try {
得到();
//errLabel.setText(String.valueOf(get()));
} catch(InterruptedException ie){
ie.printStackTrace();
} catch(ExecutionException ee){
ee.printStackTrace();
} catch(IllegalStateException is){
is.printStackTrace();
}
}
}

但输出仍然只有获取例外,将很难从此BlackBox中获取任何异常

 运行:
获取异常
线程状态名称:StartShedule,SwingWorker状态为STARTED
线程状态名称:StartShedule,SwingWorker状态为DONE
获取异常
具有名称的线程状态:StartShedule,SwingWorker状态为STARTED
具有名称的线程状态:StartShedule,SwingWorker状态为DONE
获取异常
线程状态名称:StartShedule,SwingWorker状态为STARTED
线程状态名称:StartShedule,SwingWorker状态为DONE
获取异常
线程状态名称:StartShedule,SwingWorker状态为STARTED
线程状态名称:StartShedule,SwingWorker状态已完成
BUILD SUCCESSFUL(总时间:13秒)


解决方案

p>我不确定它增加了很多,但是我得到了引起的使用takteek的 answer 如下所示。我从命令行运行它,以确保IDE不是帮助。

 
$ java -cp build / classes TableWithExecutor
StartShedule:PENDING - > STARTED
java.util.concurrent.ExecutionException:java.lang.ArrayIndexOutOfBoundsException:数组索引超出范围:2
在java.util.concurrent.FutureTask $ Sync.innerGet (FutureTask.java:222)
在java.util.concurrent.FutureTask.get(FutureTask.java:83)
在javax.swing.SwingWorker.get(SwingWorker.java:582)
在TableWithExecutor $ MyTask.done(TableWithExecutor.java:103)
在javax.swing.SwingWorker $ 5.run(SwingWorker.java:717)
在javax.swing.SwingWorker $ DoSubmitAccumulativeRunnable.run(SwingWorker .java:814)
at sun.swing.AccumulativeRunnable.run(AccumulativeRunnable.java:95)
在javax.swing.SwingWorker $ DoSubmitAccumulativeRunnable.actionPerformed(SwingWorker.java:824)
at javax.swing.Timer.fireActionPerformed(Timer.java:291)
在javax.swing.Ti mer $ DoPostEvent.run(Timer.java:221)
在java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
在java.awt.EventQueue.dispatchEventImpl(EventQueue.java: 677)
在java.awt.EventQueue.access $ 000(EventQueue.java:85)
在java.awt.EventQueue $ 1.run(EventQueue.java:638)
在java.awt .EventQueue $ 1.run(EventQueue.java:636)
在java.security.AccessController.doPrivileged(本机方法)
在java.security.AccessControlContext $ 1.doIntersectionPrivilege(AccessControlContext.java:87)
在java.awt.EventQueue.dispatchEvent(EventQueue.java:647)
在java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
在java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread .java:211)
在java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
在java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
在java。 awt.EventDispat chThread.pumpEvents(EventDispatchThread.java:188)
在java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
导致:java.lang.ArrayIndexOutOfBoundsException:数组索引超出范围:2
在java.util.Vector.get(Vector.java:694)
在TableWithExecutor.changeTableValues(TableWithExecutor.java:64)
在TableWithExecutor.access $ 100(TableWithExecutor.java:14)
在TableWithExecutor $ MyTask.doInBackground(TableWithExecutor.java:92)
在TableWithExecutor $ MyTask.doInBackground(TableWithExecutor.java:80)
在javax.swing.SwingWorker $ 1.call(SwingWorker.java :277)
在java.util.concurrent.FutureTask $ Sync.innerRun(FutureTask.java:303)
在java.util.concurrent.FutureTask.run(FutureTask.java:138)
在javax.swing.SwingWorker.run(SwingWorker.java:316)
在java.util.concurrent.ThreadPoolExecutor $ Worker.runTask(ThreadPoolExecutor.java:886)
在java.util.concurrent。的ThreadPoolExecutor $ Worker.run(THRE adPoolExecutor.java:908)
在java.lang.Thread.run(Thread.java:680)
StartShedule:STARTED - > DONE

全部代码:

  import java.awt.BorderLayout; 
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.DateFormat;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import javax.swing。*;
import javax.swing.table。*;

/ ** @see https://stackoverflow.com/questions/7054627 * /
public class TableWithExecutor extends JFrame {

private static final int delay = 1000;
private static final DateFormat df = DateFormat.getTimeInstance();
private String [] columnNames = {Product,Availability};
private Object [] [] data = {columnNames,columnNames,columnNames};
私人DefaultTableModel模型;
私人JTable表;
private执行者executor = Executors.newCachedThreadPool();
私人定时器定时器;

public TableWithExecutor(){
model = new DefaultTableModel(data,columnNames);
table = new JTable(model){

@Override
public Class getColumnClass(int column){
return getValueAt(0,column).getClass();
}
};
table.setDefaultRenderer(Date.class,new DefaultTableCellRenderer(){

@Override
protected void setValue(Object value){
setText((value == null )?:df.format(value));
}
});
table.setPreferredScrollableViewportSize(new Dimension(200,100));
JScrollPane scrollPane = new JScrollPane(table);
add(scrollPane,BorderLayout.CENTER);
timer = new Timer(delay,startCycle());
timer.setRepeats(true);
timer.start();
}

private Action startCycle(){
return new AbstractAction(MyTask.STARTSCHEDULE){

@Override
public void actionPerformed ActionEvent e){
executor.execute(new MyTask(MyTask.STARTSCHEDULE));
}
};
}

public static void main(String [] args){
EventQueue.invokeLater(new Runnable(){

@Override $ b $ ();
frame.pack ;
frame.setVisible(true);
}
});
}

私有类MyTask扩展SwingWorker< List< DateRecord>,DateRecord> {

private static final String STARTSCHEDULE =StartSchedule;
private String name = STARTSCHEDULE;

MyTask(String name){
this.name = name;
addPropertyChangeListener(new TaskListener(name));
}

@Override
protected List< DateRecord> doInBackground()throws Exception {
for(int row = 0; row< model.getRowCount(); row ++){
Date date = new Date();
date.setTime(date.getTime()+ row * 1000);
publish(new DateRecord(row,date));
}
返回null;
}

@Override
protected void process(List< DateRecord> chunks){
for(DateRecord dr:chunks){
model.setValueAt dr.date,dr.rowNumber,1);
}
}

@Override
protected void done(){
try {
get();
} catch(Exception e){
e.printStackTrace(System.err);
}
}
}

私有静态类DateRecord {

private int rowNumber;
私人日期;

public DateRecord(int recordNumber,Date date){
this.rowNumber = recordNumber;
this.date = date;
}
}

私有静态类TaskListener实现PropertyChangeListener {

private String name;

TaskListener(String name){
this.name = name;
}

@Override
public void propertyChange(PropertyChangeEvent e){
System.out.println(name +:
+ e.getOldValue ()+ - >+ e.getNewValue());
}
}
}


I play with multitreading for SwingWorker by using Executor, and I'm there by mistake identified wrong elements from the Vector, looks like as this code pretty ignores that element in Vector doesn't exist

my question -> how to/is possible to catch this exception(s) some way

simple output

run:
Thread Status with Name :StartShedule, SwingWorker Status is STARTED
Thread Status with Name :StartShedule, SwingWorker Status is DONE
Thread Status with Name :StartShedule, SwingWorker Status is STARTED
Thread Status with Name :StartShedule, SwingWorker Status is DONE
Thread Status with Name :StartShedule, SwingWorker Status is STARTED
Thread Status with Name :StartShedule, SwingWorker Status is DONE
BUILD SUCCESSFUL (total time: 11 seconds)

by uncomment

//changeTableValues1(); // un-comment for get ArrayIndexOutOfBoundsException

everything is correct, I get ArrayIndexOutOfBoundsException and output is

run:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 2
        at java.util.Vector.get(Vector.java:694)
        at KondorExport.Util.Help.Table.TableWithExecutor.changeTableValues1(TableWithExecutor.java:70)
        at KondorExport.Util.Help.Table.TableWithExecutor.access$100(TableWithExecutor.java:18)
        at KondorExport.Util.Help.Table.TableWithExecutor$2.actionPerformed(TableWithExecutor.java:61)
        at javax.swing.Timer.fireActionPerformed(Timer.java:271)
        at javax.swing.Timer$DoPostEvent.run(Timer.java:201)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Thread Status with Name :StartShedule, SwingWorker Status is STARTED
Thread Status with Name :StartShedule, SwingWorker Status is DONE
BUILD SUCCESSFUL (total time: 10 seconds)

from code

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import javax.swing.*;
import javax.swing.table.*;

public class TableWithExecutor extends JFrame {

    private static final long serialVersionUID = 1L;
    private String[] columnNames = {"Narrative", "Description"};
    private Object[][] data = {{"About", "About"}, {"Add", "Add"}};
    private JTable table;
    private Executor executor = Executors.newCachedThreadPool();
    private Timer timerRun;
    private int delay = 3000;
    private Vector<String> fwDeals;
    private Vector<String> fwDeals1;

    public TableWithExecutor() {
        DefaultTableModel model = new DefaultTableModel(data, columnNames);
        table = new JTable(model) {

            private static final long serialVersionUID = 1L;

            @Override
            public Class getColumnClass(int column) {
                return getValueAt(0, column).getClass();
            }
        };
        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        JScrollPane scrollPane = new JScrollPane(table);
        add(scrollPane, BorderLayout.CENTER);
        prepareStartShedule();
    }

    private void prepareStartShedule() {
        timerRun = new javax.swing.Timer(delay, startCycle());
        timerRun.setRepeats(true);
        timerRun.start();
    }

    private Action startCycle() {
        return new AbstractAction("Start Shedule") {

            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                executor.execute(new TableWithExecutor.MyTask("StartShedule")); //non on EDT
                //changeTableValues1(); // un-comment for get ArrayIndexOutOfBoundsException
            }
        };
    }

    private void changeTableValues1() {
        fwDeals1 = new Vector<String>();
        fwDeals1.add("First"); // ElementAt(0)
        fwDeals1.add("Second");// ElementAt(1)
        checkDealsInDb1(fwDeals1.get(1), fwDeals1.get(2));
    }

    private void checkDealsInDb1(String Str, String Str1) {
        table.getModel().setValueAt(Str, 0, 1);
        table.getModel().setValueAt(Str1, 1, 1);
    }

    private void changeTableValues() {
        fwDeals = new Vector<String>();
        fwDeals.add("First"); // ElementAt(0)
        fwDeals.add("Second");// ElementAt(1)
        checkDealsInDb(fwDeals.get(1), fwDeals.get(2));
    }

    private void checkDealsInDb(String Str, String Str1) {
        table.getModel().setValueAt(Str, 0, 1);
        table.getModel().setValueAt(Str1, 1, 1);
    }

    public static void main(String[] args) {
        TableWithExecutor frame = new TableWithExecutor();
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.setLocation(150, 150);
        frame.pack();
        frame.setVisible(true);
    }

    private class MyTask extends SwingWorker<Void, Integer> {

        private String str;
        private String namePr;

        MyTask(String str) {
            this.str = str;
            addPropertyChangeListener(new SwingWorkerCompletionWaiter(str, namePr));
        }

        @Override
        protected Void doInBackground() throws Exception {
            if (str.equals("StartShedule")) {
                changeTableValues();
            }
            return null;
        }

        @Override
        protected void process(List<Integer> progress) {
        }

        @Override
        protected void done() {
            if (str.equals("StartShedule")) {
            }
        }
    }

    private class SwingWorkerCompletionWaiter implements PropertyChangeListener {

        private String str;
        private String namePr;

        SwingWorkerCompletionWaiter(String str, String namePr) {
            this.str = str;
            this.namePr = namePr;
        }

        SwingWorkerCompletionWaiter(String namePr) {
            this.namePr = namePr;
        }

        @Override
        public void propertyChange(PropertyChangeEvent event) {
            if ("state".equals(event.getPropertyName()) && SwingWorker.StateValue.DONE == event.getNewValue()) {
                System.out.println("Thread Status with Name :" + str + ", SwingWorker Status is " + event.getNewValue());
            } else if ("state".equals(event.getPropertyName()) && SwingWorker.StateValue.PENDING == event.getNewValue()) {
                System.out.println("Thread Status with Mame :" + str + ", SwingWorker Status is " + event.getNewValue());
            } else if ("state".equals(event.getPropertyName()) && SwingWorker.StateValue.STARTED == event.getNewValue()) {
                System.out.println("Thread Status with Name :" + str + ", SwingWorker Status is " + event.getNewValue());
            } else {
                System.out.println("SomeThing Wrong happends with Thread Status with Name :" + str);
            }
        }
    }
}

EDIT:

added re-thrown from Future#get() in done() method (by @takteek excellent suggestion)

@Override
    protected void done() {
        if (str.equals("StartShedule")) {
            try {
                get();
                //errLabel.setText(String.valueOf(get()));
            } catch (InterruptedException ie) {
                ie.printStackTrace();
            } catch (ExecutionException ee) {
                ee.printStackTrace();
            }catch (IllegalStateException is) {
                is.printStackTrace();
            }
        }
    }

but output is still and only Got exception, would be so hard to get any exception(s) from this BlackBox

run:
Got exception
Thread Status with Name :StartShedule, SwingWorker Status is STARTED
Thread Status with Name :StartShedule, SwingWorker Status is DONE
Got exception
Thread Status with Name :StartShedule, SwingWorker Status is STARTED
Thread Status with Name :StartShedule, SwingWorker Status is DONE
Got exception
Thread Status with Name :StartShedule, SwingWorker Status is STARTED
Thread Status with Name :StartShedule, SwingWorker Status is DONE
Got exception
Thread Status with Name :StartShedule, SwingWorker Status is STARTED
Thread Status with Name :StartShedule, SwingWorker Status is DONE
BUILD SUCCESSFUL (total time: 13 seconds)

解决方案

I'm not sure it adds much, but I got the expected Caused by using the variation of takteek's answer shown below. I ran it from the command line to be sure the IDE wasn't "helping".

$ java -cp build/classes TableWithExecutor
StartShedule: PENDING -> STARTED
java.util.concurrent.ExecutionException: java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 2
    at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:222)
    at java.util.concurrent.FutureTask.get(FutureTask.java:83)
    at javax.swing.SwingWorker.get(SwingWorker.java:582)
    at TableWithExecutor$MyTask.done(TableWithExecutor.java:103)
    at javax.swing.SwingWorker$5.run(SwingWorker.java:717)
    at javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.run(SwingWorker.java:814)
    at sun.swing.AccumulativeRunnable.run(AccumulativeRunnable.java:95)
    at javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.actionPerformed(SwingWorker.java:824)
    at javax.swing.Timer.fireActionPerformed(Timer.java:291)
    at javax.swing.Timer$DoPostEvent.run(Timer.java:221)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:677)
    at java.awt.EventQueue.access$000(EventQueue.java:85)
    at java.awt.EventQueue$1.run(EventQueue.java:638)
    at java.awt.EventQueue$1.run(EventQueue.java:636)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:647)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Caused by: java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 2
    at java.util.Vector.get(Vector.java:694)
    at TableWithExecutor.changeTableValues(TableWithExecutor.java:64)
    at TableWithExecutor.access$100(TableWithExecutor.java:14)
    at TableWithExecutor$MyTask.doInBackground(TableWithExecutor.java:92)
    at TableWithExecutor$MyTask.doInBackground(TableWithExecutor.java:80)
    at javax.swing.SwingWorker$1.call(SwingWorker.java:277)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at javax.swing.SwingWorker.run(SwingWorker.java:316)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:680)
StartShedule: STARTED -> DONE

Full code:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.DateFormat;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import javax.swing.*;
import javax.swing.table.*;

/** @see https://stackoverflow.com/questions/7054627 */
public class TableWithExecutor extends JFrame {

    private static final int delay = 1000;
    private static final DateFormat df = DateFormat.getTimeInstance();
    private String[] columnNames = {"Product", "Availability"};
    private Object[][] data = {columnNames, columnNames, columnNames};
    private DefaultTableModel model;
    private JTable table;
    private Executor executor = Executors.newCachedThreadPool();
    private Timer timer;

    public TableWithExecutor() {
        model = new DefaultTableModel(data, columnNames);
        table = new JTable(model) {

            @Override
            public Class getColumnClass(int column) {
                return getValueAt(0, column).getClass();
            }
        };
        table.setDefaultRenderer(Date.class, new DefaultTableCellRenderer() {

            @Override
            protected void setValue(Object value) {
                setText((value == null) ? "" : df.format(value));
            }
        });
        table.setPreferredScrollableViewportSize(new Dimension(200, 100));
        JScrollPane scrollPane = new JScrollPane(table);
        add(scrollPane, BorderLayout.CENTER);
        timer = new Timer(delay, startCycle());
        timer.setRepeats(true);
        timer.start();
    }

    private Action startCycle() {
        return new AbstractAction(MyTask.STARTSCHEDULE) {

            @Override
            public void actionPerformed(ActionEvent e) {
                executor.execute(new MyTask(MyTask.STARTSCHEDULE));
            }
        };
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                TableWithExecutor frame = new TableWithExecutor();
                frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    private class MyTask extends SwingWorker<List<DateRecord>, DateRecord> {

        private static final String STARTSCHEDULE = "StartSchedule";
        private String name = STARTSCHEDULE;

        MyTask(String name) {
            this.name = name;
            addPropertyChangeListener(new TaskListener(name));
        }

        @Override
        protected List<DateRecord> doInBackground() throws Exception {
            for (int row = 0; row < model.getRowCount(); row++) {
                Date date = new Date();
                date.setTime(date.getTime() + row * 1000);
                publish(new DateRecord(row, date));
            }
            return null;
        }

        @Override
        protected void process(List<DateRecord> chunks) {
            for (DateRecord dr : chunks) {
                model.setValueAt(dr.date, dr.rowNumber, 1);
            }
        }

        @Override
        protected void done() {
            try {
                get();
            } catch (Exception e) {
                e.printStackTrace(System.err);
            }
        }
    }

    private static class DateRecord {

        private int rowNumber;
        private Date date;

        public DateRecord(int recordNumber, Date date) {
            this.rowNumber = recordNumber;
            this.date = date;
        }
    }

    private static class TaskListener implements PropertyChangeListener {

        private String name;

        TaskListener(String name) {
            this.name = name;
        }

        @Override
        public void propertyChange(PropertyChangeEvent e) {
            System.out.println(name + ": "
                + e.getOldValue() + " -> " + e.getNewValue());
        }
    }
}

这篇关于无法从Future&lt;?&gt;获取ArrayIndexOutOfBoundsException如果线程启动Executor,则为SwingWorker的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆