Header Ads

test

Download Manager SOURCE CODE JAVA

  1: /**
  2:  * Download Manager
  3:  *
  7:  * Save-Listing1 as>Download.java, Listing 2 as>DownloadManager.java,
  8:    Listing 3 as>DownloadsTableModel.java,Listing 4
  9: as>ProgressRenderer.java.
 10:    Then Compile like>javac DownloadManager.java 
 11: DownloadsTableModel.java
 12:     ProgressRenderer.java Download.java & then
 13:     > javaw DownloadManager
 14:  */
 15: listing 1
 16: import java.io.*;
 17: import java.net.*;
 18: import java.util.*;
 19: 
 20: // This class downloads a file from a URL.
 21: class Download extends Observable implements Runnable {
 22:   // Max size of download buffer.
 23:   private static final int MAX_BUFFER_SIZE = 1024;
 24: 
 25:   // These are the status names.
 26:   public static final String STATUSES[] = {"Downloading",
 27:     "Paused", "Complete", "Cancelled", "Error"};
 28: 
 29:   // These are the status codes.
 30:   public static final int DOWNLOADING = 0;
 31:   public static final int PAUSED = 1;
 32:   public static final int COMPLETE = 2;
 33:   public static final int CANCELLED = 3;
 34:   public static final int ERROR = 4;
 35: 
 36:   private URL url; // download URL
 37:   private int size; // size of download in bytes
 38:   private int downloaded; // number of bytes downloaded
 39:   private int status; // current status of download
 40: 
 41:   // Constructor for Download.
 42:   public Download(URL url) {
 43:     this.url = url;
 44:     size = -1;
 45:     downloaded = 0;
 46:     status = DOWNLOADING;
 47: 
 48:     // Begin the download.
 49:     download();
 50:   }
 51: 
 52:   // Get this download's URL.
 53:   public String getUrl() {
 54:     return url.toString();
 55:   }
 56: 
 57:   // Get this download's size.
 58:   public int getSize() {
 59:     return size;
 60:   }
 61: 
 62:   // Get this download's progress.
 63:   public float getProgress() {
 64:     return ((float) downloaded / size) * 100;
 65:   }
 66: 
 67:   // Get this download's status.
 68:   public int getStatus() {
 69:     return status;
 70:   }
 71: 
 72:   // Pause this download.
 73:   public void pause() {
 74:     status = PAUSED;
 75:     stateChanged();
 76:   }
 77: 
 78:   // Resume this download.
 79:   public void resume() {
 80:     status = DOWNLOADING;
 81:     stateChanged();
 82:     download();
 83:   }
 84: 
 85:   // Cancel this download.
 86:   public void cancel() {
 87:     status = CANCELLED;
 88:     stateChanged();
 89:   }
 90: 
 91:   // Mark this download as having an error.
 92:   private void error() {
 93:     status = ERROR;
 94:     stateChanged();
 95:   }
 96: 
 97:   // Start or resume downloading.
 98:   private void download() {
 99:     Thread thread = new Thread(this);
100:     thread.start();
101:   }
102: 
103:   // Get file name portion of URL.
104:   private String getFileName(URL url) {
105:     String fileName = url.getFile();
106:     return fileName.substring(fileName.lastIndexOf('/') + 1);
107:   }
108: 
109:   // Download file.
110:   public void run() {
111:     RandomAccessFile file = null;
112:     InputStream stream = null;
113: 
114:     try {
115:       // Open connection to URL.
116:       HttpURLConnection connection =
117:         (HttpURLConnection) url.openConnection();
118: 
119:       // Specify what portion of file to download.
120:       connection.setRequestProperty("Range",
121:         "bytes=" + downloaded + "-");
122: 
123:       // Connect to server.
124:       connection.connect();
125: 
126:       // Make sure response code is in the 200 range.
127:       if (connection.getResponseCode() / 100 != 2) {
128:         error();
129:       }
130: 
131:       // Check for valid content length.
132:       int contentLength = connection.getContentLength();
133:       if (contentLength < 1) {
134:         error();
135:       }
136: 
137:       /* Set the size for this download if it
138:          hasn't been already set. */
139:       if (size == -1) {
140:         size = contentLength;
141:         stateChanged();
142:       }
143: 
144:       // Open file and seek to the end of it.
145:       file = new RandomAccessFile(getFileName(url), "rw");
146:       file.seek(downloaded);
147: 
148:       stream = connection.getInputStream();
149:       while (status == DOWNLOADING) {
150:         /* Size buffer according to how much of the
151:            file is left to download. */
152:         byte buffer[];
153:         if (size - downloaded > MAX_BUFFER_SIZE) {
154:           buffer = new byte[MAX_BUFFER_SIZE];
155:         } else {
156:           buffer = new byte[size - downloaded];
157:         }
158: 
159:         // Read from server into buffer.
160:         int read = stream.read(buffer);
161:         if (read == -1)
162:           break;
163: 
164:         // Write buffer to file.
165:         file.write(buffer, 0, read);
166:         downloaded += read;
167:         stateChanged();
168:       }
169: 
170:       /* Change status to complete if this point was
171:          reached because downloading has finished. */
172:       if (status == DOWNLOADING) {
173:         status = COMPLETE;
174:         stateChanged();
175:       }
176:     } catch (Exception e) {
177:       error();
178:     } finally {
179:       // Close file.
180:       if (file != null) {
181:         try {
182:           file.close();
183:         } catch (Exception e) {}
184:       }
185: 
186:       // Close connection to server.
187:       if (stream != null) {
188:         try {
189:           stream.close();
190:         } catch (Exception e) {}
191:       }
192:     }
193:   }
194: 
195:   // Notify observers that this download's status has changed.
196:   private void stateChanged() {
197:     setChanged();
198:     notifyObservers();
199:   }
200: }
201: 
202: listing 2
203: import java.awt.*;
204: import java.awt.event.*;
205: import java.net.*;
206: import java.util.*;
207: import javax.swing.*;
208: import javax.swing.event.*;
209: 
210: // The Download Manager.
211: public class DownloadManager extends JFrame
212:   implements Observer
213: {
214:   // Add download text field.
215:   private JTextField addTextField;
216: 
217:   // Download table's data model.
218:   private DownloadsTableModel tableModel;
219: 
220:   // Table showing downloads.
221:   private JTable table;
222: 
223:   // These are the buttons for managing the selected download.
224:   private JButton pauseButton, resumeButton;
225:   private JButton cancelButton, clearButton;
226: 
227:   // Currently selected download.
228:   private Download selectedDownload;
229: 
230:   // Flag for whether or not table selection is being cleared.
231:   private boolean clearing;
232: 
233:   // Constructor for Download Manager.
234:   public DownloadManager()
235:   {
236:     // Set application title.
237:     setTitle("Download Manager");
238: 
239:     // Set window size.
240:     setSize(640, 480);
241: 
242:     // Handle window closing events.
243:     addWindowListener(new WindowAdapter() {
244:       public void windowClosing(WindowEvent e) {
245:         actionExit();
246:       }
247:     });
248: 
249:     // Set up file menu.
250:     JMenuBar menuBar = new JMenuBar();
251:     JMenu fileMenu = new JMenu("File");
252:     fileMenu.setMnemonic(KeyEvent.VK_F);
253:     JMenuItem fileExitMenuItem = new JMenuItem("Exit",
254:       KeyEvent.VK_X);
255:     fileExitMenuItem.addActionListener(new ActionListener() {
256:       public void actionPerformed(ActionEvent e) {
257:         actionExit();
258:       }
259:     });
260:     fileMenu.add(fileExitMenuItem);
261:     menuBar.add(fileMenu);
262:     setJMenuBar(menuBar);
263: 
264:     // Set up add panel.
265:     JPanel addPanel = new JPanel();
266:     addTextField = new JTextField(30);
267:     addPanel.add(addTextField);
268:     JButton addButton = new JButton("Add Download");
269:     addButton.addActionListener(new ActionListener() {
270:       public void actionPerformed(ActionEvent e) {
271:         actionAdd();
272:       }
273:     });
274:     addPanel.add(addButton);
275: 
276:     // Set up Downloads table.
277:     tableModel = new DownloadsTableModel();
278:     table = new JTable(tableModel);
279:     table.getSelectionModel().addListSelectionListener(new
280:       ListSelectionListener() {
281:       public void valueChanged(ListSelectionEvent e) {
282:         tableSelectionChanged();
283:       }
284:     });
285:     // Allow only one row at a time to be selected.
286:     table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
287: 
288:     // Set up ProgressBar as renderer for progress column.
289:     ProgressRenderer renderer = new ProgressRenderer(0, 100);
290:     renderer.setStringPainted(true); // show progress text
291:     table.setDefaultRenderer(JProgressBar.class, renderer);
292: 
293:     // Set table's row height large enough to fit JProgressBar.
294:     table.setRowHeight(
295:       (int) renderer.getPreferredSize().getHeight());
296: 
297:     // Set up downloads panel.
298:     JPanel downloadsPanel = new JPanel();
299:     downloadsPanel.setBorder(
300:       BorderFactory.createTitledBorder("Downloads"));
301:     downloadsPanel.setLayout(new BorderLayout());
302:     downloadsPanel.add(new JScrollPane(table),
303:       BorderLayout.CENTER);
304: 
305:     // Set up buttons panel.
306:     JPanel buttonsPanel = new JPanel();
307:     pauseButton = new JButton("Pause");
308:     pauseButton.addActionListener(new ActionListener() {
309:       public void actionPerformed(ActionEvent e) {
310:         actionPause();
311:       }
312:     });
313:     pauseButton.setEnabled(false);
314:     buttonsPanel.add(pauseButton);
315:     resumeButton = new JButton("Resume");
316:     resumeButton.addActionListener(new ActionListener() {
317:       public void actionPerformed(ActionEvent e) {
318:         actionResume();
319:       }
320:     });
321:     resumeButton.setEnabled(false);
322:     buttonsPanel.add(resumeButton);
323:     cancelButton = new JButton("Cancel");
324:     cancelButton.addActionListener(new ActionListener() {
325:       public void actionPerformed(ActionEvent e) {
326:         actionCancel();
327:       }
328:     });
329:     cancelButton.setEnabled(false);
330:     buttonsPanel.add(cancelButton);
331:     clearButton = new JButton("Clear");
332:     clearButton.addActionListener(new ActionListener() {
333:       public void actionPerformed(ActionEvent e) {
334:         actionClear();
335:       }
336:     });
337:     clearButton.setEnabled(false);
338:     buttonsPanel.add(clearButton);
339: 
340:     // Add panels to display.
341:     getContentPane().setLayout(new BorderLayout());
342:     getContentPane().add(addPanel, BorderLayout.NORTH);
343:     getContentPane().add(downloadsPanel, BorderLayout.CENTER);
344:     getContentPane().add(buttonsPanel, BorderLayout.SOUTH);
345:   }
346: 
347:   // Exit this program.
348:   private void actionExit() {
349:     System.exit(0);
350:   }
351: 
352:   // Add a new download.
353:   private void actionAdd() {
354:     URL verifiedUrl = verifyUrl(addTextField.getText());
355:     if (verifiedUrl != null) {
356:       tableModel.addDownload(new Download(verifiedUrl));
357:       addTextField.setText(""); // reset add text field
358:     } else {
359:       JOptionPane.showMessageDialog(this,
360:         "Invalid Download URL", "Error",
361:         JOptionPane.ERROR_MESSAGE);
362:     }
363:   }
364: 
365:   // Verify download URL.
366:   private URL verifyUrl(String url) {
367:     // Only allow HTTP URLs.
368:     if (!url.toLowerCase().startsWith("http://"))
369:       return null;
370: 
371:     // Verify format of URL.
372:     URL verifiedUrl = null;
373:     try {
374:       verifiedUrl = new URL(url);
375:     } catch (Exception e) {
376:       return null;
377:     }
378: 
379:     // Make sure URL specifies a file.
380:     if (verifiedUrl.getFile().length() < 2)
381:       return null;
382: 
383:     return verifiedUrl;
384:   }
385: 
386:   // Called when table row selection changes.
387:   private void tableSelectionChanged() {
388:     /* Unregister from receiving notifications
389:        from the last selected download. */
390:     if (selectedDownload != null)
391:       selectedDownload.deleteObserver(DownloadManager.this);
392: 
393:     /* If not in the middle of clearing a download,
394:        set the selected download and register to
395:        receive notifications from it. */
396:     if (!clearing && table.getSelectedRow() > -1) {
397:       selectedDownload =
398:         tableModel.getDownload(table.getSelectedRow());
399:       selectedDownload.addObserver(DownloadManager.this);
400:       updateButtons();
401:     }
402:   }
403: 
404:   // Pause the selected download.
405:   private void actionPause() {
406:     selectedDownload.pause();
407:     updateButtons();
408:   }
409: 
410:   // Resume the selected download.
411:   private void actionResume() {
412:     selectedDownload.resume();
413:     updateButtons();
414:   }
415: 
416:   // Cancel the selected download.
417:   private void actionCancel() {
418:     selectedDownload.cancel();
419:     updateButtons();
420:   }
421: 
422:   // Clear the selected download.
423:   private void actionClear() {
424:     clearing = true;
425:     tableModel.clearDownload(table.getSelectedRow());
426:     clearing = false;
427:     selectedDownload = null;
428:     updateButtons();
429:   }
430: 
431:   /* Update each button's state based off of the
432:      currently selected download's status. */
433:   private void updateButtons() {
434:     if (selectedDownload != null) {
435:       int status = selectedDownload.getStatus();
436:       switch (status) {
437:         case Download.DOWNLOADING:
438:           pauseButton.setEnabled(true);
439:           resumeButton.setEnabled(false);
440:           cancelButton.setEnabled(true);
441:           clearButton.setEnabled(false);
442:           break;
443:         case Download.PAUSED:
444:           pauseButton.setEnabled(false);
445:           resumeButton.setEnabled(true);
446:           cancelButton.setEnabled(true);
447:           clearButton.setEnabled(false);
448:           break;
449:         case Download.ERROR:
450:           pauseButton.setEnabled(false);
451:           resumeButton.setEnabled(true);
452:           cancelButton.setEnabled(false);
453:           clearButton.setEnabled(true);
454:           break;
455:         default: // COMPLETE or CANCELLED
456:           pauseButton.setEnabled(false);
457:           resumeButton.setEnabled(false);
458:           cancelButton.setEnabled(false);
459:           clearButton.setEnabled(true);
460:       }
461:     } else {
462:       // No download is selected in table.
463:       pauseButton.setEnabled(false);
464:       resumeButton.setEnabled(false);
465:       cancelButton.setEnabled(false);
466:       clearButton.setEnabled(false);
467:     }
468:   }
469: 
470:   /* Update is called when a Download notifies its
471:      observers of any changes. */
472:   public void update(Observable o, Object arg) {
473:     // Update buttons if the selected download has changed.
474:     if (selectedDownload != null && selectedDownload.equals(o))
475:       updateButtons();
476:   }
477: 
478:   // Run the Download Manager.
479:   public static void main(String[] args) {
480:     DownloadManager manager = new DownloadManager();
481:     manager.setVisible(true);
482:   }
483: }
484: 
485: listing 3
486: import java.util.*;
487: import javax.swing.*;
488: import javax.swing.table.*;
489: 
490: // This class manages the download table's data.
491: class DownloadsTableModel extends AbstractTableModel
492:   implements Observer
493: {
494:   // These are the names for the table's columns.
495:   private static final String[] columnNames = {"URL", "Size",
496:     "Progress", "Status"};
497: 
498:   // These are the classes for each column's values.
499:   private static final Class[] columnClasses = {String.class,
500:     String.class, JProgressBar.class, String.class};
501: 
502:   // The table's list of downloads.
503:   private ArrayList<Download> downloadList =
504:              new ArrayList<Download>();
505: 
506:   // Add a new download to the table.
507:   public void addDownload(Download download) {
508:     // Register to be notified when the download changes.
509:     download.addObserver(this);
510: 
511:     downloadList.add(download);
512: 
513:     // Fire table row insertion notification to table.
514:     fireTableRowsInserted(getRowCount() - 1, getRowCount() - 1);
515:   }
516: 
517:   // Get a download for the specified row.
518:   public Download getDownload(int row) {
519:     return (Download) downloadList.get(row);
520:   }
521: 
522:   // Remove a download from the list.
523:   public void clearDownload(int row) {
524:     downloadList.remove(row);
525: 
526:     // Fire table row deletion notification to table.
527:     fireTableRowsDeleted(row, row);
528:   }
529: 
530:   // Get table's column count.
531:   public int getColumnCount() {
532:     return columnNames.length;
533:   }
534: 
535:   // Get a column's name.
536:   public String getColumnName(int col) {
537:      return columnNames[col];
538:   }
539: 
540:   // Get a column's class.
541:   public Class getColumnClass(int col) {
542:     return columnClasses[col];
543:   }
544: 
545:   // Get table's row count.
546:   public int getRowCount() {
547:     return downloadList.size();
548:   }
549: 
550:   // Get value for a specific row and column combination.
551:   public Object getValueAt(int row, int col) {
552:     Download download = downloadList.get(row);
553:     switch (col) {
554:       case 0: // URL
555:         return download.getUrl();
556:       case 1: // Size
557:         int size = download.getSize();
558:         return (size == -1) ? "" : Integer.toString(size);
559:       case 2: // Progress
560:         return new Float(download.getProgress());
561:       case 3: // Status
562:         return Download.STATUSES[download.getStatus()];
563:     }
564:     return "";
565:   }
566: 
567:   /* Update is called when a Download notifies its
568:      observers of any changes */
569:   public void update(Observable o, Object arg) {
570:     int index = downloadList.indexOf(o);
571: 
572:     // Fire table row update notification to table.
573:     fireTableRowsUpdated(index, index);
574:   }
575: }
576: 
577: listing 4
578: import java.awt.*;
579: import javax.swing.*;
580: import javax.swing.table.*;
581: 
582: // This class renders a JProgressBar in a table cell.
583: class ProgressRenderer extends JProgressBar
584:   implements TableCellRenderer
585: {
586:   // Constructor for ProgressRenderer.
587:   public ProgressRenderer(int min, int max) {
588:     super(min, max);
589:   }
590: 
591:   /* Returns this JProgressBar as the renderer
592:      for the given table cell. */
593:   public Component getTableCellRendererComponent(
594:     JTable table, Object value, boolean isSelected,
595:     boolean hasFocus, int row, int column)
596:   {
597:     // Set JProgressBar's percent complete value.
598:     setValue((int) ((Float) value).floatValue());
599:     return this;
600:   }
601: }

No comments

please write your mail id for contact: