Coverage Report - wjhk.jupload2.gui.filepanel.FilePanelTableImp
 
Classes in this File Line Coverage Branch Coverage Complexity
FilePanelTableImp
51 %
83/161
40 %
20/50
2,231
FilePanelTableImp$1
100 %
1/1
N/A
2,231
 
 1  
 //
 2  
 // $Id: FilePanelTableImp.java 1721 2015-03-29 17:48:44Z etienne_sf $
 3  
 //
 4  
 // jupload - A file upload applet.
 5  
 // Copyright 2007 The JUpload Team
 6  
 //
 7  
 // Created: ?
 8  
 // Creator: William JinHua Kwong
 9  
 // Last modified: $Date: 2015-03-29 19:48:44 +0200 (dim., 29 mars 2015) $
 10  
 //
 11  
 // This program is free software; you can redistribute it and/or modify it under
 12  
 // the terms of the GNU General Public License as published by the Free Software
 13  
 // Foundation; either version 2 of the License, or (at your option) any later
 14  
 // version. This program is distributed in the hope that it will be useful, but
 15  
 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 16  
 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 17  
 // details. You should have received a copy of the GNU General Public License
 18  
 // along with this program; if not, write to the Free Software Foundation, Inc.,
 19  
 // 675 Mass Ave, Cambridge, MA 02139, USA.
 20  
 package wjhk.jupload2.gui.filepanel;
 21  
 
 22  
 import java.awt.BorderLayout;
 23  
 import java.awt.Color;
 24  
 import java.awt.Component;
 25  
 import java.awt.Font;
 26  
 import java.awt.Point;
 27  
 import java.awt.event.ComponentEvent;
 28  
 import java.awt.event.ComponentListener;
 29  
 import java.io.File;
 30  
 import java.util.List;
 31  
 
 32  
 import javax.swing.JPanel;
 33  
 import javax.swing.JScrollPane;
 34  
 import javax.swing.table.TableColumnModel;
 35  
 
 36  
 import wjhk.jupload2.exception.JUploadExceptionStopAddingFiles;
 37  
 import wjhk.jupload2.filedata.FileData;
 38  
 import wjhk.jupload2.gui.JUploadPanel;
 39  
 import wjhk.jupload2.gui.filepanel.treeview.FolderNode;
 40  
 import wjhk.jupload2.gui.filepanel.treeview.FileDataTreeViewModel;
 41  
 import wjhk.jupload2.gui.filepanel.treeview.MyTreeTable;
 42  
 import wjhk.jupload2.gui.filepanel.treeview.MyTreeTableModel;
 43  
 import wjhk.jupload2.gui.filepanel.treeview.TreeFileDataNode;
 44  
 import wjhk.jupload2.policies.UploadPolicy;
 45  
 
 46  
 /**
 47  
  * Implementation of the FilePanel : it creates the {@link wjhk.jupload2.gui.filepanel.FilePanelJFlatTable}, and handles
 48  
  * the necessary functionalities.<BR/>
 49  
  * Since version 6.0, this class manages the link with the hierarchical (tree) view of the files to upload. This class
 50  
  * remains the central point for file management, even if it's not visible. That is: even if the list displayed is the
 51  
  * hierarchical view.
 52  
  * 
 53  
  * @author William JinHua Kwong
 54  
  * @version $Revision: 1721 $
 55  
  */
 56  
 public class FilePanelTableImp extends JPanel implements FilePanel, ComponentListener {
 57  
 
 58  
     /** A generated serialVersionUID, to avoid warning during compilation */
 59  
     static final long serialVersionUID = -8273990467324350526L;
 60  
 
 61  
     /** The main panel of the applet. */
 62  40
     JUploadPanel juploadPanel = null;
 63  
 
 64  
     /** The table, for the flat list */
 65  
     FilePanelJFlatTable flatTable;
 66  
 
 67  
     /** the data model, for the flat list */
 68  
     FilePanelFlatDataModel2 flatModel;
 69  
 
 70  
     /** The table, for the tree view */
 71  
     MyTreeTable treeTable;
 72  
 
 73  
     /** the data model, for the tree view */
 74  
     MyTreeTableModel<TreeFileDataNode> /* FileDataTreeViewModel */treeModel;
 75  
 
 76  
     /** The view, which displays the flat view. */
 77  40
     JScrollPane flatScrollPane = null;
 78  
 
 79  
     /** The view, which displays the tree view. */
 80  40
     JScrollPane treeScrollPane = null;
 81  
 
 82  
     /** The current display mode, for the file list. The default value is FLAT */
 83  40
     FileListViewMode fileListViewMode = FileListViewMode.FLAT;
 84  
 
 85  
     /** The current policy, always useful. */
 86  40
     UploadPolicy uploadPolicy = null;
 87  
 
 88  
     /**
 89  
      * Creates a new instance.
 90  
      * 
 91  
      * @param juploadPanel The upload panel (parent).
 92  
      * @param uploadPolicy The upload policy to apply.
 93  
      */
 94  40
     public FilePanelTableImp(JUploadPanel juploadPanel, UploadPolicy uploadPolicy) {
 95  40
         this.juploadPanel = juploadPanel;
 96  40
         this.uploadPolicy = uploadPolicy;
 97  
 
 98  40
         setLayout(new BorderLayout());
 99  40
         addMouseListener(juploadPanel.getMouseListener());
 100  40
         setTransferHandler(juploadPanel.getTransferHandler());
 101  
 
 102  
         // Construction of the flat view
 103  40
         this.flatTable = new FilePanelJFlatTable(juploadPanel, uploadPolicy);
 104  40
         this.flatModel = new FilePanelFlatDataModel2(uploadPolicy);
 105  40
         this.flatTable.setModel(this.flatModel);
 106  40
         this.flatScrollPane = new JScrollPane(this.flatTable);
 107  40
         this.flatScrollPane.addMouseListener(juploadPanel.getMouseListener());
 108  
         // We must resize columns, when the size of the view changes.
 109  40
         this.flatScrollPane.getViewport().addComponentListener(this);
 110  
 
 111  
         // Construction of the tree view
 112  40
         treeModel = new FileDataTreeViewModel(uploadPolicy, this.flatModel);
 113  40
         treeTable = new MyTreeTable(treeModel);
 114  40
         treeModel.setTree(treeTable.getTree());
 115  40
         this.treeScrollPane = new JScrollPane(this.treeTable);
 116  40
         this.treeScrollPane.addMouseListener(juploadPanel.getMouseListener());
 117  
         // We must resize columns, when the size of the view changes.
 118  40
         this.treeScrollPane.getViewport().addComponentListener(this);
 119  
 
 120  
         // Let's display the chosen mode.
 121  40
         this.fileListViewMode = this.uploadPolicy.getFileListViewMode();
 122  40
         switch (this.fileListViewMode) {
 123  
             case FLAT:
 124  40
                 add(this.flatScrollPane, BorderLayout.CENTER);
 125  40
                 break;
 126  
             case TREE_VIEW:
 127  
             case INDEPENDENT_TREE_VIEW:
 128  0
                 add(this.treeScrollPane, BorderLayout.CENTER);
 129  
                 break;
 130  
         }// switch
 131  40
     }
 132  
 
 133  
     /** @see FilePanel#getFileListMode() */
 134  
     public FileListViewMode getFileListMode() {
 135  0
         return this.fileListViewMode;
 136  
     }
 137  
 
 138  
     /** @see FilePanel#setFileListViewMode(wjhk.jupload2.gui.filepanel.FilePanel.FileListViewMode) */
 139  
     public void setFileListViewMode(FileListViewMode fileListViewMode) {
 140  0
         if (this.fileListViewMode != fileListViewMode) {
 141  0
             switch (fileListViewMode) {
 142  
                 case FLAT:
 143  0
                     remove(this.treeScrollPane);
 144  0
                     add(this.flatScrollPane, BorderLayout.CENTER);
 145  
                     // this.flatScrollPane.setVisible(true);
 146  
                     // this.treeScrollPane.setVisible(false);
 147  0
                     break;
 148  
                 case TREE_VIEW:
 149  0
                     remove(this.flatScrollPane);
 150  0
                     add(this.treeScrollPane, BorderLayout.CENTER);
 151  
                     // this.flatScrollPane.setVisible(false);
 152  
                     // this.treeScrollPane.setVisible(true);
 153  0
                     break;
 154  
                 default:
 155  0
                     IllegalArgumentException e = new IllegalArgumentException("Unknown value for fileListMode:"
 156  0
                             + fileListViewMode.toString());
 157  0
                     uploadPolicy.displayErr(e);
 158  0
                     throw e;
 159  
             }
 160  0
             this.fileListViewMode = fileListViewMode;
 161  0
             this.uploadPolicy.setFileListViewMode(fileListViewMode);
 162  
         }
 163  0
     }
 164  
 
 165  
     /**
 166  
      * @see wjhk.jupload2.gui.filepanel.FilePanel#addFiles(java.io.File[],java.io.File)
 167  
      */
 168  
     public final void addFiles(File[] filesToAdd) {
 169  
         // adding file can be long. Let's add a time counter, there...
 170  8
         long startTime = System.currentTimeMillis();
 171  8
         int nbFiles = 0;
 172  
 
 173  8
         if (null == filesToAdd) {
 174  0
             String msg = "FilePanelTableImpl: filesToUpload may not be null)";
 175  0
             uploadPolicy.displayErr(msg);
 176  0
             throw new java.lang.IllegalArgumentException(msg);
 177  
         } else {
 178  
             try {
 179  24
                 for (int i = 0; i < filesToAdd.length; i++) {
 180  16
                     nbFiles += treeModel.attachObject(filesToAdd[i]);
 181  
                 }// for
 182  0
             } catch (JUploadExceptionStopAddingFiles e) { // The user want to stop here. Nothing else to do.
 183  0
                 this.uploadPolicy.displayWarn(getClass().getName() + ".addFiles() [" + e.getClass().getName() + "]: "
 184  0
                         + e.getMessage());
 185  0
             } catch (Exception e) {
 186  0
                 this.uploadPolicy.displayErr("Unexpected error during file adding: " + getClass().getName()
 187  0
                         + ".addFiles() [" + e.getClass().getName() + "]: " + e.getMessage());
 188  8
             }
 189  
         }
 190  8
         this.juploadPanel.updateButtonState();
 191  
 
 192  
         // Update of the flat view
 193  8
         this.flatModel.fireTableDataChanged();
 194  
 
 195  
         // Update of the tree view. In flat mode and tree_view mode, the visible root may have changed after adding
 196  
         // files.
 197  8
         if (this.uploadPolicy.getFileListViewMode().equals(FileListViewMode.FLAT)
 198  0
                 || this.uploadPolicy.getFileListViewMode().equals(FileListViewMode.TREE_VIEW)) {
 199  8
             FolderNode visibleRoot = (FolderNode) treeModel.getTreePathForObject(flatModel.getFileRoot())
 200  8
                     .getLastPathComponent();
 201  8
             if (visibleRoot == null) {
 202  0
                 uploadPolicy.displayErr("[Internal Error] Folder Node not found for folder "
 203  0
                         + flatModel.getFileRoot().getAbsolutePath());
 204  
             } else {
 205  8
                 treeModel.setRoot(visibleRoot);
 206  
             }
 207  8
         } else {
 208  
             // We still need to refresh the data
 209  0
             reload();
 210  
         }
 211  
 
 212  
         // adding file can be long. Let's add a time counter, there...
 213  8
         long finishTime = System.currentTimeMillis();
 214  8
         uploadPolicy.displayInfo("Added " + nbFiles + " files in " + ((finishTime - startTime) / 1000) + " seconds");
 215  8
     }
 216  
 
 217  
     /**
 218  
      * @see wjhk.jupload2.gui.filepanel.FilePanel#getFiles()
 219  
      */
 220  
     public final List<FileData> getFiles() {
 221  4
         return this.flatModel.getFiles();
 222  
     }
 223  
 
 224  
     /**
 225  
      * @see wjhk.jupload2.gui.filepanel.FilePanel#getFilesLength()
 226  
      */
 227  
     public final int getFilesLength() {
 228  9
         return this.flatTable.getRowCount();
 229  
     }
 230  
 
 231  
     /**
 232  
      * @see wjhk.jupload2.gui.filepanel.FilePanel#removeSelected()
 233  
      */
 234  
     public final void removeSelected() {
 235  1
         synchronized (this.flatModel.getFiles()) {
 236  1
             int[] rows = this.flatTable.getSelectedRows();
 237  3
             for (int i = rows.length - 1; 0 <= i; i--) {
 238  2
                 removeRow(rows[i], null);
 239  
             }
 240  1
         }
 241  1
     }
 242  
 
 243  
     /**
 244  
      * @see java.awt.Container#removeAll()
 245  
      */
 246  
     @Override
 247  
     public final void removeAll() {
 248  1
         synchronized (this.flatModel.getFiles()) {
 249  4
             for (int i = getFilesLength() - 1; 0 <= i; i--) {
 250  3
                 removeRow(i, null);
 251  
             }
 252  1
         }
 253  1
     }
 254  
 
 255  
     /** {@inheritDoc} */
 256  
     public void remove(FileData[] files) {
 257  0
         for (FileData fd : files) {
 258  0
             removeRow(null, fd);
 259  
         }
 260  0
         this.treeModel.reload();
 261  0
     }
 262  
 
 263  
     /** @see FilePanel#removeFileNotToUpload() */
 264  
     public void removeFileNotToUpload() {
 265  
         // We remove all files, for which getUploadFlag() returns false.
 266  
         // To do that, we can not do a standard for loop, to avoid the ConcurrentModificationException. So we do a
 267  
         // specific counter management.
 268  0
         int i = 0;
 269  
         FileData fd;
 270  0
         List<FileData> files = this.flatModel.getFiles();
 271  0
         while (i < files.size()) {
 272  0
             fd = files.get(i);
 273  0
             if (fd.getUploadFlag()) {
 274  
                 // This file is to be uploaded. Let's pass it, to check the next one.
 275  0
                 i += 1;
 276  
             } else {
 277  
                 // This file is to be removed. We remove it, and keep the same index, which will contain the next file
 278  
                 // in the next loop.
 279  0
                 removeRow(i, fd);
 280  
             }
 281  
         }// while
 282  0
     }
 283  
 
 284  
     /**
 285  
      * Removes all occurences of a file from the list. Each file should only appear once here, but nobody knows !
 286  
      * 
 287  
      * @param fileData The file to remove
 288  
      */
 289  
     public final void remove(FileData fileData) {
 290  4
         removeRow(null, fileData);
 291  4
     }
 292  
 
 293  
     /**
 294  
      * Removes a File from the FileList, with either the rowNumber or the FileData (or both). This method is internal to
 295  
      * this class. If only one of these parameters is sent, the other one is calculated from the given one. If both
 296  
      * parameters are sent, it's up to the calling method to guaranty that they both represents the same FileData.
 297  
      * 
 298  
      * @param rowNumber The row number in the flat view.
 299  
      * @param fileData The fileData to remove.
 300  
      */
 301  
     final void removeRow(Integer rowNumberParam, FileData fileDataParam) {
 302  9
         synchronized (this.flatModel.getFiles()) {
 303  9
             if (rowNumberParam == null && fileDataParam == null) {
 304  0
                 uploadPolicy
 305  0
                         .displayErr("rowNumberParam and fileDataParam may not be both null (in FilePanelTableImpl.removeRow(Integer,FileData)");
 306  
             }
 307  
 
 308  9
             Integer rowNumber = rowNumberParam;
 309  9
             FileData fileData = fileDataParam;
 310  9
             if (rowNumber == null) {
 311  4
                 rowNumber = this.flatModel.getRow(fileDataParam);
 312  5
             } else if (fileData == null) {
 313  5
                 fileData = this.flatModel.getFileDataAt(rowNumber);
 314  
             }
 315  
 
 316  
             // Removes the row, from the flat view .. If it exists.
 317  9
             if (rowNumber == null || rowNumber < 0) {
 318  1
                 uploadPolicy.displayWarn("The row " + rowNumber
 319  
                         + " doesn't exist (in FilePanelTableImpl.removeRow(Integer,FileData)");
 320  
             } else {
 321  8
                 this.flatModel.removeRow(rowNumber);
 322  
             }
 323  
 
 324  
             // Removes the row, from the tree view
 325  9
             if (fileData == null) {
 326  0
                 uploadPolicy.displayWarn("The fileData for " + rowNumber
 327  
                         + " doesn't exist (in FilePanelTableImpl.removeRow(Integer,FileData)");
 328  
             } else {
 329  
                 // FIXME Pour changer ├ža: passer par tous les noeuds, et trouver le FileData
 330  
                 try {
 331  9
                     this.treeModel.remove(fileData.getTreeFileDataNode());
 332  1
                 } catch (Exception e) {
 333  1
                     uploadPolicy.displayErr(e);
 334  8
                 }
 335  
                 /*
 336  
                  * TreePath tp = treeModel.getTreePath(fileData.getTreeFileDataNode()); if (tp == null) {
 337  
                  * uploadPolicy.displayWarn("The fileData for file " + fileData.getAbsolutePath() +
 338  
                  * " doesn't exist (in FilePanelTableImpl.removeRow(Integer,FileData)"); } else if
 339  
                  * (!(tp.getLastPathComponent() instanceof FileDataNode)) {
 340  
                  * uploadPolicy.displayErr("The node for the fileData " + fileData.getAbsolutePath() +
 341  
                  * " should be a FileDataNode (in FilePanelTableImpl.removeRow(Integer,FileData)"); } else { try {
 342  
                  * this.treeModel.remove((FileDataNode) tp.getLastPathComponent()); } catch (Exception e) {
 343  
                  * uploadPolicy.displayErr(e); } }
 344  
                  */
 345  
             }
 346  9
         }// synchronized
 347  9
     }
 348  
 
 349  
     /**
 350  
      * Clear the current selection in the JTable.
 351  
      */
 352  
     public final void clearSelection() {
 353  1
         this.flatTable.clearSelection();
 354  1
     }
 355  
 
 356  
     /** @see wjhk.jupload2.gui.filepanel.FilePanel#focusTable() */
 357  
     public final void focusTable() {
 358  0
         if (0 < this.flatTable.getRowCount()) {
 359  0
             this.flatTable.requestFocus();
 360  
         }
 361  0
     }
 362  
 
 363  
     /** @see wjhk.jupload2.gui.filepanel.FilePanel#getFileDataAt(Point) */
 364  
     public FileData getFileDataAt(Point point) {
 365  1
         int row = this.flatTable.rowAtPoint(point);
 366  1
         return this.flatModel.getFileDataAt(row);
 367  
     }
 368  
 
 369  
     /**
 370  
      * Return the component on which drop event can occur. Used by {@link JUploadPanel}, when initializing the
 371  
      * DropTarget.
 372  
      * 
 373  
      * @return Component on which the drop event can occur.
 374  
      */
 375  
     public Component getDropComponent() {
 376  33
         return this;
 377  
     }
 378  
 
 379  
     /**
 380  
      * Catches the <I>hidden</I> event on the JViewport. {@inheritDoc}
 381  
      */
 382  
     public void componentHidden(ComponentEvent arg0) {
 383  
         // We don't care...
 384  0
     }
 385  
 
 386  
     /**
 387  
      * Catches the <I>moved</I> event on the JViewport. {@inheritDoc}
 388  
      */
 389  
     public void componentMoved(ComponentEvent arg0) {
 390  
         // We don't care...
 391  0
     }
 392  
 
 393  
     /**
 394  
      * When the size of the file list (actually the JViewport) changes, we adapt the size if the columns. {@inheritDoc}
 395  
      */
 396  
     public void componentResized(ComponentEvent arg0) {
 397  
         // Is the width set?
 398  0
         if (getWidth() > 0) {
 399  
             // First: we resize the flat table.
 400  0
             TableColumnModel flatColumnModel = this.flatTable.getColumnModel();
 401  0
             for (int i = 0; i < this.flatModel.getColumnCount(); i++) {
 402  0
                 flatColumnModel.getColumn(i)
 403  0
                         .setPreferredWidth(
 404  0
                                 (this.flatModel.getColumnSizePercentage(i) * this.flatScrollPane.getViewport()
 405  0
                                         .getWidth()) / 100);
 406  
             }// for
 407  
 
 408  
             // Then the tree view
 409  0
             TableColumnModel treeviewColumnModel = this.treeTable.getColumnModel();
 410  0
             for (int i = 0; i < this.treeModel.getColumnCount(); i++) {
 411  0
                 treeviewColumnModel.getColumn(i)
 412  0
                         .setPreferredWidth(
 413  0
                                 (this.treeModel.getColumnSizePercentage(i) * this.treeScrollPane.getViewport()
 414  0
                                         .getWidth()) / 100);
 415  
             }// for
 416  
         }
 417  0
     }
 418  
 
 419  
     /**
 420  
      * Catches the <I>shown</I> event on the JViewport. {@inheritDoc}
 421  
      */
 422  
     public void componentShown(ComponentEvent arg0) {
 423  
         // We don't care...
 424  0
     }
 425  
 
 426  
     /**
 427  
      * Set color of files list grid border.
 428  
      * 
 429  
      * @param color awt Color
 430  
      */
 431  
     public void setGridBorderColor(Color color) {
 432  0
         this.flatTable.setGridColor(color);
 433  0
     }
 434  
 
 435  
     /**
 436  
      * Set back color of table header
 437  
      * 
 438  
      * @param color awt Color
 439  
      */
 440  
     public void setTableHeaderBackColor(Color color) {
 441  0
         this.flatTable.getTableHeader().setBackground(color);
 442  0
     }
 443  
 
 444  
     /**
 445  
      * Set table header text font
 446  
      * 
 447  
      * @param color awt Color
 448  
      */
 449  
     public void setTableHeaderFont(Font font) {
 450  0
         this.flatTable.getTableHeader().setFont(font);
 451  0
     }
 452  
 
 453  
     /**
 454  
      * Set text color of table header
 455  
      * 
 456  
      * @param color awt Color
 457  
      */
 458  
     public void setTableHeaderTextColor(Color color) {
 459  0
         this.flatTable.getTableHeader().setForeground(color);
 460  0
     }
 461  
 
 462  
     /** {@inheritDoc} */
 463  
     public void reload() {
 464  0
         this.treeModel.reload();
 465  0
     }
 466  
 
 467  
     /** {@inheritDoc} */
 468  
     public void cleanHierarchy() {
 469  0
         this.treeModel.cleanHierarchy();
 470  0
         reload();
 471  0
     }
 472  
 
 473  
 }