// // $Id: JUploadPanelImpl.java 303 2007-07-21 07:42:51 +0000 (sam., 21 juil. // 2007) // etienne_sf $ // // jupload - A file upload applet. // Copyright 2007 The JUpload Team // // Created: ? // Creator: William JinHua Kwong // Last modified: $Date: 2010-05-14 11:09:27 -0300 (Sex, 14 Mai 2010) $ // // This program is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) any later // version. This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more // details. You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software Foundation, Inc., // 675 Mass Ave, Cambridge, MA 02139, USA. package wjhk.jupload2.gui; import java.awt.Frame; import java.awt.Point; import java.awt.dnd.DnDConstants; import java.awt.dnd.DropTarget; import java.awt.dnd.DropTargetDropEvent; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.InputEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.Action; import javax.swing.ActionMap; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.JScrollPane; import javax.swing.ScrollPaneConstants; import javax.swing.SwingConstants; import javax.swing.TransferHandler; import wjhk.jupload2.JUploadApplet; import wjhk.jupload2.gui.filepanel.FilePanel; import wjhk.jupload2.gui.filepanel.FilePanelTableImp; import wjhk.jupload2.policies.UploadPolicy; import wjhk.jupload2.upload.FileUploadManagerThread; import wjhk.jupload2.upload.FileUploadManagerThreadImpl; /** * * Standard implementation for the {@link JUploadPanel} interface. It contains * the actual creation of the GUI items. * * @author etienne_sf * @version $Revision: 1165 $ */ public class JUploadPanelImpl extends JPanel implements ActionListener, JUploadPanel, MouseListener { /** A generated serialVersionUID, to avoid warning during compilation */ private static final long serialVersionUID = -1212601012568225757L; /** The debug popup menu of the applet */ private JUploadDebugPopupMenu jUploadDebugPopupMenu; /** The main popup menu of the applet */ private JUploadMainPopupMenu jUploadMainPopupMenu; // ------------- VARIABLES ---------------------------------------------- /** * The Drag and Drop listener, that will manage the drop event. All pplet * element should register this instance, so that the user see the whole * applet as a unique drop target. */ private DnDListener dndListener = null; private JButton browseButton = null, removeButton = null, removeAllButton = null, uploadButton = null, stopButton = null; private JUploadFileChooser fileChooser = null; private FilePanel filePanel = null; private JProgressBar preparationProgressBar = null; private JProgressBar uploadProgressBar = null; private JLabel statusLabel = null; /** * The log window. It's created by {@link JUploadApplet}. */ private JUploadTextArea logWindow = null; /** * The log window pane contains the log window, and the relevant scroll * bars. It's actually this pane that is displayed, as a view on the log * window. */ private JScrollPane jLogWindowPane = null; private UploadPolicy uploadPolicy = null; private FileUploadManagerThread fileUploadManagerThread = null; // ------------- CONSTRUCTOR -------------------------------------------- /** * Standard constructor. * * @param logWindow * The log window that should already have been created. This * allows putting text into it, before the effective creation of * the layout. * @param uploadPolicyParam * The current UploadPolicy. Null if a new one must be created. * @throws Exception */ public JUploadPanelImpl(JUploadTextArea logWindow, UploadPolicy uploadPolicyParam) throws Exception { this.logWindow = logWindow; this.uploadPolicy = uploadPolicyParam; this.jUploadDebugPopupMenu = new JUploadDebugPopupMenu( this.uploadPolicy); this.jUploadMainPopupMenu = new JUploadMainPopupMenu(this.uploadPolicy, this); // First: create standard components. createStandardComponents(); logWindow.addMouseListener(this); // Define the drop target. this.dndListener = new DnDListener(this, this.uploadPolicy); new DropTarget(this, this.dndListener); new DropTarget(this.filePanel.getDropComponent(), this.dndListener); new DropTarget(this.logWindow, this.dndListener); // Define the TransfertHandler, to manage paste operations. JUploadTransferHandler jUploadTransfertHandler = new JUploadTransferHandler( this.uploadPolicy, this); this.setTransferHandler(jUploadTransfertHandler); this.filePanel.setTransferHandler(jUploadTransfertHandler); ActionMap map = this.getActionMap(); map.put(TransferHandler.getPasteAction().getValue(Action.NAME), TransferHandler.getPasteAction()); // The JUploadPanelImpl will listen to Mouse messages for the standard // component. The current only application of this, it the CTRL+Righ // Click, that triggers the popup menu, which allow to switch debug on. this.browseButton.addMouseListener(this); this.removeAllButton.addMouseListener(this); this.removeButton.addMouseListener(this); this.stopButton.addMouseListener(this); this.uploadButton.addMouseListener(this); this.jLogWindowPane.addMouseListener(this); logWindow.addMouseListener(this); this.preparationProgressBar.addMouseListener(this); this.uploadProgressBar.addMouseListener(this); this.statusLabel.addMouseListener(this); // Then: display them on the applet this.uploadPolicy.addComponentsToJUploadPanel(this); } // ---------------------------------------------------------------------- /** * Creates all components used by the default upload policy.
* You can change the component position of these components on the applet, * by creating a new upload policy, and override the * {@link UploadPolicy#addComponentsToJUploadPanel(JUploadPanel)} method.
* You should keep these components, as there content is managed by the * internal code of the applet.
* Note: this method will create component only if they were not * already created. That is only if the relevant attribute contain a null * value. If it's not the case, the already created component are keeped * unchanged. */ private void createStandardComponents() { // -------- JButton browse -------- if (this.browseButton == null) { this.browseButton = new JButton(this.uploadPolicy .getLocalizedString("buttonBrowse")); this.browseButton.setIcon(new ImageIcon(getClass().getResource( "/images/explorer.gif"))); } this.browseButton.addActionListener(this); // -------- JButton remove -------- if (this.removeButton == null) { this.removeButton = new JButton(this.uploadPolicy .getLocalizedString("buttonRemoveSelected")); this.removeButton.setIcon(new ImageIcon(getClass().getResource( "/images/recycle.gif"))); } this.removeButton.setEnabled(false); this.removeButton.addActionListener(this); // -------- JButton removeAll -------- if (this.removeAllButton == null) { this.removeAllButton = new JButton(this.uploadPolicy .getLocalizedString("buttonRemoveAll")); this.removeAllButton.setIcon(new ImageIcon(getClass().getResource( "/images/cross.gif"))); } this.removeAllButton.setEnabled(false); this.removeAllButton.addActionListener(this); // -------- JButton upload -------- if (null == this.uploadButton) { this.uploadButton = new JButton(this.uploadPolicy .getLocalizedString("buttonUpload")); this.uploadButton.setIcon(new ImageIcon(getClass().getResource( "/images/up.gif"))); } this.uploadButton.setEnabled(false); this.uploadButton.addActionListener(this); // -------- The main thing: the file panel -------- this.filePanel = new FilePanelTableImp(this, this.uploadPolicy); // -------- JProgressBar progress -------- if (null == this.preparationProgressBar) { this.preparationProgressBar = new JProgressBar( SwingConstants.HORIZONTAL); this.preparationProgressBar.setStringPainted(true); } if (null == this.uploadProgressBar) { this.uploadProgressBar = new JProgressBar(SwingConstants.HORIZONTAL); this.uploadProgressBar.setStringPainted(true); } // -------- JButton stop -------- if (null == this.stopButton) { this.stopButton = new JButton(this.uploadPolicy .getLocalizedString("buttonStop")); this.stopButton.setIcon(new ImageIcon(getClass().getResource( "/images/cross.gif"))); } this.stopButton.setEnabled(false); this.stopButton.addActionListener(this); // -------- JButton stop -------- if (this.jLogWindowPane == null) { this.jLogWindowPane = new JScrollPane(); this.jLogWindowPane .setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); this.jLogWindowPane .setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); } this.jLogWindowPane.getViewport().add(this.logWindow); this.jLogWindowPane.setPreferredSize(null); // -------- statusLabel -------- this.statusLabel = new JLabel("JUpload applet " + this.uploadPolicy.getContext().getDetailedVersionMessage()); } /** {@inheritDoc} */ public void showOrHideLogWindow() { if ((this.uploadPolicy.getShowLogWindow() .equals(UploadPolicy.SHOWLOGWINDOW_TRUE)) || (this.uploadPolicy.getShowLogWindow().equals( UploadPolicy.SHOWLOGWINDOW_ONERROR) && this.uploadPolicy .getLastException() != null)) { // The log window should be visible. this.jLogWindowPane.setVisible(true); } else { // It should be hidden. this.jLogWindowPane.setVisible(false); } // Let's recalculate the component display validate(); } // /////////////////////////////////////////////////////////////////////////////// // ///////////////// Action methods // /////////////////////////////////////////////////////////////////////////////// /** {@inheritDoc} */ public void doBrowse() { // If the file chooser was not created, we create it now. if (null == this.fileChooser) { // Setup File Chooser. try { this.uploadPolicy.displayDebug( "Before this.uploadPolicy.createFileChooser()", 80); this.fileChooser = this.uploadPolicy.createFileChooser(); this.uploadPolicy.displayDebug( "After this.uploadPolicy.createFileChooser()", 80); } catch (Exception e) { this.uploadPolicy.displayErr(e); } } // If the fileChooser succeed (should be the case), we go on. if (null != this.fileChooser) { try { int ret = this.fileChooser.showOpenDialog(new Frame()); if (JFileChooser.APPROVE_OPTION == ret) this.filePanel.addFiles( this.fileChooser.getSelectedFiles(), this.fileChooser.getCurrentDirectory()); // We stop any running task for the JUploadFileView this.uploadPolicy.setCurrentBrowsingDirectory(this.fileChooser .getCurrentDirectory().getAbsolutePath()); this.fileChooser.shutdownNow(); } catch (Exception ex) { this.uploadPolicy.displayErr(ex); } } } /** {@inheritDoc} */ public void doRemove() { this.filePanel.removeSelected(); if (0 >= this.filePanel.getFilesLength()) { this.removeButton.setEnabled(false); this.removeAllButton.setEnabled(false); this.uploadButton.setEnabled(false); } } /** {@inheritDoc} */ public void doRemoveAll() { this.filePanel.removeAll(); this.removeButton.setEnabled(false); this.removeAllButton.setEnabled(false); this.uploadButton.setEnabled(false); } /** {@inheritDoc} */ public void doStartUpload() { // Check that the upload is ready (we ask the uploadPolicy. Then, // we'll call beforeUpload for each // FileData instance, that exists in allFiles[]. // /////////////////////////////////////////////////////////////////////////////////////////////// // IMPORTANT: It's up to the UploadPolicy to explain to the user // that the upload is not ready! // /////////////////////////////////////////////////////////////////////////////////////////////// try { if (this.uploadPolicy.beforeUpload()) { // The FileUploadManagerThread will manage everything around // upload, including GUI part. this.fileUploadManagerThread = new FileUploadManagerThreadImpl( this.uploadPolicy); this.fileUploadManagerThread.start(); } // if isIploadReady() } catch (Exception e) { // If an exception occurs here, it fails silently. The exception is // thrown to the AWT event dispatcher. this.uploadPolicy.displayErr(e.getClass().getName() + " in JUploadPanelImpl.doStartUpload()", e); } } /** {@inheritDoc} */ public void doStopUpload() { this.fileUploadManagerThread.stopUpload(); } // /////////////////////////////////////////////////////////////////////////////// // ///////////////// Implementation of the ActionListener // /////////////////////////////////////////////////////////////////////////////// /** * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) */ public void actionPerformed(ActionEvent e) { // Let's log some info. this.uploadPolicy.displayDebug("Action : " + e.getActionCommand(), 1); final String actionPaste = (String) TransferHandler.getPasteAction() .getValue(Action.NAME); if (e.getActionCommand().equals(actionPaste)) { Action a = getActionMap().get(actionPaste); if (a != null) { a.actionPerformed(new ActionEvent(this.filePanel, ActionEvent.ACTION_PERFORMED, e.getActionCommand())); this.uploadPolicy.afterFileDropped(new DropTargetDropEvent(new DropTarget( this.filePanel.getDropComponent(), this.dndListener).getDropTargetContext(), new Point(), DnDConstants.ACTION_MOVE, DnDConstants.ACTION_COPY_OR_MOVE )); } } else if (e.getActionCommand() == this.browseButton.getActionCommand()) { doBrowse(); } else if (e.getActionCommand() == this.removeButton.getActionCommand()) { // Remove clicked doRemove(); } else if (e.getActionCommand() == this.removeAllButton .getActionCommand()) { // Remove All clicked doRemoveAll(); } else if (e.getActionCommand() == this.uploadButton.getActionCommand()) { // Upload clicked doStartUpload(); } else if (e.getActionCommand() == this.stopButton.getActionCommand()) { // We request the thread to stop its job. doStopUpload(); } // focus the table. This is necessary in order to enable mouse // events // for triggering tooltips. this.filePanel.focusTable(); } // /////////////////////////////////////////////////////////////////////////////// // ///////////////// Implementation of the MouseListener // /////////////////////////////////////////////////////////////////////////////// /** * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent) */ public void mouseClicked(MouseEvent mouseEvent) { maybeOpenPopupMenu(mouseEvent); } /** * @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent) */ public void mouseEntered(MouseEvent mouseEvent) { maybeOpenPopupMenu(mouseEvent); } /** * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent) */ public void mouseExited(MouseEvent mouseEvent) { maybeOpenPopupMenu(mouseEvent); } /** * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent) */ public void mousePressed(MouseEvent mouseEvent) { maybeOpenPopupMenu(mouseEvent); } /** * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent) */ public void mouseReleased(MouseEvent mouseEvent) { if (mouseEvent.getClickCount() == 2) { // We have a double-click. Let's tell it to the current upload // policy... this.uploadPolicy.onFileDoubleClicked(this.filePanel .getFileDataAt(mouseEvent.getPoint())); } else { maybeOpenPopupMenu(mouseEvent); } } /** {@inheritDoc} */ public boolean maybeOpenPopupMenu(MouseEvent mouseEvent) { // Should we open one out of the numerous (2!) popup menus ? if (mouseEvent.isPopupTrigger()) { if ((mouseEvent.getModifiersEx() & InputEvent.CTRL_DOWN_MASK) == InputEvent.CTRL_DOWN_MASK) { // We open the debug menu if (this.jUploadDebugPopupMenu != null) { this.jUploadDebugPopupMenu.show(mouseEvent.getComponent(), mouseEvent.getX(), mouseEvent.getY()); return true; } } else { // Let's open the main popup menu if (this.jUploadMainPopupMenu != null) { this.jUploadMainPopupMenu.show(mouseEvent.getComponent(), mouseEvent.getX(), mouseEvent.getY()); return true; } } } return false; } /** {@inheritDoc} */ public void updateButtonState() { if (this.fileUploadManagerThread != null && this.fileUploadManagerThread.isAlive() && !this.fileUploadManagerThread.isUploadFinished()) { // An upload is running on. this.browseButton.setEnabled(false); this.removeButton.setEnabled(false); this.removeAllButton.setEnabled(false); this.uploadButton.setEnabled(false); this.stopButton.setEnabled(true); // Let's delegate any additional work to the upload policy. this.uploadPolicy .updateButtonState(UploadPolicy.EXEC_STATUS_UPLOADING); } else { // No upload running on. this.browseButton.setEnabled(true); this.stopButton.setEnabled(false); boolean enabled = (this.filePanel.getFilesLength() > 0); this.removeButton.setEnabled(enabled); this.removeAllButton.setEnabled(enabled); this.uploadButton.setEnabled(enabled); // Let's delegate any additional work to the upload policy. this.uploadPolicy.updateButtonState(UploadPolicy.EXEC_STATUS_READY); } } /** {@inheritDoc} */ public void clearLogWindow() { this.logWindow.setText(""); } /** {@inheritDoc} */ public void copyLogWindow() { this.logWindow.selectAll(); this.logWindow.copy(); } /** {@inheritDoc} */ public ActionListener getActionListener() { return this; } /** {@inheritDoc} */ public JButton getBrowseButton() { return this.browseButton; } /** {@inheritDoc} */ public JComponent getJComponent() { return this; } /** {@inheritDoc} */ public DnDListener getDndListener() { return this.dndListener; } /** {@inheritDoc} */ public FilePanel getFilePanel() { return this.filePanel; } /** {@inheritDoc} */ public JScrollPane getJLogWindowPane() { return this.jLogWindowPane; } /** * Get the log window, that is: the component where messages (debug, info, * error...) are written. You should not use this component directly, but: * * * @return the logWindow */ protected JUploadTextArea getLogWindow() { return this.logWindow; } /** {@inheritDoc} */ public MouseListener getMouseListener() { return this; } /** {@inheritDoc} */ public JProgressBar getPreparationProgressBar() { return this.preparationProgressBar; } /** {@inheritDoc} */ public JProgressBar getUploadProgressBar() { return this.uploadProgressBar; } /** {@inheritDoc} */ public JButton getRemoveAllButton() { return this.removeAllButton; } /** {@inheritDoc} */ public JButton getRemoveButton() { return this.removeButton; } /** {@inheritDoc} */ public JLabel getStatusLabel() { return this.statusLabel; } /** {@inheritDoc} */ public JButton getStopButton() { return this.stopButton; } /** {@inheritDoc} */ public JButton getUploadButton() { return this.uploadButton; } /** {@inheritDoc} */ public void setFilePanel(FilePanel filePanel) { this.filePanel = filePanel; } /** {@inheritDoc} */ public FileUploadManagerThread getFileUploadManagerThread() { return fileUploadManagerThread; } }