Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Creazione di un download
manager in Java
40 Capitolo 34
creazione di Java, non sorprende che le capacit di rete di Java siano insuperabili.
Per esempio, il tentativo di creare il Download Manager in un altro linguaggio,
quale C++, comporterebbe molti pi problemi e lavoro.
La classe Download il cavallo da tiro del Download Manager. Lo scopo primario scaricare un file e salvarne i contenuti nel disco. Ogni volta che si aggiunge un nuovo download al Download Manager, viene creato un nuovo oggetto
Download per gestirlo.
Il Download Manager in grado di scaricare pi file contemporaneamente.
Per farlo necessario che ogni download sia eseguito in modo indipendente.
inoltre necessario che ogni singolo download gestisca il proprio stato in modo
che possa essere riflesso nella GUI. Ci si ottiene con la classe Download.
Il codice completo per Download mostrato di seguito. Si noti che estende
Observable e implementa Runnable. Ogni parte si esamina in dettaglio nei paragrafi successivi.
import java.io.*;
import java.net.*;
import java.util.*;
// Questa classe scarica un file da un URL.
class Download extends Observable implements Runnable {
// Dimensioni max del buffer di download.
private static final int MAX_BUFFER_SIZE = 1024;
// Questi sono i nomi degli stati.
2012, McGraw-Hill
PARTE IV
42 Capitolo 34
// Riprende il download.
public void resume() {
status = DOWNLOADING;
stateChanged();
download();
}
// Annulla il download.
public void cancel() {
status = CANCELLED;
stateChanged();
}
// Contrassegna il download come con errore.
private void error() {
status = ERROR;
stateChanged();
}
// Avvia o riprende il download.
private void download() {
Thread thread = new Thread(this);
thread.start();
}
PARTE IV
44 Capitolo 34
if (connection.getResponseCode() / 100 != 2) {
error();
}
// Controlla la validit della lunghezza dei contenuti.
int contentLength = connection.getContentLength();
if (contentLength < 1) {
error();
}
/* Imposta le dimensioni per il download se
non sono gi impostate. */
if (size == -1) {
size = contentLength;
stateChanged();
}
// Apre il file e ne cerca la fine.
file = new RandomAccessFile(getFileName(url), rw);
file.seek(downloaded);
stream = connection.getInputStream();
while (status == DOWNLOADING) {
/* Dimensiona il buffer secondo la quantit di
file restata da scaricare. */
byte buffer[];
if (size - downloaded > MAX_BUFFER_SIZE) {
buffer = new byte[MAX_BUFFER_SIZE];
} else {
buffer = new byte[size - downloaded];
}
// Legge dal server nel buffer.
int read = stream.read(buffer);
if (read == -1)
break;
// Scrive il buffer nel file.
file.write(buffer, 0, read);
downloaded += read;
stateChanged();
}
/* Cambia lo stato in completo se questo punto stato
raggiunto perch finito il download. */
if (status == DOWNLOADING) {
status = COMPLETE;
2012, McGraw-Hill
stateChanged();
}
} catch (Exception e) {
error();
} finally {
// Chiude il file.
if (file != null) {
try {
file.close();
} catch (Exception e) {}
}
// Chiude la connessine al server.
if (stream != null) {
try {
stream.close();
} catch (Exception e) {}
}
Le variabili di Download
Download inizia dichiarando numerose variabili static final che specificano le
diverse costanti utilizzate dalla classe, quindi sono dichiarate quattro variabili di
istanza. La variabile url contiene lURL Internet per il file da scaricare, la variabile
size contiene le dimensioni del file da scaricare in byte; la variabile downloaded
contiene il numero di byte scaricati e la variabile status indica lo stato corrente
del download.
Il costruttore di Download
Al costruttore di Download si passa un riferimento allURL da scaricare sotto
forma di un oggetto URL, assegnato alla variabile di istanza url. Si impostano
quindi le variabili di istanza restanti sui relativi stati iniziali e si chiama il metodo download(). Si noti che size impostata su -1 a indicare che non sono ancora
presenti le dimensioni.
Il metodo download()
Il metodo download() crea un nuovo oggetto Thread, passando ad esso un riferimento allistanza di Download chiamante. Come detto in precedenza, necessario che ogni download sia eseguito in modo indipendente. Affinch la classe
2012, McGraw-Hill
PARTE IV
}
}
// Segnala agli osservatori che lo stato del download cambiato.
private void stateChanged() {
setChanged();
notifyObservers();
}
}
46 Capitolo 34
Download agisca da sola, deve essere eseguita nel proprio thread. Java dispone di un eccellente supporto incorporato per i thread e ne facilita lutilizzo. Per
utilizzare i thread, la classe Download implementa semplicemente linterfaccia
Runnable ridefinendo il metodo run(). Quando il metodo download() ha creato
una nuova istanza di Thread, passando al costruttore la classe Download Runnable, chiama il metodo start() del thread. La chiamata al metodo start() fa in modo
che sia eseguito il metodo run() dellistanza Runnable (della classe Download).
Il metodo run()
Quando viene eseguito il metodo run(), inizia il download effettivo. A causa delle dimensioni e dellimportanza di tale metodo, viene esaminato in dettaglio. Il
metodo run() inizia con le righe mostrate di seguito:
RandomAccessFile file = null;
InputStream stream = null;
try {
// Apre connessione verso lURL.
HttpURLConnection connection =
(HttpURLConnection) url.openConnection();
run() imposta le variabili per il flusso di rete da cui vengono letti i contenuti
del download e imposta il file in cui si scrivono i contenuti del download. Quindi
apre una connessione verso lURL del download chiamando url.openConnection(). Poich noto che il Download Manager supporta solo download HTTP, la
connessione viene convertita nel tipo HttpURLConnection. La conversione della
connessione in HttpURLConnection consente di sfruttare le funzioni di connessione specifiche per HTTP quali il metodo getResponseCode(). Si noti che la chiamata a url.openConnection() non crea una connessione verso il server dellURL;
crea semplicemente una nuova istanza URLConnection associata allURL che in
seguito verr utilizzato per la connessione al server.
Dopo la creazione di HttpURLConnection, si imposta la propriet di richiesta
della connessione chiamando connection.setRequestProperty(), come mostrato
di seguito:
// Specifica la parte di file da scaricare.
connection.setRequestProperty(Range,
bytes= + downloaded + -);
Limpostazione delle propriet di richiesta consente di inviare informazioni extra sulla richiesta al server da cui proviene il download. In questo caso si
imposta la propriet Range. molto importante, poich la propriet Range
specifica lintervallo di byte richiesti per il download dal server. Normalmente
vengono scaricati tutti i byte del file in una sola volta. Tuttavia, se un download
stato interrotto o fermato, si devono recuperare solo i byte restanti del download. Limpostazione della propriet Range la base del funzionamento del
Download Manager.
2012, McGraw-Hill
Viene chiamato il metodo connection.connect() per effettuare la connessione al server di download. Quindi si controlla il codice di risposta restituito dal
server. Il protocollo HTTP ha un elenco di codici di risposta che indicano la risposta di un server a una richiesta. I codici di risposta HTTP sono organizzati
in intervalli numerici di cento in cento e lintervallo 200 indica il successo. Si
controlla che codice di risposta del server sia nellintervallo 200 chiamando connection.getResponseCode() e dividendolo per 100. Se il valore della divisione
2, la connessione stata effettuata con successo.
Quindi run() ottiene la lunghezza del contenuto chiamando connection.getContentLength(). La lunghezza del contenuto rappresenta il numero di byte nel
rile richiesto. Se la lunghezza del contenuto minore di 1, viene chiamato il metodo error(), che aggiorna lo stato del download su ERROR, quindi chiama stateChanged(). Il metodo stateChanged() descritto in dettaglio pi avanti.
Dopo avere ottenuto la lunghezza del contenuto, il codice di seguito controlla
se gi stato assegnato alla variabile size:
/* Imposta le dimensioni per il download se
non sono gi impostate. */
if (size == -1) {
size = contentLength;
stateChanged();
}
2012, McGraw-Hill
PARTE IV
// Si connette al server.
connection.connect();
// Verifica che il codice di risposta sia nellintervallo
200.
if (connection.getResponseCode() / 100 != 2) {
error();
}
// Controlla la validit della lunghezza dei contenuti.
int contentLength = connection.getContentLength();
if (contentLength < 1) {
error();
}
48 Capitolo 34
Come si pu osservare, invece di assegnare la lunghezza del contenuto alla variabile size in modo incondizionato, viene assegnata solo se non ha gi un valore.
Il motivo che la lunghezza del contenuto riflette il numero di byte che il server
invier. Se si specifica un elemento diverso da un inizio di intervallo basato su
0, la lunghezza del contenuto rappresenta solo una parte delle dimensioni del
file. La variabile size deve essere impostata sulle dimensioni complete del file di
download.
Le righe di codice successive mostrate di seguito creano un nuovo RandomAccessFile utilizzando la parte di nome di file dellURL del download recuperato
con una chiamata al metodo getFileName():
// Apre il file e ne cerca la fine.
file = new RandomAccessFile(getFileName(url), rw);
file.seek(downloaded);
Il RandomAccessFile viene aperto in modalit rw, che specifica che possibile leggere il file e scrivere in esso. Quando il file aperto, run() cerca la fine
del file chiamando il metodo file.seek(), passando la variabile downloaded. Ci
indica al file di posizionarsi sul numero di byte scaricati, in altre parole alla fine.
necessario posizionare il file alla fine nel caso in cui un download sia stato ripreso. Se si riprende un download, i byte scaricati vengono aggiunti alla fine del
file e non sovrascrivono i byte scaricati in precedenza. Dopo la preparazione del
file di output, si ottiene un gestore del flusso di rete verso il server aperto chiamando connection.getInputStream(), come mostrato di seguito:
stream = connection.getInputStream();
Inizia quindi il centro dellazione con un ciclo while:
while (status == DOWNLOADING) {
/* Dimensiona il buffer secondo la quantit di
file restata da scaricare. */
byte buffer[];
if (size - downloaded > MAX_BUFFER_SIZE) {
buffer = new byte[MAX_BUFFER_SIZE];
} else {
buffer = new byte[size - downloaded];
}
// Legge dal server nel buffer.
int read = stream.read(buffer);
if (read == -1)
break;
// Scrive il buffer nel file.
file.write(buffer, 0, read);
downloaded += read;
stateChanged();
}
2012, McGraw-Hill
Il ciclo viene impostato per essere eseguito fino a quando la variabile status
diversa da DOWNLOADING. Nel ciclo si crea un array di buffer byte per contenere i byte da scaricare. Il buffer dimensionato secondo la quantit di download
restante per il completamento. Se si deve scaricare una quantit di byte maggiore
di MAX_BUFFER_SIZE, per dimensionare il buffer si utilizza MAX_BUFFER_
SIZE, altrimenti il buffer viene dimensionato sul numero di byte ancora da scaricare. Quando il buffer stato dimensionato correttamente, ha luogo il download
con una chiamata a stream.read(). La chiamata legge byte dal server e li inserisce
nel buffer, restituendo il conteggio dei byte effettivamente letti. Se il numero di
byte letti uguale a -1, il download completo e si esce dal ciclo, altrimenti il
download non terminato e i byte letti vengono scritti su disco con una chiamata
a file.write(). Quindi si aggiorna la variabile downloaded, in modo da riflettere
il numero di byte scaricati. Infine, allinterno del ciclo, si chiama il metodo stateChanged(). Ulteriori dettagli pi avanti.
Dopo luscita dal ciclo, il codice di seguito controlla perch si usciti dal ciclo:
/* Cambia lo stato in completo se questo punto stato
raggiunto perch finito il download. */
if (status == DOWNLOADING) {
status = COMPLETE;
stateChanged();
}
PARTE IV
50 Capitolo 34
se le connessioni file e stream sono state aperte, vengano chiuse, che sia stata lanciata uneccezione o no. Come esercizio, si pu provare a modificare il codice in
modo da utilizzare la nuova dichiarazione try con risorse per gestire tali risorse.
Il metodo stateChanged()
Affinch il Download Manager visualizzi informazioni aggiornate sui download che gestisce, deve sapere quando cambiano le informazioni su un download.
Per gestire tale situazione si utilizza lo schema di design Observer. Lo schema
Observer analogo a una mailing list di annunci in cui le persone si registrano
per ricevere annunci. Ogni volta che esiste un nuovo annuncio, tutte le persone
nellelenco ricevono un messaggio con lannuncio. Nel caso dello schema Observer esiste una classe osservata presso cui le classi osservatrici possono registrarsi
per ricevere notifiche di modifiche.
La classe Download utilizza lo schema Observer estendendo la classe di utility
incorporata Observable di Java. Lestensione della classe Observable consente
alle classi che implementano linterfaccia Observer di Java di registrarsi presso
la classe Download per ricevere notifiche di modifiche. Ogni volta che la classe
Download deve notificare un cambiamento agli Observer registrati, viene chiamato il metodo stateChanged(). Il metodo stateChanged() chiama prima il metodo setChanged() della classe Observable per contrassegnare la classe come modificata. Quindi il metodo stateChanged() chiama il metodo notifyObservers()
di Observable, che trasmette la notifica di cambiamento agli Observer registrati.
PARTE IV
52 Capitolo 34
return columnNames[col];
}
// Ottiene la classe di una colonna.
public Class<?> getColumnClass(int col) {
return columnClasses[col];
}
// Ottiene conteggio di righe della tabella.
public int getRowCount() {
return downloadList.size();
}
PARTE IV
54 Capitolo 34
Il metodo addDownload()
Il metodo addDownload(), mostrato di seguito, aggiunge un nuovo oggetto
Download allelenco di download gestiti, quindi aggiunge una riga nella tabella:
// Aggiunge un nuovo download alla tabella.
public void addDownload(Download download) {
// Si registra per essere avvisto quando cambia il download.
download.addObserver(this);
downloadList.add(download);
// Invia alla tabella notifica di inserimento di riga.
fireTableRowsInserted(getRowCount() - 1, getRowCount() - 1);
}
Il metodo clearDownload()
Il metodo clearDownload(), mostrato di seguito, elimina un Download dallelenco di download gestiti:
// Elimina un download dallelenco.
public void clearDownload(int row) {
downloadList.remove(row);
// Invia alla tabella notifica di eliminazione di riga.
fireTableRowsDeleted(row, row);
}
Dopo avere eliminato il Download dallelenco interno, viene inviata una notifica di eliminazione di riga di tabella per indicare alla tabella che stata eliminata
una riga.
Il metodo getColumnClass()
Il metodo getColumnClass(), mostrato di seguito, restituisce il tipo di classe per
i dati visualizzati nella colonna specificata:
// Ottiene la classe di una colonna.
public Class<?> getColumnClass(int col) {
return columnClasses[col];
}
2012, McGraw-Hill
Tutte le colonne sono visualizzate come testo (vale a dire oggetti String) ad eccezione della colonna Progress, visualizzata come barra di avanzamento (un oggetto di tipo JProgressBar).
Il metodo getValueAt()
Il metodo getValueAt(), mostrato di seguito, viene chiamato per ottenere il valore corrente da visualizzare per ogni cella della tabella:
// Ottiene valore per una combinazione specifica di riga e di
colonna.
public Object getValueAt(int row, int col) {
Download download = downloadList.get(row);
switch (col) {
case 0: // URL
return download.getUrl();
case 1: // Dimensioni
int size = download.getSize();
return (size == -1) ? : Integer.toString(size);
case 2: // Avanzamento
return new Float(download.getProgress());
case 3: // Stato
return Download.STATUSES[download.getStatus()];
}
return ;
}
Il metodo update()
Il metodo update() mostrato di seguito. Adempie al contratto con linterfaccia
Observer consentendo alla classe DownloadsTableModel di ricevere notifiche
dagli oggetti Download quando cambiano.
/* Update viene chiamato quando un Download informa i suoi
osservatori di modifiche */
public void update(Observable o, Object arg) {
int index = downloadList.indexOf(o);
// Invia alla tabella notifica di aggiornamento di riga.
fireTableRowsUpdated(index, index);
}
Al metodo si passa un riferimento al Download cambiato, sotto forma di oggetto Observable. Quindi si cerca un indice verso tale download nellelenco dei
download e si utilizza tale indice per inviare una notifica di evento di aggiornamento di riga di tabella, che indica alla tabella che la riga data stata modificata.
La tabella visualizza la riga con lindice dato, riflettendo i nuovi valori.
2012, McGraw-Hill
PARTE IV
56 Capitolo 34
java.awt.*;
java.awt.event.*;
java.net.*;
java.util.*;
javax.swing.*;
javax.swing.event.*;
// Il Download Manager.
public class DownloadManager extends JFrame
implements Observer
{
// Aggiunge i campi di testo per i download.
private JTextField addTextField;
// Il modello di dati della tabella di download.
private DownloadsTableModel tableModel;
// Tabella che elenca i download.
private JTable table;
// Questi sono i pulsanti per la gestione del download selezionato.
private JButton pauseButton, resumeButton;
private JButton cancelButton, clearButton;
// Download selezionato.
private Download selectedDownload;
// Flag per sapere se la selezione di tabella deve essere
annullata.
private boolean clearing;
// Costruttore per Download Manager.
public DownloadManager()
{
// Imposta titolo dellapplicazione.
setTitle(Download Manager);
2012, McGraw-Hill
PARTE IV
58 Capitolo 34
2012, McGraw-Hill
});
clearButton.setEnabled(false);
buttonsPanel.add(clearButton);
// Aggiunge pannelli da visualizzare.
getContentPane().setLayout(new BorderLayout());
getContentPane().add(addPanel, BorderLayout.NORTH);
getContentPane().add(downloadsPanel, BorderLayout.CENTER);
getContentPane().add(buttonsPanel, BorderLayout.SOUTH);
}
// Esce dal programma.
private void actionExit() {
System.exit(0);
}
PARTE IV
60 Capitolo 34
switch (status) {
case Download.DOWNLOADING:
pauseButton.setEnabled(true);
resumeButton.setEnabled(false);
cancelButton.setEnabled(true);
clearButton.setEnabled(false);
break;
case Download.PAUSED:
pauseButton.setEnabled(false);
resumeButton.setEnabled(true);
cancelButton.setEnabled(true);
clearButton.setEnabled(false);
break;
case Download.ERROR:
pauseButton.setEnabled(false);
resumeButton.setEnabled(true);
cancelButton.setEnabled(false);
clearButton.setEnabled(true);
break;
default: // COMPLETE o CANCELLED
pauseButton.setEnabled(false);
resumeButton.setEnabled(false);
cancelButton.setEnabled(false);
clearButton.setEnabled(true);
}
} else {
// Nella tabella non selezionato alcun download.
pauseButton.setEnabled(false);
resumeButton.setEnabled(false);
cancelButton.setEnabled(false);
clearButton.setEnabled(false);
}
}
/* Update viene chiamato quando un Download informa i suoi
osservatori di modifiche. */
public void update(Observable o, Object arg) {
// Aggiorna pulsanti se il download cambiato.
if (selectedDownload != null && selectedDownload.
equals(o))
SwingUtilities.invokeLater(new Runnable() {
public void run() {
updateButtons();
}
});
}
// Esegue il Download Manager.
public static void main(String[] args) {
2012, McGraw-Hill
PARTE IV
62 Capitolo 34
SwingUtilities.invokeLater(new Runnable() {
public void run() {
DownloadManager manager = new DownloadManager();
manager.setVisible(true);
}
});
}
}
Le variabili di DownloadManager
DownloadManager inizia dichiarando numerose variabili di istanza, molte delle
quali contengono riferimenti ai controlli della GUI. La variabile selectedDownload contiene un riferimento alloggetto Download rappresentato dalla riga selezionata nella tabella. Infine la variabile di istanza clearing una flag boolean che
indica se un download in fase di eliminazione dalla tabella Downloads.
Il costruttore di DownloadManager
Quando si crea unistanza di DownloadManager, tutti i controlli della GUI vengono inizializzati allinterno del costruttore. Il costruttore contiene molto codice,
in gran parte semplice. La descrizione di seguito fornisce una panoramica.
In primo luogo si imposta il titolo della finestra con una chiamata a setTitle().
Quindi la chiamata a setSize() definisce laltezza e la larghezza della finestra in
pixel. In seguito si aggiunge un rilevatore di finestra chiamando addWindowListener(), passando un oggetto WindowAdapter che ridefinisce il gestore di eventi windowClosing(). Il gestore chiama il metodo actionExit() quando viene chiusa la finestra dellapplicazione. Si aggiunge alla finestra dellapplicazione una
barra del menu con un menu File. Quindi si imposta il pannello add, con
il campo di testo e il pulsante. Si aggiunge un ActionListener al pulsante Add
Download in modo che il metodo actionAdd() sia chiamato ogni volta che si fa
clic sul pulsante.
In seguito viene costruita la tabella dei download. Si aggiunge alla tabella un
ListSelectionListener, in modo che ogni volta che si seleziona una riga nella tabella sia chiamato il metodo tableSelectionChanged(). Viene inoltre aggiornata la
modalit di selezione della tabella in ListSelectionModel.SINGLE_SELECTION,
in modo che sia possibile selezionare una sola riga per volta. La limitazione della
selezione di righe a una sola riga semplifica la logica per determinare i pulsanti
da attivare nella GUI quando viene selezionata una riga nella tabella di download. Quindi si istanzia un oggetto della classe ProgressRenderer e si registra nella
tabella per gestire la colonna Progress. Laltezza della riga di tabella si aggiorna
secondo laltezza di ProgressRenderer chiamando table.setRowHeight(). Dopo
la creazione e la regolazione della tabella, questa viene inserita in un JScrollPane
affinch si possa scorrere in essa e viene aggiunta a un pannello.
Infine si crea il riquadro dei pulsanti, contenente i pulsanti Pause, Resume,
Cancel e Clear. Ciascun pulsante aggiunge un ActionListener che chiama il rispettivo metodo di azione quando si fa clic su di esso. Dopo la creazione del
riquadro dei pulsanti, tutti i riquadri creati vengono aggiunti alla finestra.
2012, McGraw-Hill
Il metodo verifyUrl()
Il metodo verifyUrl() viene chiamato dal metodo actionAdd() ogni volta che si
aggiunge un download al Download Manager. Il metodo verifyUrl() mostrato
di seguito:
// Verifica URL di download.
private URL verifyUrl(String url) {
// Consente solo URL HTTP.
if (!url.toLowerCase().startsWith(http://))
return null;
// Verifica formato dellURL.
URL verifiedUrl = null;
try {
verifiedUrl = new URL(url);
} catch (Exception e) {
return null;
}
// Verifica che lURL specifichi un file.
if (verifiedUrl.getFile().length() < 2)
return null;
return verifiedUrl;
Il metodo verifica che lURL immesso sia un URL HTTP, poich supportato
solo HTTP. Quindi si utilizza lURL verificato per costruire una nuova istanza
della classe URL. Se lURL malformato, il costruttore della classe URL lancia
uneccezione. Infine il metodo verifica che nellURL sia specificato un file.
Il metodo tableSelectionChanged()
Il metodo tableSelectionChanged(), mostrato di seguito, viene chiamato ogni
volta che si seleziona una riga nella tabella dei download:
// Chiamato quando cambia selezione di riga di tabella.
private void tableSelectionChanged() {
/* Annulla registrazione per ricezione notifiche
dallultimo download selezionato. */
if (selectedDownload != null)
selectedDownload.deleteObserver(DownloadManager.this);
/* Se non si trova nellannullamento di un download,
imposta download selezionato e si registra per
ricevere notifiche da esso. */
if (!clearing && table.getSelectedRow() > -1) {
selectedDownload =
tableModel.getDownload(table.getSelectedRow());
selectedDownload.addObserver(DownloadManager.this);
2012, McGraw-Hill
PARTE IV
64 Capitolo 34
updateButtons();
}
}
Il metodo updateButtons()
Il metodo updateButtons() aggiorna lo stato di tutti i pulsanti del riquadro in
base allo stato del download selezionato. Il metodo updateButtons() mostrato
di seguito.
/* Aggiorna lo stato di ogni pulsante in base allo
stato del download selezionato. */
private void updateButtons() {
if (selectedDownload != null) {
int status = selectedDownload.getStatus();
switch (status) {
case Download.DOWNLOADING:
pauseButton.setEnabled(true);
resumeButton.setEnabled(false);
cancelButton.setEnabled(true);
clearButton.setEnabled(false);
break;
case Download.PAUSED:
pauseButton.setEnabled(false);
resumeButton.setEnabled(true);
cancelButton.setEnabled(true);
clearButton.setEnabled(false);
break;
case Download.ERROR:
pauseButton.setEnabled(false);
resumeButton.setEnabled(true);
cancelButton.setEnabled(false);
clearButton.setEnabled(true);
break;
default: // COMPLETE o CANCELLED
pauseButton.setEnabled(false);
resumeButton.setEnabled(false);
cancelButton.setEnabled(false);
clearButton.setEnabled(true);
}
2012, McGraw-Hill
} else {
// Nella tabella non selezionato alcun download.
pauseButton.setEnabled(false);
resumeButton.setEnabled(false);
cancelButton.setEnabled(false);
clearButton.setEnabled(false);
}
}
Se nella tabella dei download non selezionato alcun download, tutti i pulsanti vengono disattivati. Se selezionato un download, lo stato di ogni pulsante
viene impostato in base al fatto che loggetto Download abbia uno stato DOWNLOADING, PAUSED, ERROR, COMPLETE o CANCELLED.
Il Download Manager facile da utilizzare: immettere lURL di un file da scaricare nel campo di testo nella parte superiore dello schermo. Per esempio, per
scaricare un file dal nome 0072229713_code.zip dal sito web di McGraw-Hill immettere
http://www.mhprofessional.com/downloads/proucts/
0072229713/0072229713_code.zip
Si tratta del file contenente il codice per il libro dellautore The Art of Java,
scritto insieme a James Holmes.
2012, McGraw-Hill
PARTE IV
66 Capitolo 34
Dopo avere aggiunto un download al Download Manager, si pu gestire selezionandolo nella tabella. Dopo la selezione possibile fermare, annullare, riprendere ed eliminare un download. La Figura 34.2 mostra il Download Manager in
funzione.
2012, McGraw-Hill