sirve que progressbar para ejemplo java swing exception-handling vector swingworker

java - que - No se puede obtener ArrayIndexOutOfBoundsException de Future<?> Y SwingWorker si el hilo se inicia Executor



swingworker java ejemplo (2)

Juego con Multitreading para SwingWorker usando Executor, y estoy allí por error, identifiqué elementos incorrectos del Vector, parece que este código ignora bastante ese elemento en Vector no existe

mi pregunta -> cómo / es posible atrapar esta (s) excepción (es) de alguna manera

salida simple

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)

por comentario

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

todo es correcto, obtengo ArrayIndexOutOfBoundsException y el resultado es

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)

del código

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); } } } }

EDITAR:

añadido relanzado desde Future # get () en método done () (por @takteek excelente sugerencia)

@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(); } } }

pero el resultado es fijo y solo Got exception , sería tan difícil obtener cualquier excepción de este 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)


Creo que el problema al que te estás enfrentando es que las excepciones detectadas en el hilo de fondo solo se vuelven a lanzar si llamas a get() cuando se completa el proceso. Este parece ser un problema común con SwingWorker.

Puede cambiar su función done() a:

@Override protected void done() { if (str.equals("StartShedule")) { try { get(); } catch (Exception ex) { // This exception was thrown during processing ex.printStackTrace(); } } }

done() se ejecuta en el hilo de envío del evento para que pueda visualizar los mensajes de error que necesite desde allí. Espero que eso ayude a algunos.


No estoy seguro de que agregue mucho, pero obtuve la Causa esperada Caused by usar la variación de la respuesta de takteek que se muestra a continuación. Lo ejecuté desde la línea de comando para asegurarme de que el IDE no estaba "ayudando".

$ 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

Código completo:

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://.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()); } } }