/**
*#########################################################################
*
* A component of the Gatherer application, part of the Greenstone digital
* library suite from the New Zealand Digital Library Project at the
* University of Waikato, New Zealand.
*
*
*
* Author: John Thompson, Greenstone Digital Library, University of Waikato
*
*
*
* Copyright (C) 1999 New Zealand Digital Library Project
*
*
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*########################################################################
*/
package org.greenstone.gatherer.gui;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import org.greenstone.gatherer.Dictionary;
import org.greenstone.gatherer.Gatherer;
import org.greenstone.gatherer.collection.DownloadJob;
import org.greenstone.gatherer.util.AppendLineOnlyFileDocument;
public class DownloadProgressBar
extends JPanel
implements ActionListener {
static final private Dimension MINIMUM_BUTTON_SIZE = new Dimension(100, 25);
static final private Dimension PROGRESS_BAR_SIZE = new Dimension(580,70);
private boolean simple = false;
private Dimension bar_size = new Dimension(520, 20);
private int current_action;
private int err_count;
private int file_count;
private int total_count;
private int warning_count;
private JLabel current_status;
private JLabel main_status;
private JLabel results_status;
private JPanel center_pane;
private JPanel inner_pane;
private JProgressBar progress;
private long file_size;
private long total_size;
private String current_url;
private String initial_url;
private DownloadJob owner;
public JButton stop_start_button;
public JButton log_button;
public JButton close_button;
public DownloadProgressBar(DownloadJob owner, String initial_url, boolean simple) {
this.owner = owner;
this.current_url = null;
this.err_count = 0;
this.initial_url = initial_url;
this.file_count = 0;
this.file_size = 0;
this.simple = simple;
this.total_count = 0;
this.total_size = 0;
this.warning_count = 0;
this.setLayout(new BorderLayout());
this.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
this.current_action = DownloadJob.STOPPED;
inner_pane = new JPanel(new BorderLayout());
inner_pane.setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
center_pane = new JPanel(new GridLayout(3,1));
main_status = new JLabel();
current_status = new JLabel();
results_status = new JLabel();
progress = new JProgressBar();
progress.setStringPainted(true);
progress.setMinimum(0);
progress.setMaximum(0);
progress.setEnabled(false);
progress.setString(Dictionary.get("Mirroring.DownloadJob.Waiting"));
inner_pane.add(progress, BorderLayout.CENTER);
center_pane.add(main_status);
center_pane.add(current_status);
center_pane.add(results_status);
JPanel button_pane = new JPanel();
stop_start_button = new GLIButton(Dictionary.get("Mirroring.DownloadJob.Pause"), Dictionary.get("Mirroring.DownloadJob.Pause_Tooltip"));
stop_start_button.addActionListener(this);
stop_start_button.addActionListener(owner);
stop_start_button.setMinimumSize(MINIMUM_BUTTON_SIZE);
stop_start_button.setEnabled(true);
log_button = new GLIButton(Dictionary.get("Mirroring.DownloadJob.Log"), Dictionary.get("Mirroring.DownloadJob.Log_Tooltip"));
log_button.addActionListener(owner);
log_button.addActionListener(this);
log_button.setEnabled(false);
log_button.setMinimumSize(MINIMUM_BUTTON_SIZE);
close_button = new GLIButton(Dictionary.get("Mirroring.DownloadJob.Close"), Dictionary.get("Mirroring.DownloadJob.Close_Tooltip"));
close_button.addActionListener(owner);
close_button.addActionListener(this);
close_button.setMinimumSize(MINIMUM_BUTTON_SIZE);
close_button.setEnabled(true);
// Layout - or at least some of it
inner_pane.add(center_pane, BorderLayout.NORTH);
button_pane.setLayout(new GridLayout(3,1));
button_pane.add(stop_start_button);
button_pane.add(log_button);
button_pane.add(close_button);
this.add(inner_pane, BorderLayout.CENTER);
this.add(button_pane, BorderLayout.EAST);
// Make the labels, etc update.
refresh();
}
public void actionPerformed(ActionEvent event) {
Object source = event.getSource();
if(source == stop_start_button) {
// If we are running, stop.
if (current_action == DownloadJob.RUNNING) {
current_action = DownloadJob.STOPPED;
stop_start_button.setText(Dictionary.get("Mirroring.DownloadJob.Resume"));
stop_start_button.setToolTipText(Dictionary.get("Mirroring.DownloadJob.Resume_Tooltip"));
progress.setString(Dictionary.get("Mirroring.DownloadJob.Download_Stopped"));
progress.setIndeterminate(false);
} else {
current_action = DownloadJob.RUNNING;
stop_start_button.setText(Dictionary.get("Mirroring.DownloadJob.Pause"));
stop_start_button.setToolTipText(Dictionary.get("Mirroring.DownloadJob.Pause_Tooltip"));
progress.setString(Dictionary.get("Mirroring.DownloadJob.Download_Progress"));
progress.setIndeterminate(true);
}
}
else if(source == close_button) {
// If we are running, stop.
if (current_action == DownloadJob.RUNNING) {
current_action = DownloadJob.STOPPED;
progress.setString(Dictionary.get("Mirroring.DownloadJob.Download_Stopped"));
progress.setIndeterminate(false);
}
}
else if(source == log_button) {
LogDialog dialog = new LogDialog(owner.getLogDocument());
dialog.setVisible(true);
dialog = null;
}
}
/** This method is called when a new download is begun. The
* details of the download are updated and a new JProgressBar
* assigned to track the download.
* @param url The url String of the file that is being downloaded.
*/
public void addDownload(String url) {
current_url = url;
file_size = 0;
refresh();
}
/** When the download of the current url is completed, this method
* is called to enlighten the DownloadProgressBar of this fact.
*/
public void downloadComplete() {
current_url = null;
file_count++;
if(total_count < (file_count + err_count + warning_count)) {
total_count = (file_count + err_count + warning_count);
}
progress.setValue(progress.getMaximum());
refresh();
}
public void downloadFailed() {
err_count++;
if(total_count < (file_count + err_count + warning_count)) {
total_count = (file_count + err_count + warning_count);
}
refresh();
}
public void downloadWarning() {
warning_count++;
if(total_count < (file_count + err_count + warning_count)) {
total_count = (file_count + err_count + warning_count);
}
refresh();
}
public Dimension getPreferredSize() {
return PROGRESS_BAR_SIZE;
}
/** When a link to be downloaded is located, the increaseTotalCount
* method is called. In this way the total count shows the most
* accurate remaining number of files to be downloaded.
*/
public void increaseFileCount() {
total_count++;
refresh();
}
/** When a mirroring task is first initiated this function is called
* to set initial values for the variables if necessary and to
* fiddle visual components such as the tool tip etc.
* @param reset A Boolean specifying whether the variables should be
* reset to zero.
*/
public void mirrorBegun(boolean reset, boolean simple) {
if(reset) {
this.file_count = 0;
this.file_size = 0;
this.total_count = 0;
this.total_size = 0;
this.err_count = 0;
this.warning_count = 0;
}
current_action = DownloadJob.RUNNING;
stop_start_button.setEnabled(true);
log_button.setEnabled(true);
if(simple) {
progress.setIndeterminate(true);
progress.setString(Dictionary.get("Mirroring.DownloadJob.Download_Progress"));
}
}
/** Once a mirroring task is complete, is the DownloadJob returns from the
* native call but the status is still running, then this method
* is called to once again tinker with the pritty visual
* components.
*/
public void mirrorComplete() {
current_action = DownloadJob.COMPLETE;
current_url = null;
if(simple) {
progress.setIndeterminate(false);
}
progress.setValue(progress.getMaximum());
progress.setString(Dictionary.get("Mirroring.DownloadJob.Download_Complete"));
stop_start_button.setEnabled(false);
this.updateUI();
}
/** When called this method updates the DownloadProgressBar to reflect
* the ammount of the current file downloaded.
*/
public void updateProgress(long current, long expected) {
file_size = file_size + current;
if(!progress.isIndeterminate()) {
// If current is zero, then this is the 'precall' before the
// downloading actually starts.
if(current == 0) {
// Remove the old progress bar, then deallocate it.
inner_pane.remove(progress);
progress = null;
if(expected == 0) {
// We don't have a content length. This bar will go from 0 to 100 only!
progress = new JProgressBar(0, 100);
}
else {
// Assign a new progress bar of length expected content length.
progress = new JProgressBar(0, (new Long(expected)).intValue());
}
progress.setEnabled(true);
// Add the new progress bar.
inner_pane.add(progress, BorderLayout.CENTER);
inner_pane.updateUI();
}
// Otherwise if expected is not zero move the progress bar and
// update percent complete.
else if (expected != 0) {
progress.setValue((new Long(file_size)).intValue());
int p_c = (new Double(progress.getPercentComplete() * 100)).intValue();
progress.setString(p_c + "%");
progress.setStringPainted(true);
}
// Finally, in the case we have no content length, we'll instead
// write the current number of bytes downloaded again.
else {
progress.setString(file_size + " b");
progress.setStringPainted(true);
}
}
refresh();
}
/** Causes the two labels associated with this DownloadProgressBar object to
* update, thus reflecting the progression of the download. This
* method is called by any of the other public setter methods in this
* class.
*/
private void refresh() {
// Refresh the contents of main label.
String args1[] = new String[1];
args1[0] = initial_url.toString();
main_status.setText(Dictionary.get("Mirroring.DownloadJob.Downloading", args1));
if (current_url != null) {
// Refresh the current label contents.
String args2[] = new String[1];
args2[0] = current_url;
current_status.setText(Dictionary.get("Mirroring.DownloadJob.Downloading", args2));
}
else if (current_action == DownloadJob.STOPPED || current_action == DownloadJob.PAUSED) {
current_status.setText(Dictionary.get("Mirroring.DownloadJob.Waiting_User"));
}
else {
current_status.setText(Dictionary.get("Mirroring.DownloadJob.Download_Complete"));
}
// Refresh the contents of results label
String args3[] = new String[4];
args3[0] = file_count + "";
args3[1] = total_count + "";
args3[2] = warning_count + "";
args3[3] = err_count + "";
results_status.setText(Dictionary.get("Mirroring.DownloadJob.Status", args3));
this.updateUI();
}
static final private Dimension DIALOG_SIZE = new Dimension(640,480);
private class LogDialog
extends JDialog {
public LogDialog(AppendLineOnlyFileDocument document) {
super(Gatherer.g_man, "Mirroring.DownloadJob.Download_Log_Dialog_Title");
setSize(DIALOG_SIZE);
JPanel content_pane = (JPanel) getContentPane();
JTextArea text_area = new JTextArea(document);
JButton button = new GLIButton(Dictionary.get("General.Close"));
// Connection
button.addActionListener(new CloseActionListener());
// Layout
content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
content_pane.setLayout(new BorderLayout());
content_pane.add(new JScrollPane(text_area), BorderLayout.CENTER);
content_pane.add(button, BorderLayout.SOUTH);
}
private class CloseActionListener
implements ActionListener {
public void actionPerformed(ActionEvent event) {
LogDialog.this.dispose();
}
}
}
}