/* * #%L * gitools-ui-platform * %% * Copyright (C) 2013 Universitat Pompeu Fabra - Biomedical Genomics group * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ package org.gitools.ui.platform.progress; import org.gitools.api.analysis.IProgressMonitor; import org.gitools.ui.platform.dialog.ExceptionGlassPane; import javax.swing.*; import java.awt.*; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.CancellationException; import java.util.concurrent.CountDownLatch; public class JobThread implements JobRunnable { private final Window parent; private final JobRunnable runnable; private CountDownLatch latch; private Thread thread; private IProgressComponent progressDialog; private JobProgressMonitor monitor; private static boolean running = false; public static void execute(Window parent, JobRunnable runnable) { new JobThread(parent, runnable).execute(); } public static void execute(Window parent, JobRunnable runnable, CountDownLatch waitingLatch) { new JobThread(parent, runnable, waitingLatch).execute(); } private JobThread(Window parent, JobRunnable runnable) { this.parent = parent; this.runnable = runnable; } private JobThread(Window parent, JobRunnable runnable, CountDownLatch latch) { this.parent = parent; this.runnable = runnable; this.latch = latch; } private JobThread(Window parent, JobRunnable runnable, IProgressComponent dialog) { this.parent = parent; this.runnable = runnable; this.progressDialog = dialog; } public JobThread(JFrame parent) { this.parent = parent; this.runnable = this; } public Window getParent() { return parent; } Thread getThread() { return thread; } synchronized void setThread(Thread jobThread) { this.thread = jobThread; } private synchronized IProgressComponent getProgressDialog() { if (progressDialog == null) { progressDialog = new JobProgressGlassPane(parent, true); progressDialog.addCancelListener(new CancelListener() { @Override public void cancelled() { cancelJob(); } }); } return progressDialog; } private synchronized void setProgressDialog(IProgressComponent progressDialog) { this.progressDialog = progressDialog; } void cancelJob() { getMonitor().cancel(); progressDialog.setMessage("Cancelling..."); Timer timer = new Timer("JobThread.cancelJob"); timer.schedule(new TimerTask() { @Override public void run() { synchronized (JobThread.this) { Thread jobThread = getThread(); if (jobThread != null && jobThread.isAlive()) { jobThread.interrupt(); } } } }, 250); } void done() { running = false; SwingUtilities.invokeLater(new Runnable() { @Override public void run() { IProgressComponent dlg = getProgressDialog(); dlg.setVisible(false); //TODO progressDialog.dispose(); setProgressDialog(null); } }); } synchronized JobProgressMonitor getMonitor() { return monitor; } synchronized void setMonitor(JobProgressMonitor monitor) { this.monitor = monitor; } void startThread() { thread = new Thread("JobThread") { @Override public void run() { newRunnable().run(); // notify waiting thread if (latch != null) { latch.countDown(); } } }; thread.start(); } private Runnable newRunnable() { return new Runnable() { @Override public void run() { JobProgressMonitor m = new JobProgressMonitor(getProgressDialog(), System.out, false, false); setMonitor(m); org.gitools.utils.progressmonitor.ProgressMonitor.set(m); try { monitor.start(); running = true; runnable.run(monitor); running = false; monitor.end(); } catch (CancellationException e) { if (!monitor.isCancelled()) { monitor.exception(e); } } catch (Throwable cause) { if (!(cause.getCause() instanceof CancellationException && m.isCancelled())) { m.exception(cause); } } done(); setThread(null); if (monitor.getCause() != null && !(monitor.getCause() instanceof CancellationException && monitor.isCancelled())) { ExceptionGlassPane ed = new ExceptionGlassPane(parent, monitor.getCause()); ed.setVisible(true); } } }; } void execute() { startThread(); //getProgressDialog().setModal(true); getProgressDialog().setVisible(true); } public boolean isCancelled() { return getMonitor().isCancelled(); } public Throwable getCause() { return getMonitor().getCause(); } @Override public void run(IProgressMonitor monitor) { throw new UnsupportedOperationException("Opperation should be overrided"); } public static boolean isRunning() { return running; } }