package org.limewire.ui.swing.upload.table; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Font; import java.awt.event.ActionEvent; import java.lang.ref.WeakReference; import java.text.DecimalFormat; import java.text.NumberFormat; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JTable; import javax.swing.SwingConstants; import net.miginfocom.swing.MigLayout; import org.jdesktop.application.Resource; import org.jdesktop.swingx.JXHyperlink; import org.limewire.core.api.upload.UploadErrorState; import org.limewire.core.api.upload.UploadItem; import org.limewire.core.api.upload.UploadState; import org.limewire.core.api.upload.UploadItem.BrowseType; import org.limewire.core.api.upload.UploadItem.UploadItemType; import org.limewire.ui.swing.components.IconButton; import org.limewire.ui.swing.components.LimeProgressBar; import org.limewire.ui.swing.components.RemoteHostWidget; import org.limewire.ui.swing.components.RemoteHostWidgetFactory; import org.limewire.ui.swing.components.RemoteHostWidget.RemoteWidgetType; import org.limewire.ui.swing.components.decorators.ProgressBarDecorator; import org.limewire.ui.swing.table.TableRendererEditor; import org.limewire.ui.swing.util.CategoryIconManager; import org.limewire.ui.swing.util.GuiUtils; import org.limewire.ui.swing.util.I18n; import org.limewire.util.CommonUtils; import com.google.inject.Inject; public class UploadTableRendererEditor extends TableRendererEditor { private NumberFormat formatter = new DecimalFormat("0.00"); private CategoryIconManager categoryIconManager; private JLabel statusLabel; private JLabel nameLabel; private JLabel iconLabel; private RemoteHostWidget browseNameLabel; private JButton cancelButton; private JXHyperlink removeLink; private WeakReference<UploadItem> editItemReference; private LimeProgressBar progressBar; private JLabel timeLabel; @Resource private Color linkColor; @Resource private Font statusFont; @Resource private Font titleFont; @Resource private Icon cancelIcon; @Resource private Icon cancelIconRollover; @Resource private Icon cancelIconPressed; @Resource private Icon friendBrowseHostIcon; @Resource private Icon p2pBrowseHostIcon; @Inject public UploadTableRendererEditor(CategoryIconManager categoryIconManager, ProgressBarDecorator progressBarFactory, RemoteHostWidgetFactory remoteHostWidgetFactory){ GuiUtils.assignResources(this); setLayout(new MigLayout("fill, insets 0 0 0 0 , gap 0, novisualpadding")); this.categoryIconManager = categoryIconManager; initializeComponents(progressBarFactory, remoteHostWidgetFactory); addComponents(); } public void setActionHandler(final UploadActionHandler actionHandler){ cancelButton.setActionCommand(UploadActionHandler.CANCEL_COMMAND); Action cancelAction = new AbstractAction(I18n.tr("Cancel")) { @Override public void actionPerformed(ActionEvent e) { actionHandler.performAction(cancelButton.getActionCommand(), editItemReference.get()); cancelCellEditing(); } }; cancelButton.addActionListener(cancelAction); removeLink.setActionCommand(UploadActionHandler.REMOVE_COMMAND); Action removeAction = new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { actionHandler.performAction(removeLink.getActionCommand(), editItemReference.get()); cancelCellEditing(); } }; removeLink.addActionListener(removeAction); } @Override public Component doTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if(value instanceof UploadItem) { update((UploadItem)value); return this; } else { return emptyPanel; } } @Override public Component doTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { if(value instanceof UploadItem) { editItemReference = new WeakReference<UploadItem>((UploadItem)value); update(editItemReference.get()); return this; } else { return emptyPanel; } } private void initializeComponents(ProgressBarDecorator progressBarDecorator, RemoteHostWidgetFactory remoteHostWidgetFactory){ //string parameter ensures proper sizing nameLabel = new JLabel("NAME"); nameLabel.setFont(titleFont); iconLabel = new JLabel(); //string parameter ensures proper sizing statusLabel = new JLabel(I18n.tr("Status")); statusLabel.setFont(statusFont); browseNameLabel = remoteHostWidgetFactory.create(RemoteWidgetType.UPLOAD); cancelButton = new IconButton(cancelIcon, cancelIconRollover, cancelIconPressed); removeLink = new JXHyperlink(); removeLink.setText("<HTML><U>" + I18n.tr("Remove") + "</U></HTML>"); removeLink.setForeground(linkColor); removeLink.setClickedColor(linkColor); removeLink.setFont(statusFont); //string parameter ensures proper sizing timeLabel = new JLabel("TIME"); timeLabel.setHorizontalAlignment(SwingConstants.RIGHT); progressBar = new LimeProgressBar(); progressBarDecorator.decoratePlain(progressBar); Dimension size = new Dimension(400, 16); progressBar.setPreferredSize(size); progressBar.setMinimumSize(size); progressBar.setMaximumSize(size); setOpaque(false); } private void addComponents() { add(iconLabel, "gapleft 10, alignx left, aligny 50%, spany 3, hidemode 3"); add(nameLabel, "gapleft 10, gaptop 5, aligny bottom, hidemode 2"); add(cancelButton, "gapright 10, alignx right, aligny 50%, spany 3, push, wrap"); add(progressBar, "gapleft 10, , gaptop 2, hidemode 3, wrap"); add(browseNameLabel, "split 4, gapleft 10, gapbottom 5, gaptop 2, aligny top"); add(statusLabel, "gapleft 10, gapbottom 5, gaptop 2, alignx left, aligny top"); add(timeLabel, "push, gaptop 2, gapbottom 5, aligny top, alignx right, hidemode 1"); add(removeLink, "push, gaptop 2, gapbottom 5, aligny top, alignx right, hidemode 1"); } private void update(UploadItem item){ if (item == null) { return; } nameLabel.setVisible(!isBrowseHost(item)); if (nameLabel.isVisible()) { nameLabel.setText(item.getFileName()); } if(item.getUploadItemType() == UploadItemType.GNUTELLA) { browseNameLabel.setVisible(true); browseNameLabel.setPerson(item.getRemoteHost()); } else { browseNameLabel.setVisible(false); } statusLabel.setText(getMessage(item)); if (UploadItemType.GNUTELLA == item.getUploadItemType()) { progressBar.setVisible(item.getState() == UploadState.UPLOADING); if (progressBar.isVisible()) { progressBar.setValue((int) (100 * item.getTotalAmountUploaded() / item .getFileSize())); } timeLabel.setVisible(item.getState() == UploadState.UPLOADING); if (timeLabel.isVisible()) { timeLabel.setText(CommonUtils.seconds2time(item.getRemainingUploadTime())); } } else { progressBar.setVisible(false); timeLabel.setVisible(false); } if (item.getState() == UploadState.UPLOADING) { nameLabel.setIcon(categoryIconManager.getIcon(item.getCategory())); iconLabel.setVisible(false); } else { nameLabel.setIcon(null); if (isBrowseHost(item)) { if (item.getBrowseType() == BrowseType.FRIEND) { iconLabel.setIcon(friendBrowseHostIcon); } else { iconLabel.setIcon(p2pBrowseHostIcon); } } else { iconLabel.setIcon(categoryIconManager.getIcon(item.getCategory())); } iconLabel.setVisible(true); } removeLink.setVisible(item.getState() == UploadState.UNABLE_TO_UPLOAD); if(item.getState() == UploadState.DONE || isBrowseHost(item)){ cancelButton.setActionCommand(UploadActionHandler.REMOVE_COMMAND); } else { cancelButton.setActionCommand(UploadActionHandler.CANCEL_COMMAND); } } private boolean isBrowseHost(UploadItem item){ return item.getState() == UploadState.BROWSE_HOST || item.getState() == UploadState.BROWSE_HOST_DONE; } private String getMessage(UploadItem item){ switch (item.getState()){ case BROWSE_HOST: case BROWSE_HOST_DONE: return I18n.tr("Library was browsed"); case DONE: return I18n.tr("Done uploading"); case UPLOADING: if(UploadItemType.BITTORRENT == item.getUploadItemType()) { int numConnections = item.getNumUploadConnections(); String ratio = formatter.format(item.getSeedRatio()); if(numConnections == 1) { return I18n.tr("Connected to {0} P2P user, uploading at {1} - Ratio {2}", numConnections, GuiUtils.rate2speed(item.getUploadSpeed()), ratio); } else { return I18n.tr("Connected to {0} P2P users, uploading at {1} - Ratio {2}", numConnections, GuiUtils.rate2speed(item.getUploadSpeed()), ratio); } } else { return I18n.tr("Uploading - {0} of {1}({2})", GuiUtils.toUnitbytes(item.getTotalAmountUploaded()), GuiUtils.toUnitbytes(item.getFileSize()), GuiUtils.rate2speed(item.getUploadSpeed())); } case WAITING: case QUEUED: return I18n.tr("Waiting..."); case UNABLE_TO_UPLOAD: return getErrorMessage(item.getErrorState()); } return null; } private String getErrorMessage(UploadErrorState errorState){ switch(errorState){ case FILE_ERROR: return I18n.tr("Unable to upload: file error"); case INTERRUPTED: return I18n.tr("Unable to upload: transfer interrupted"); case LIMIT_REACHED: return I18n.tr("Unable to upload: upload limit reached"); } return null; } }