/*
* ThreadedTaskPanel.java 29 sept. 2008
*
* Sweet Home 3D, Copyright (c) 2008 Emmanuel PUYBARET / eTeks <info@eteks.com>
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.eteks.sweethome3d.swing;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import com.eteks.sweethome3d.model.UserPreferences;
import com.eteks.sweethome3d.viewcontroller.ThreadedTaskController;
import com.eteks.sweethome3d.viewcontroller.ThreadedTaskView;
import com.eteks.sweethome3d.viewcontroller.View;
/**
* A MVC view of a threaded task.
* @author Emmanuel Puybaret
*/
public class ThreadedTaskPanel extends JPanel implements ThreadedTaskView {
private final UserPreferences preferences;
private final ThreadedTaskController controller;
private JLabel taskLabel;
private JProgressBar taskProgressBar;
private JDialog dialog;
private boolean taskRunning;
public ThreadedTaskPanel(String taskMessage,
UserPreferences preferences,
ThreadedTaskController controller) {
super(new BorderLayout(5, 5));
this.preferences = preferences;
this.controller = controller;
createComponents(taskMessage);
layoutComponents();
}
/**
* Creates and initializes components.
*/
private void createComponents(String taskMessage) {
this.taskLabel = new JLabel(taskMessage);
this.taskProgressBar = new JProgressBar();
this.taskProgressBar.setIndeterminate(true);
}
/**
* Layouts panel components in panel with their labels.
*/
private void layoutComponents() {
add(this.taskLabel, BorderLayout.NORTH);
add(this.taskProgressBar, BorderLayout.SOUTH);
}
/**
* Sets the status of the progress bar shown by this panel as indeterminate.
* This method may be called from an other thread than EDT.
*/
public void setIndeterminateProgress() {
if (EventQueue.isDispatchThread()) {
this.taskProgressBar.setIndeterminate(true);
} else {
// Ensure modifications are done in EDT
invokeLater(new Runnable() {
public void run() {
setIndeterminateProgress();
}
});
}
}
/**
* Sets the current value of the progress bar shown by this panel.
* This method may be called from an other thread than EDT.
*/
public void setProgress(final int value,
final int minimum,
final int maximum) {
if (EventQueue.isDispatchThread()) {
this.taskProgressBar.setIndeterminate(false);
this.taskProgressBar.setValue(value);
this.taskProgressBar.setMinimum(minimum);
this.taskProgressBar.setMaximum(maximum);
} else {
// Ensure modifications are done in EDT
invokeLater(new Runnable() {
public void run() {
setProgress(value, minimum, maximum);
}
});
}
}
/**
* Executes <code>runnable</code> asynchronously in the Event Dispatch Thread.
* Caution !!! This method may be called from an other thread than EDT.
*/
public void invokeLater(Runnable runnable) {
EventQueue.invokeLater(runnable);
}
/**
* Sets the running status of the threaded task.
* If <code>taskRunning</code> is <code>true</code>, a waiting dialog will be shown.
*/
public void setTaskRunning(boolean taskRunning, View executingView) {
this.taskRunning = taskRunning;
if (taskRunning && this.dialog == null) {
String dialogTitle = this.preferences.getLocalizedString(
ThreadedTaskPanel.class, "threadedTask.title");
final JButton cancelButton = new JButton(this.preferences.getLocalizedString(
ThreadedTaskPanel.class, "cancelButton.text"));
final JOptionPane optionPane = new JOptionPane(this, JOptionPane.PLAIN_MESSAGE,
JOptionPane.DEFAULT_OPTION, null, new Object [] {cancelButton});
cancelButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev) {
optionPane.setValue(cancelButton);
}
});
this.dialog = optionPane.createDialog(SwingUtilities.getRootPane((JComponent)executingView), dialogTitle);
try {
// Sleep 200 ms before showing dialog to avoid displaying it
// when the task doesn't last so long
Thread.sleep(200);
} catch (InterruptedException ex) {
}
if (this.controller.isTaskRunning()) {
this.dialog.setVisible(true);
this.dialog.dispose();
if (this.taskRunning
&& (cancelButton == optionPane.getValue()
|| new Integer(JOptionPane.CLOSED_OPTION).equals(optionPane.getValue()))) {
this.dialog = null;
this.controller.cancelTask();
}
}
} else if (!taskRunning && this.dialog != null) {
this.dialog.setVisible(false);
}
}
}