001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.progress.swing; 003 004import java.util.concurrent.CancellationException; 005import java.util.concurrent.ExecutionException; 006import java.util.concurrent.Future; 007import java.util.concurrent.LinkedBlockingQueue; 008import java.util.concurrent.ThreadPoolExecutor; 009import java.util.concurrent.TimeUnit; 010 011import org.openstreetmap.josm.tools.Logging; 012import org.openstreetmap.josm.tools.Utils; 013 014/** 015 * Executor that displays the progress monitor to the user. 016 * 017 * Similar to Executors.newSingleThreadExecutor(), but displays the 018 * progress monitor whenever a new task is executed. 019 * @since 12675 (moved from {@code gui.progress} package} 020 */ 021public class ProgressMonitorExecutor extends ThreadPoolExecutor { 022 023 /** 024 * Creates a new {@code ProgressMonitorExecutor} 025 * @param nameFormat see {@link Utils#newThreadFactory(String, int)} 026 * @param threadPriority see {@link Utils#newThreadFactory(String, int)} 027 */ 028 public ProgressMonitorExecutor(final String nameFormat, final int threadPriority) { 029 super(1, 1, 0L, TimeUnit.MILLISECONDS, 030 new LinkedBlockingQueue<Runnable>(), 031 Utils.newThreadFactory(nameFormat, threadPriority)); 032 } 033 034 @Override 035 public void execute(Runnable command) { 036 if (PleaseWaitProgressMonitor.currentProgressMonitor != null) { 037 //TODO show only if this can't be in background or better if always in background is not checked 038 PleaseWaitProgressMonitor.currentProgressMonitor.showForegroundDialog(); 039 } 040 super.execute(command); 041 } 042 043 @Override 044 public void afterExecute(final Runnable r, Throwable t) { 045 // largely as proposed by JDK8 docs 046 super.afterExecute(r, t); 047 if (t == null && r instanceof Future<?>) { 048 try { 049 ((Future<?>) r).get(); 050 } catch (CancellationException cancellationException) { 051 t = cancellationException; 052 } catch (ExecutionException executionException) { 053 Logging.trace(executionException); 054 t = executionException.getCause(); 055 } catch (InterruptedException interruptedException) { 056 Thread.currentThread().interrupt(); // ignore/reset 057 } 058 } 059 if (t != null) { 060 Logging.error("Thread {0} raised {1}", Thread.currentThread().getName(), t); 061 } 062 } 063}