<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://www.jexp.ru/index.php?action=history&amp;feed=atom&amp;title=Java%2FTiny_Application%2FDownload_Manager</id>
		<title>Java/Tiny Application/Download Manager - История изменений</title>
		<link rel="self" type="application/atom+xml" href="http://www.jexp.ru/index.php?action=history&amp;feed=atom&amp;title=Java%2FTiny_Application%2FDownload_Manager"/>
		<link rel="alternate" type="text/html" href="http://www.jexp.ru/index.php?title=Java/Tiny_Application/Download_Manager&amp;action=history"/>
		<updated>2026-04-21T21:57:43Z</updated>
		<subtitle>История изменений этой страницы в вики</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://www.jexp.ru/index.php?title=Java/Tiny_Application/Download_Manager&amp;diff=8841&amp;oldid=prev</id>
		<title>Admin: 1 версия</title>
		<link rel="alternate" type="text/html" href="http://www.jexp.ru/index.php?title=Java/Tiny_Application/Download_Manager&amp;diff=8841&amp;oldid=prev"/>
				<updated>2010-06-01T07:19:43Z</updated>
		
		<summary type="html">&lt;p&gt;1 версия&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr style=&quot;vertical-align: top;&quot; lang=&quot;ru&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;← Предыдущая&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;Версия 07:19, 1 июня 2010&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; style=&quot;text-align: center;&quot; lang=&quot;ru&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(нет различий)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>http://www.jexp.ru/index.php?title=Java/Tiny_Application/Download_Manager&amp;diff=8840&amp;oldid=prev</id>
		<title> в 18:01, 31 мая 2010</title>
		<link rel="alternate" type="text/html" href="http://www.jexp.ru/index.php?title=Java/Tiny_Application/Download_Manager&amp;diff=8840&amp;oldid=prev"/>
				<updated>2010-05-31T18:01:47Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== File Download Manager ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
  &amp;lt;!-- start source code --&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
import java.awt.BorderLayout;&lt;br /&gt;
import java.awt.ruponent;&lt;br /&gt;
import java.awt.event.ActionEvent;&lt;br /&gt;
import java.awt.event.ActionListener;&lt;br /&gt;
import java.awt.event.KeyEvent;&lt;br /&gt;
import java.awt.event.WindowAdapter;&lt;br /&gt;
import java.awt.event.WindowEvent;&lt;br /&gt;
import java.io.InputStream;&lt;br /&gt;
import java.io.RandomAccessFile;&lt;br /&gt;
import java.net.HttpURLConnection;&lt;br /&gt;
import java.net.URL;&lt;br /&gt;
import java.util.ArrayList;&lt;br /&gt;
import java.util.Observable;&lt;br /&gt;
import java.util.Observer;&lt;br /&gt;
import javax.swing.BorderFactory;&lt;br /&gt;
import javax.swing.JButton;&lt;br /&gt;
import javax.swing.JFrame;&lt;br /&gt;
import javax.swing.JMenu;&lt;br /&gt;
import javax.swing.JMenuBar;&lt;br /&gt;
import javax.swing.JMenuItem;&lt;br /&gt;
import javax.swing.JOptionPane;&lt;br /&gt;
import javax.swing.JPanel;&lt;br /&gt;
import javax.swing.JProgressBar;&lt;br /&gt;
import javax.swing.JScrollPane;&lt;br /&gt;
import javax.swing.JTable;&lt;br /&gt;
import javax.swing.JTextField;&lt;br /&gt;
import javax.swing.ListSelectionModel;&lt;br /&gt;
import javax.swing.event.ListSelectionEvent;&lt;br /&gt;
import javax.swing.event.ListSelectionListener;&lt;br /&gt;
import javax.swing.table.AbstractTableModel;&lt;br /&gt;
import javax.swing.table.TableCellRenderer;&lt;br /&gt;
public class DownloadManager extends JFrame implements Observer {&lt;br /&gt;
  private JTextField addTextField = new JTextField(30);&lt;br /&gt;
  private DownloadsTableModel tableModel = new DownloadsTableModel();&lt;br /&gt;
  private JTable table;&lt;br /&gt;
  private JButton pauseButton = new JButton(&amp;quot;Pause&amp;quot;);&lt;br /&gt;
  private JButton resumeButton = new JButton(&amp;quot;Resume&amp;quot;);&lt;br /&gt;
  private JButton cancelButton, clearButton;&lt;br /&gt;
  private Download selectedDownload;&lt;br /&gt;
  private boolean clearing;&lt;br /&gt;
  public DownloadManager() {&lt;br /&gt;
    setTitle(&amp;quot;Download Manager&amp;quot;);&lt;br /&gt;
    setSize(640, 480);&lt;br /&gt;
    addWindowListener(new WindowAdapter() {&lt;br /&gt;
      public void windowClosing(WindowEvent e) {&lt;br /&gt;
        System.exit(0);&lt;br /&gt;
      }&lt;br /&gt;
    });&lt;br /&gt;
    JMenuBar menuBar = new JMenuBar();&lt;br /&gt;
    JMenu fileMenu = new JMenu(&amp;quot;File&amp;quot;);&lt;br /&gt;
    fileMenu.setMnemonic(KeyEvent.VK_F);&lt;br /&gt;
    JMenuItem fileExitMenuItem = new JMenuItem(&amp;quot;Exit&amp;quot;, KeyEvent.VK_X);&lt;br /&gt;
    fileExitMenuItem.addActionListener(new ActionListener() {&lt;br /&gt;
      public void actionPerformed(ActionEvent e) {&lt;br /&gt;
        System.exit(0);&lt;br /&gt;
      }&lt;br /&gt;
    });&lt;br /&gt;
    fileMenu.add(fileExitMenuItem);&lt;br /&gt;
    menuBar.add(fileMenu);&lt;br /&gt;
    setJMenuBar(menuBar);&lt;br /&gt;
    // Set up add panel.&lt;br /&gt;
    JPanel addPanel = new JPanel();&lt;br /&gt;
    addPanel.add(addTextField);&lt;br /&gt;
    JButton addButton = new JButton(&amp;quot;Add Download&amp;quot;);&lt;br /&gt;
    addButton.addActionListener(new ActionListener() {&lt;br /&gt;
      public void actionPerformed(ActionEvent e) {&lt;br /&gt;
        actionAdd();&lt;br /&gt;
      }&lt;br /&gt;
    });&lt;br /&gt;
    addPanel.add(addButton);&lt;br /&gt;
    // Set up Downloads table.&lt;br /&gt;
    table = new JTable(tableModel);&lt;br /&gt;
    table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {&lt;br /&gt;
      public void valueChanged(ListSelectionEvent e) {&lt;br /&gt;
        tableSelectionChanged();&lt;br /&gt;
      }&lt;br /&gt;
    });&lt;br /&gt;
    table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);&lt;br /&gt;
    ProgressRenderer renderer = new ProgressRenderer(0, 100);&lt;br /&gt;
    renderer.setStringPainted(true); // show progress text&lt;br /&gt;
    table.setDefaultRenderer(JProgressBar.class, renderer);&lt;br /&gt;
    table.setRowHeight((int) renderer.getPreferredSize().getHeight());&lt;br /&gt;
    JPanel downloadsPanel = new JPanel();&lt;br /&gt;
    downloadsPanel.setBorder(BorderFactory.createTitledBorder(&amp;quot;Downloads&amp;quot;));&lt;br /&gt;
    downloadsPanel.setLayout(new BorderLayout());&lt;br /&gt;
    downloadsPanel.add(new JScrollPane(table), BorderLayout.CENTER);&lt;br /&gt;
    JPanel buttonsPanel = new JPanel();&lt;br /&gt;
    pauseButton.addActionListener(new ActionListener() {&lt;br /&gt;
      public void actionPerformed(ActionEvent e) {&lt;br /&gt;
        actionPause();&lt;br /&gt;
      }&lt;br /&gt;
    });&lt;br /&gt;
    pauseButton.setEnabled(false);&lt;br /&gt;
    buttonsPanel.add(pauseButton);&lt;br /&gt;
    resumeButton.addActionListener(new ActionListener() {&lt;br /&gt;
      public void actionPerformed(ActionEvent e) {&lt;br /&gt;
        actionResume();&lt;br /&gt;
      }&lt;br /&gt;
    });&lt;br /&gt;
    resumeButton.setEnabled(false);&lt;br /&gt;
    buttonsPanel.add(resumeButton);&lt;br /&gt;
    cancelButton = new JButton(&amp;quot;Cancel&amp;quot;);&lt;br /&gt;
    cancelButton.addActionListener(new ActionListener() {&lt;br /&gt;
      public void actionPerformed(ActionEvent e) {&lt;br /&gt;
        actionCancel();&lt;br /&gt;
      }&lt;br /&gt;
    });&lt;br /&gt;
    cancelButton.setEnabled(false);&lt;br /&gt;
    buttonsPanel.add(cancelButton);&lt;br /&gt;
    clearButton = new JButton(&amp;quot;Clear&amp;quot;);&lt;br /&gt;
    clearButton.addActionListener(new ActionListener() {&lt;br /&gt;
      public void actionPerformed(ActionEvent e) {&lt;br /&gt;
        actionClear();&lt;br /&gt;
      }&lt;br /&gt;
    });&lt;br /&gt;
    clearButton.setEnabled(false);&lt;br /&gt;
    buttonsPanel.add(clearButton);&lt;br /&gt;
    getContentPane().setLayout(new BorderLayout());&lt;br /&gt;
    getContentPane().add(addPanel, BorderLayout.NORTH);&lt;br /&gt;
    getContentPane().add(downloadsPanel, BorderLayout.CENTER);&lt;br /&gt;
    getContentPane().add(buttonsPanel, BorderLayout.SOUTH);&lt;br /&gt;
  }&lt;br /&gt;
  private void actionAdd() {&lt;br /&gt;
    URL verifiedUrl = verifyUrl(addTextField.getText());&lt;br /&gt;
    if (verifiedUrl != null) {&lt;br /&gt;
      tableModel.addDownload(new Download(verifiedUrl));&lt;br /&gt;
      addTextField.setText(&amp;quot;&amp;quot;); // reset add text field&lt;br /&gt;
    } else {&lt;br /&gt;
      JOptionPane.showMessageDialog(this, &amp;quot;Invalid Download URL&amp;quot;, &amp;quot;Error&amp;quot;,&lt;br /&gt;
          JOptionPane.ERROR_MESSAGE);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  private URL verifyUrl(String url) {&lt;br /&gt;
    if (!url.toLowerCase().startsWith(&amp;quot;http://&amp;quot;))&lt;br /&gt;
      return null;&lt;br /&gt;
    URL verifiedUrl = null;&lt;br /&gt;
    try {&lt;br /&gt;
      verifiedUrl = new URL(url);&lt;br /&gt;
    } catch (Exception e) {&lt;br /&gt;
      return null;&lt;br /&gt;
    }&lt;br /&gt;
    if (verifiedUrl.getFile().length() &amp;lt; 2)&lt;br /&gt;
      return null;&lt;br /&gt;
    return verifiedUrl;&lt;br /&gt;
  }&lt;br /&gt;
  private void tableSelectionChanged() {&lt;br /&gt;
    if (selectedDownload != null)&lt;br /&gt;
      selectedDownload.deleteObserver(DownloadManager.this);&lt;br /&gt;
    if (!clearing &amp;amp;&amp;amp; table.getSelectedRow() &amp;gt; -1) {&lt;br /&gt;
      selectedDownload = tableModel.getDownload(table.getSelectedRow());&lt;br /&gt;
      selectedDownload.addObserver(DownloadManager.this);&lt;br /&gt;
      updateButtons();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  private void actionPause() {&lt;br /&gt;
    selectedDownload.pause();&lt;br /&gt;
    updateButtons();&lt;br /&gt;
  }&lt;br /&gt;
  private void actionResume() {&lt;br /&gt;
    selectedDownload.resume();&lt;br /&gt;
    updateButtons();&lt;br /&gt;
  }&lt;br /&gt;
  private void actionCancel() {&lt;br /&gt;
    selectedDownload.cancel();&lt;br /&gt;
    updateButtons();&lt;br /&gt;
  }&lt;br /&gt;
  private void actionClear() {&lt;br /&gt;
    clearing = true;&lt;br /&gt;
    tableModel.clearDownload(table.getSelectedRow());&lt;br /&gt;
    clearing = false;&lt;br /&gt;
    selectedDownload = null;&lt;br /&gt;
    updateButtons();&lt;br /&gt;
  }&lt;br /&gt;
  private void updateButtons() {&lt;br /&gt;
    if (selectedDownload != null) {&lt;br /&gt;
      int status = selectedDownload.getStatus();&lt;br /&gt;
      switch (status) {&lt;br /&gt;
      case Download.DOWNLOADING:&lt;br /&gt;
        pauseButton.setEnabled(true);&lt;br /&gt;
        resumeButton.setEnabled(false);&lt;br /&gt;
        cancelButton.setEnabled(true);&lt;br /&gt;
        clearButton.setEnabled(false);&lt;br /&gt;
        break;&lt;br /&gt;
      case Download.PAUSED:&lt;br /&gt;
        pauseButton.setEnabled(false);&lt;br /&gt;
        resumeButton.setEnabled(true);&lt;br /&gt;
        cancelButton.setEnabled(true);&lt;br /&gt;
        clearButton.setEnabled(false);&lt;br /&gt;
        break;&lt;br /&gt;
      case Download.ERROR:&lt;br /&gt;
        pauseButton.setEnabled(false);&lt;br /&gt;
        resumeButton.setEnabled(true);&lt;br /&gt;
        cancelButton.setEnabled(false);&lt;br /&gt;
        clearButton.setEnabled(true);&lt;br /&gt;
        break;&lt;br /&gt;
      default: // COMPLETE or CANCELLED&lt;br /&gt;
        pauseButton.setEnabled(false);&lt;br /&gt;
        resumeButton.setEnabled(false);&lt;br /&gt;
        cancelButton.setEnabled(false);&lt;br /&gt;
        clearButton.setEnabled(true);&lt;br /&gt;
      }&lt;br /&gt;
    } else {&lt;br /&gt;
      pauseButton.setEnabled(false);&lt;br /&gt;
      resumeButton.setEnabled(false);&lt;br /&gt;
      cancelButton.setEnabled(false);&lt;br /&gt;
      clearButton.setEnabled(false);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  public void update(Observable o, Object arg) {&lt;br /&gt;
    // Update buttons if the selected download has changed.&lt;br /&gt;
    if (selectedDownload != null &amp;amp;&amp;amp; selectedDownload.equals(o))&lt;br /&gt;
      updateButtons();&lt;br /&gt;
  }&lt;br /&gt;
  // Run the Download Manager.&lt;br /&gt;
  public static void main(String[] args) {&lt;br /&gt;
    DownloadManager manager = new DownloadManager();&lt;br /&gt;
    manager.setVisible(true);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
class Download extends Observable implements Runnable {&lt;br /&gt;
  private static final int MAX_BUFFER_SIZE = 1024;&lt;br /&gt;
  public static final String STATUSES[] = { &amp;quot;Downloading&amp;quot;, &amp;quot;Paused&amp;quot;, &amp;quot;Complete&amp;quot;, &amp;quot;Cancelled&amp;quot;,&lt;br /&gt;
      &amp;quot;Error&amp;quot; };&lt;br /&gt;
  public static final int DOWNLOADING = 0;&lt;br /&gt;
  public static final int PAUSED = 1;&lt;br /&gt;
  public static final int COMPLETE = 2;&lt;br /&gt;
  public static final int CANCELLED = 3;&lt;br /&gt;
  public static final int ERROR = 4;&lt;br /&gt;
  private URL url; // download URL&lt;br /&gt;
  private int size; // size of download in bytes&lt;br /&gt;
  private int downloaded; // number of bytes downloaded&lt;br /&gt;
  private int status; // current status of download&lt;br /&gt;
  // Constructor for Download.&lt;br /&gt;
  public Download(URL url) {&lt;br /&gt;
    this.url = url;&lt;br /&gt;
    size = -1;&lt;br /&gt;
    downloaded = 0;&lt;br /&gt;
    status = DOWNLOADING;&lt;br /&gt;
    // Begin the download.&lt;br /&gt;
    download();&lt;br /&gt;
  }&lt;br /&gt;
  // Get this download&amp;quot;s URL.&lt;br /&gt;
  public String getUrl() {&lt;br /&gt;
    return url.toString();&lt;br /&gt;
  }&lt;br /&gt;
  // Get this download&amp;quot;s size.&lt;br /&gt;
  public int getSize() {&lt;br /&gt;
    return size;&lt;br /&gt;
  }&lt;br /&gt;
  // Get this download&amp;quot;s progress.&lt;br /&gt;
  public float getProgress() {&lt;br /&gt;
    return ((float) downloaded / size) * 100;&lt;br /&gt;
  }&lt;br /&gt;
  public int getStatus() {&lt;br /&gt;
    return status;&lt;br /&gt;
  }&lt;br /&gt;
  public void pause() {&lt;br /&gt;
    status = PAUSED;&lt;br /&gt;
    stateChanged();&lt;br /&gt;
  }&lt;br /&gt;
  public void resume() {&lt;br /&gt;
    status = DOWNLOADING;&lt;br /&gt;
    stateChanged();&lt;br /&gt;
    download();&lt;br /&gt;
  }&lt;br /&gt;
  public void cancel() {&lt;br /&gt;
    status = CANCELLED;&lt;br /&gt;
    stateChanged();&lt;br /&gt;
  }&lt;br /&gt;
  private void error() {&lt;br /&gt;
    status = ERROR;&lt;br /&gt;
    stateChanged();&lt;br /&gt;
  }&lt;br /&gt;
  private void download() {&lt;br /&gt;
    Thread thread = new Thread(this);&lt;br /&gt;
    thread.start();&lt;br /&gt;
  }&lt;br /&gt;
  // Get file name portion of URL.&lt;br /&gt;
  private String getFileName(URL url) {&lt;br /&gt;
    String fileName = url.getFile();&lt;br /&gt;
    return fileName.substring(fileName.lastIndexOf(&amp;quot;/&amp;quot;) + 1);&lt;br /&gt;
  }&lt;br /&gt;
  // Download file.&lt;br /&gt;
  public void run() {&lt;br /&gt;
    RandomAccessFile file = null;&lt;br /&gt;
    InputStream stream = null;&lt;br /&gt;
    try {&lt;br /&gt;
      // Open connection to URL.&lt;br /&gt;
      HttpURLConnection connection = (HttpURLConnection) url.openConnection();&lt;br /&gt;
      // Specify what portion of file to download.&lt;br /&gt;
      connection.setRequestProperty(&amp;quot;Range&amp;quot;, &amp;quot;bytes=&amp;quot; + downloaded + &amp;quot;-&amp;quot;);&lt;br /&gt;
      // Connect to server.&lt;br /&gt;
      connection.connect();&lt;br /&gt;
      // Make sure response code is in the 200 range.&lt;br /&gt;
      if (connection.getResponseCode() / 100 != 2) {&lt;br /&gt;
        error();&lt;br /&gt;
      }&lt;br /&gt;
      // Check for valid content length.&lt;br /&gt;
      int contentLength = connection.getContentLength();&lt;br /&gt;
      if (contentLength &amp;lt; 1) {&lt;br /&gt;
        error();&lt;br /&gt;
      }&lt;br /&gt;
      /*&lt;br /&gt;
       * Set the size for this download if it hasn&amp;quot;t been already set.&lt;br /&gt;
       */&lt;br /&gt;
      if (size == -1) {&lt;br /&gt;
        size = contentLength;&lt;br /&gt;
        stateChanged();&lt;br /&gt;
      }&lt;br /&gt;
      // Open file and seek to the end of it.&lt;br /&gt;
      file = new RandomAccessFile(getFileName(url), &amp;quot;rw&amp;quot;);&lt;br /&gt;
      file.seek(downloaded);&lt;br /&gt;
      stream = connection.getInputStream();&lt;br /&gt;
      while (status == DOWNLOADING) {&lt;br /&gt;
        /*&lt;br /&gt;
         * Size buffer according to how much of the file is left to download.&lt;br /&gt;
         */&lt;br /&gt;
        byte buffer[];&lt;br /&gt;
        if (size - downloaded &amp;gt; MAX_BUFFER_SIZE) {&lt;br /&gt;
          buffer = new byte[MAX_BUFFER_SIZE];&lt;br /&gt;
        } else {&lt;br /&gt;
          buffer = new byte[size - downloaded];&lt;br /&gt;
        }&lt;br /&gt;
        // Read from server into buffer.&lt;br /&gt;
        int read = stream.read(buffer);&lt;br /&gt;
        if (read == -1)&lt;br /&gt;
          break;&lt;br /&gt;
        // Write buffer to file.&lt;br /&gt;
        file.write(buffer, 0, read);&lt;br /&gt;
        downloaded += read;&lt;br /&gt;
        stateChanged();&lt;br /&gt;
      }&lt;br /&gt;
      /*&lt;br /&gt;
       * Change status to complete if this point was reached because downloading&lt;br /&gt;
       * has finished.&lt;br /&gt;
       */&lt;br /&gt;
      if (status == DOWNLOADING) {&lt;br /&gt;
        status = COMPLETE;&lt;br /&gt;
        stateChanged();&lt;br /&gt;
      }&lt;br /&gt;
    } catch (Exception e) {&lt;br /&gt;
      error();&lt;br /&gt;
    } finally {&lt;br /&gt;
      // Close file.&lt;br /&gt;
      if (file != null) {&lt;br /&gt;
        try {&lt;br /&gt;
          file.close();&lt;br /&gt;
        } catch (Exception e) {&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      // Close connection to server.&lt;br /&gt;
      if (stream != null) {&lt;br /&gt;
        try {&lt;br /&gt;
          stream.close();&lt;br /&gt;
        } catch (Exception e) {&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  private void stateChanged() {&lt;br /&gt;
    setChanged();&lt;br /&gt;
    notifyObservers();&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
class DownloadsTableModel extends AbstractTableModel implements Observer {&lt;br /&gt;
  private static final String[] columnNames = { &amp;quot;URL&amp;quot;, &amp;quot;Size&amp;quot;, &amp;quot;Progress&amp;quot;, &amp;quot;Status&amp;quot; };&lt;br /&gt;
  private static final Class[] columnClasses = { String.class, String.class, JProgressBar.class,&lt;br /&gt;
      String.class };&lt;br /&gt;
  private ArrayList&amp;lt;Download&amp;gt; downloadList = new ArrayList&amp;lt;Download&amp;gt;();&lt;br /&gt;
  public void addDownload(Download download) {&lt;br /&gt;
    download.addObserver(this);&lt;br /&gt;
    downloadList.add(download);&lt;br /&gt;
    fireTableRowsInserted(getRowCount() - 1, getRowCount() - 1);&lt;br /&gt;
  }&lt;br /&gt;
  public Download getDownload(int row) {&lt;br /&gt;
    return (Download) downloadList.get(row);&lt;br /&gt;
  }&lt;br /&gt;
  public void clearDownload(int row) {&lt;br /&gt;
    downloadList.remove(row);&lt;br /&gt;
    fireTableRowsDeleted(row, row);&lt;br /&gt;
  }&lt;br /&gt;
  public int getColumnCount() {&lt;br /&gt;
    return columnNames.length;&lt;br /&gt;
  }&lt;br /&gt;
  public String getColumnName(int col) {&lt;br /&gt;
    return columnNames[col];&lt;br /&gt;
  }&lt;br /&gt;
  public Class getColumnClass(int col) {&lt;br /&gt;
    return columnClasses[col];&lt;br /&gt;
  }&lt;br /&gt;
  public int getRowCount() {&lt;br /&gt;
    return downloadList.size();&lt;br /&gt;
  }&lt;br /&gt;
  public Object getValueAt(int row, int col) {&lt;br /&gt;
    Download download = downloadList.get(row);&lt;br /&gt;
    switch (col) {&lt;br /&gt;
    case 0: // URL&lt;br /&gt;
      return download.getUrl();&lt;br /&gt;
    case 1: // Size&lt;br /&gt;
      int size = download.getSize();&lt;br /&gt;
      return (size == -1) ? &amp;quot;&amp;quot; : Integer.toString(size);&lt;br /&gt;
    case 2: // Progress&lt;br /&gt;
      return new Float(download.getProgress());&lt;br /&gt;
    case 3: // Status&lt;br /&gt;
      return Download.STATUSES[download.getStatus()];&lt;br /&gt;
    }&lt;br /&gt;
    return &amp;quot;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
  public void update(Observable o, Object arg) {&lt;br /&gt;
    int index = downloadList.indexOf(o);&lt;br /&gt;
    fireTableRowsUpdated(index, index);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
class ProgressRenderer extends JProgressBar implements TableCellRenderer {&lt;br /&gt;
  public ProgressRenderer(int min, int max) {&lt;br /&gt;
    super(min, max);&lt;br /&gt;
  }&lt;br /&gt;
  public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,&lt;br /&gt;
      boolean hasFocus, int row, int column) {&lt;br /&gt;
    setValue((int) ((Float) value).floatValue());&lt;br /&gt;
    return this;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
           &lt;br /&gt;
       &amp;lt;/source&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
   &lt;br /&gt;
  &amp;lt;!-- end source code --&amp;gt;&lt;/div&gt;</summary>
			</entry>

	</feed>