TheDownloadclass has numerous action and accessor methods for controlling a download and getting data from it. Each of thepause( ),resume( ), andcancel( )action methods simply does as its name implies: pauses, resumes, or cancels the download, respectively. Similarly, theerror( )method marks the download as having an error. ThegetUrl( ),
getSize( ),getProgress( ), andgetStatus( )accessor methods each return their current respective values.
The ProgressRenderer Class
TheProgressRendererclass is a small utility class that is used to render the current progress of a download listed in the GUI’s “Downloads”JTableinstance. Normally, aJTableinstance renders each of its table cell’s data as text. However, often it’s particularly useful to render a cell’s data as something other than text. In the Download Manager’s case, we want to render each of the table’s Progress column cells as progress bars. TheProgressRendererclass shown here makes that possible. Notice that it extendsJProgressBarand implements
TableCellRenderer:
import java.awt.*; import javax.swing.*; import javax.swing.table.*;
// This class renders a JProgressBar in a table cell. class ProgressRenderer extends JProgressBar
implements TableCellRenderer {
// Constructor for ProgressRenderer.
public ProgressRenderer(int min, int max) { super(min, max);
}
/* Returns this JProgressBar as the renderer for the given table cell. */
public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected,
C h a p t e r 4 : C r e a t i n g a D o w n l o a d M a n a g e r i n J a v a
1 0 3
AppDev TIGHT/ The Art of Java / Schildt/Holmes / 222971-3 / Chapter 4
P:\010Comp\ApDev\971-3\ch04.vp Monday, July 07, 2003 10:03:35 AM
Color profile: Generic CMYK printer profile Composite Default screen
boolean hasFocus, int row, int column) {
// Set JProgressBar's percent complete value. setValue((int) ((Float) value).floatValue()); return this;
} }
TheProgressRendererclass takes advantage of the fact that Swing’sJTableclass has a rendering system that can accept “plug-ins” for rendering table cells. To plug into this rendering system, first, theProgressRendererclass has to implement Swing’s
TableCellRendererinterface. Second, aProgressRendererinstance has to be registered with aJTableinstance; doing so instructs theJTableinstance as to which cells should be rendered with the “plug-in.”
Implementing theTableCellRendererinterface requires the class to override the
getTableCellRendererComponent( )method. ThegetTableCellRendererComponent( )
method is invoked each time aJTableinstance goes to render a cell for which this class has been registered. This method is passed several variables, but in this case only thevalue
variable is used. Thevaluevariable holds the data for the cell being rendered and is passed toJProgressBar’ssetValue( )method. ThegetTableCellRendererComponent( )method wraps up by returning a reference to its class. This works because theProgressRenderer
class is a subclass ofJProgessbar, which is a descendent of the AWTComponentclass.
The DownloadsTableModel Class
TheDownloadsTableModelclass houses the Download Manager’s list of downloads and is the backing data source for the GUI’s “Downloads”JTableinstance.
TheDownloadsTableModelclass is shown here. Notice that it extendsAbstractTableModel
and implements theObserverinterface:
import java.util.*; import javax.swing.*; import javax.swing.table.*;
// This class manages the download table's data. class DownloadsTableModel extends AbstractTableModel
implements Observer {
// These are the names for the table's columns.
private static final String[] columnNames = {"URL", "Size", "Progress", "Status"};
// These are the classes for each column's values.
private static final Class[] columnClasses = {String.class, String.class, JProgressBar.class, String.class};
// The table's list of downloads.
private ArrayList downloadList = new ArrayList();
// Add a new download to the table.
public void addDownload(Download download) {
// Register to be notified when the download changes. download.addObserver(this);
downloadList.add(download);
// Fire table row insertion notification to table.
fireTableRowsInserted(getRowCount() - 1, getRowCount() - 1); }
// Get a download for the specified row. public Download getDownload(int row) {
return (Download) downloadList.get(row); }
// Remove a download from the list. public void clearDownload(int row) {
downloadList.remove(row);
// Fire table row deletion notification to table. fireTableRowsDeleted(row, row);
}
// Get table's column count. public int getColumnCount() {
return columnNames.length; }
// Get a column's name.
public String getColumnName(int col) { return columnNames[col];
}
// Get a column's class.
public Class getColumnClass(int col) { return columnClasses[col];
}
// Get table's row count. public int getRowCount() {
return downloadList.size();
C h a p t e r 4 : C r e a t i n g a D o w n l o a d M a n a g e r i n J a v a
1 0 5
AppDev TIGHT/ The Art of Java / Schildt/Holmes / 222971-3 / Chapter 4
P:\010Comp\ApDev\971-3\ch04.vp Monday, July 07, 2003 10:03:35 AM
Color profile: Generic CMYK printer profile Composite Default screen
}
// Get value for a specific row and column combination. public Object getValueAt(int row, int col) {
Download download = (Download) downloadList.get(row); switch (col) {
case 0: // URL
return download.getUrl(); case 1: // Size
int size = download.getSize();
return (size == -1) ? "" : Integer.toString(size); case 2: // Progress
return new Float(download.getProgress()); case 3: // Status
return Download.STATUSES[download.getStatus()]; }
return ""; }
/* Update is called when a Download notifies its observers of any changes */
public void update(Observable o, Object arg) { int index = downloadList.indexOf(o);
// Fire table row update notification to table. fireTableRowsUpdated(index, index);
} }
TheDownloadsTableModelclass essentially is a utility class utilized by the “Downloads”
JTableinstance for managing data in the table. When theJTableinstance is initialized, it is passed aDownloadsTableModelinstance. TheJTablethen proceeds to call several methods on theDownloadsTableModelinstance to populate itself. ThegetColumnCount( )method is called to retrieve the number of columns in the table. Similarly,getRowCount( )is used to retrieve the number of rows in the table. ThegetColumnName( )method returns a column’s name given its ID. ThegetDownload( )method takes a row ID and returns the associated
Downloadobject from the list. The rest of theDownloadsTableModelclass’ methods, which are more involved, are detailed in the following sections.