1: /**
2: * Download Manager3: *6: *7: * Save-Listing1 as>Download.java, Listing 2 as>DownloadManager.java,8: Listing 3 as>DownloadsTableModel.java,Listing 49: as>ProgressRenderer.java.10: Then Compile like>javac DownloadManager.java11: DownloadsTableModel.java12: ProgressRenderer.java Download.java & then13: > javaw DownloadManager14: */15: listing 116: 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 URL37: private int size; // size of download in bytes38: private int downloaded; // number of bytes downloaded39: private int status; // current status of download40: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 2203: 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 JFrame212: implements Observer213: {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(new280: 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 text291: 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 field358: } 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 to395: 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 CANCELLED456: 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 3486: 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 AbstractTableModel492: implements Observer493: {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: // URL555: return download.getUrl();556: case 1: // Size557: int size = download.getSize();558: return (size == -1) ? "" : Integer.toString(size);559: case 2: // Progress560: return new Float(download.getProgress());561: case 3: // Status562: 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 4578: 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 JProgressBar584: implements TableCellRenderer585: {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: }
Tuesday, December 15, 2009
DOWNLOAD MANAGER SOURCE CODE
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment
please write your mail id for contact: