All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.cayenne.modeler.util.LongRunningTask Maven / Gradle / Ivy

There is a newer version: 5.0-M1
Show newest version
/*****************************************************************
 *   Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *    https://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 ****************************************************************/

package org.apache.cayenne.modeler.util;

import javax.swing.*;

import org.apache.cayenne.CayenneRuntimeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A base class for monitoring progress of long running tasks. It can runshowing the exact
 * percentage of the task progress or in "indeterminate" mode.
 * 

* Warning: If the task started via "startAndWait()", caller must ensure that she is * not running in the Swing EventDispatchThread, otherwise an exception is thrown, as the * EvenDispatchThread will be blocked, preventing LongRunningTask from showing progress * dialog. *

* */ public abstract class LongRunningTask { private static final Logger LOGGER = LoggerFactory.getLogger(LongRunningTask.class); protected static final int DEFAULT_MS_TO_DECIDE_TO_POPUP = 500; protected ProgressDialog dialog; protected JFrame frame; protected String title; protected Timer taskPollingTimer; protected boolean canceled; protected int minValue; protected int maxValue; protected boolean finished; protected T result; public LongRunningTask(JFrame frame, String title) { this.frame = frame; this.title = title; } /** * Starts current task, and blocks current thread until the task is done. */ public synchronized T startAndWait() { // running from Event Dispatch Thread is bad, as this will block the timers... if (SwingUtilities.isEventDispatchThread()) { throw new CayenneRuntimeException( "Can't block EventDispatchThread. Call 'startAndWait' from another thread."); } start(); if (finished) { return result; } try { wait(); } catch (InterruptedException e) { setCanceled(true); } notifyAll(); return result; } /** * Configures the task to run in a separate thread, and immediately exits the method. * This method is allowed to be invoked from EventDispatchThread. */ public void start() { // prepare... setCanceled(false); this.finished = false; Thread task = new Thread(this::internalExecute); Timer progressDisplayTimer = new Timer( DEFAULT_MS_TO_DECIDE_TO_POPUP, e -> showProgress()); progressDisplayTimer.setRepeats(false); // start progressDisplayTimer.start(); task.start(); } /** * Starts progress dialog if the task is not finished yet. */ protected synchronized void showProgress() { LOGGER.debug("will show progress..."); if (finished) { return; } int currentValue = getCurrentValue(); if (!isCanceled() && currentValue < getMaxValue()) { LOGGER.debug("task still in progress, will show progress dialog..."); this.dialog = new ProgressDialog(frame, "Progress...", title); this.dialog.getCancelButton().addActionListener(e -> setCanceled(true)); dialog.getProgressBar().setMinimum(getMinValue()); dialog.getProgressBar().setMaximum(getMaxValue()); updateProgress(); this.taskPollingTimer = new Timer(500, e -> updateProgress()); this.taskPollingTimer.start(); this.dialog.setVisible(true); } } /** * Updates current state of the progress dialog. */ protected void updateProgress() { if (isCanceled()) { stop(); return; } dialog.getStatusLabel().setText(getCurrentNote()); JProgressBar progressBar = dialog.getProgressBar(); if (!isIndeterminate()) { progressBar.setValue(getCurrentValue()); progressBar.setIndeterminate(false); } else { progressBar.setIndeterminate(true); } } protected synchronized void stop() { if (taskPollingTimer != null) { taskPollingTimer.stop(); } if (dialog != null) { dialog.dispose(); } // there maybe other threads waiting on this task to finish... finished = true; notifyAll(); } public boolean isFinished() { return finished; } public boolean isCanceled() { return canceled; } public void setCanceled(boolean b) { if (b) { LOGGER.debug("task canceled"); } this.canceled = b; } protected void internalExecute() { try { execute(); } catch (Throwable th) { setCanceled(true); LOGGER.warn("task error", th); } finally { stop(); } } /** * Runs the actual task, consulting "isCanceled()" state to make sure that the task * wasn't canceled. */ protected abstract void execute(); protected abstract String getCurrentNote(); protected abstract int getCurrentValue(); protected abstract boolean isIndeterminate(); public int getMaxValue() { return maxValue; } public void setMaxValue(int maxValue) { this.maxValue = maxValue; } public int getMinValue() { return minValue; } public void setMinValue(int minValue) { this.minValue = minValue; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy