/*
This file is part of JFLICKS.
JFLICKS 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.
JFLICKS 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 JFLICKS. If not, see <http://www.gnu.org/licenses/>.
*/
package org.jflicks.util;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import javax.swing.JSeparator;
import org.jflicks.job.AbstractJob;
import org.jflicks.job.Jobable;
import org.jflicks.job.JobContainer;
import org.jflicks.job.JobEvent;
import org.jflicks.job.JobListener;
import org.jflicks.job.JobManager;
/**
* A UI that displays a progress bar while a given job is running. It
* listens for JobEvents so it will know when the job is complete. There
* is also a cancel button supplied so the user can interrupt the job.
*
* @author Doug Barnum
* @version 1.0
*/
public class ProgressBar implements JobListener, Jobable {
private ArrayList<JobListener> jobList =
new ArrayList<JobListener>();
private JComponent component;
private boolean undecorated;
private String title;
private JDialog dialog;
private AbstractJob job;
private JobContainer jobContainer;
/**
* Constructor with our three required arguments. The title will be
* displayed in the frame bar.
*
* @param c The Component used to center our dialog box.
* @param title The title for the dialog box.
* @param job the given job to start.
*/
public ProgressBar(JComponent c, String title, AbstractJob job) {
setUndecorated(false);
setComponent(c);
setTitle(title);
setJob(job);
init();
job.addJobListener(this);
}
/**
* Constructor with our 2 required arguments. Since a title is not
* suplied then the dialog window will be "undecorated".
*
* @param c The Component used to center our dialog box.
* @param job the given job to start.
*/
public ProgressBar(JComponent c, AbstractJob job) {
setUndecorated(true);
setTitle(null);
setComponent(c);
setJob(job);
init();
job.addJobListener(this);
}
private boolean isUndecorated() {
return (undecorated);
}
private void setUndecorated(boolean b) {
undecorated = b;
}
private JDialog getDialog() {
return (dialog);
}
private void setDialog(JDialog d) {
dialog = d;
}
private JComponent getComponent() {
return (component);
}
private void setComponent(JComponent c) {
component = c;
}
private String getTitle() {
return (title);
}
private void setTitle(String s) {
title = s;
}
private AbstractJob getJob() {
return (job);
}
private void setJob(AbstractJob j) {
job = j;
}
private JobContainer getJobContainer() {
return (jobContainer);
}
private void setJobContainer(JobContainer jc) {
jobContainer = jc;
}
private void init() {
JProgressBar progress = new JProgressBar(0, 600);
Dimension prefSize = progress.getPreferredSize();
prefSize.setSize(prefSize.getWidth() + 100, prefSize.getHeight());
progress.setPreferredSize(prefSize);
progress.setIndeterminate(true);
Window window = Util.findWindow(getComponent());
final JButton cancel = new JButton("Cancel");
RowPanel rp = new RowPanel(cancel);
ColumnPanel cp =
new ColumnPanel(null, 0, progress, new JSeparator(), rp);
JDialog dlg = null;
if (isUndecorated()) {
dlg = new JDialog(window);
dlg.setUndecorated(isUndecorated());
} else {
dlg = new JDialog(window, getTitle());
}
setDialog(dlg);
cancel.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent ae) {
JDialog dlg = getDialog();
dlg.setVisible(false);
cancel.setText("true");
dlg.dispose();
JobContainer jc = getJobContainer();
if (jc != null) {
jc.interrupt();
setDialog(null);
setJobContainer(null);
}
}
}
);
dlg.getContentPane().setLayout(new BorderLayout());
dlg.getContentPane().add(BorderLayout.CENTER, cp);
dlg.pack();
dlg.setLocationRelativeTo(window);
dlg.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dlg.setVisible(true);
}
/**
* This will start the Job.
*/
public void execute() {
AbstractJob aj = getJob();
if (aj != null) {
JobContainer jc = JobManager.getJobContainer(aj);
jc.start();
setJobContainer(jc);
}
}
/**
* Add a job listener.
*
* @param l The given job listener.
*/
public void addJobListener(JobListener l) {
jobList.add(l);
}
/**
* Remove a job listener.
*
* @param l The given job listener.
*/
public void removeJobListener(JobListener l) {
jobList.remove(l);
}
private void fireJobEvent(JobEvent event) {
processJobEvent(event);
}
private synchronized void processJobEvent(JobEvent event) {
for (int i = 0; i < jobList.size(); i++) {
JobListener l = jobList.get(i);
l.jobUpdate(event);
}
}
/**
* We need to know the status of the running job. If it's done
* we finish and dispose of our dialog box.
*
* @param event The given job event instance.
*/
public void jobUpdate(JobEvent event) {
if (event.getType() == JobEvent.COMPLETE) {
JDialog dlg = getDialog();
if (dlg != null) {
dlg.setVisible(false);
dlg.dispose();
}
String message = event.getMessage();
if (message != null) {
// We assume we need to alert the user on some problem.
JOptionPane.showMessageDialog(Util.findWindow(getComponent()),
"Error: " + message, "alert",
JOptionPane.ERROR_MESSAGE);
}
}
fireJobEvent(event);
}
}