You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by rw...@apache.org on 2012/06/05 22:30:21 UTC

svn commit: r1346574 - in /pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra: TerraFileBrowserSkin.java terra_file_browser_skin.bxml

Author: rwhitcomb
Date: Tue Jun  5 20:30:20 2012
New Revision: 1346574

URL: http://svn.apache.org/viewvc?rev=1346574&view=rev
Log:
PIVOT-857: Add activity indicator to File Browser while refreshing
  the file list.

This change also speeds up the process and puts almost all of it
into the background task so that the UI is not blocked.
Using a FileFilter so that the native filtering of File.listFiles
can be used (to do both the include and exclude filtering) which
then allows us to use Arrays.sort (probably the fastest possible
method) on the filtered array.
One other minor change: when the root directory changes, don't
call "refreshFileList" twice (once is enough from the Search
text input being cleared).

Modified:
    pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraFileBrowserSkin.java
    pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/terra_file_browser_skin.bxml

Modified: pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraFileBrowserSkin.java
URL: http://svn.apache.org/viewvc/pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraFileBrowserSkin.java?rev=1346574&r1=1346573&r2=1346574&view=diff
==============================================================================
--- pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraFileBrowserSkin.java (original)
+++ pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraFileBrowserSkin.java Tue Jun  5 20:30:20 2012
@@ -23,6 +23,7 @@ import java.io.FileFilter;
 import java.io.IOException;
 import java.io.Serializable;
 import java.text.DateFormat;
+import java.util.Arrays;
 import java.util.Comparator;
 import java.util.Date;
 
@@ -35,9 +36,11 @@ import org.apache.pivot.collections.Sequ
 import org.apache.pivot.serialization.SerializationException;
 import org.apache.pivot.text.FileSizeFormat;
 import org.apache.pivot.util.Filter;
+import org.apache.pivot.util.concurrent.AbortException;
 import org.apache.pivot.util.concurrent.Task;
 import org.apache.pivot.util.concurrent.TaskExecutionException;
 import org.apache.pivot.util.concurrent.TaskListener;
+import org.apache.pivot.wtk.ActivityIndicator;
 import org.apache.pivot.wtk.BoxPane;
 import org.apache.pivot.wtk.Button;
 import org.apache.pivot.wtk.ButtonPressListener;
@@ -48,6 +51,7 @@ import org.apache.pivot.wtk.Container;
 import org.apache.pivot.wtk.Dimensions;
 import org.apache.pivot.wtk.FileBrowser;
 import org.apache.pivot.wtk.FocusTraversalDirection;
+import org.apache.pivot.wtk.GridPane;
 import org.apache.pivot.wtk.HorizontalAlignment;
 import org.apache.pivot.wtk.ImageView;
 import org.apache.pivot.wtk.Insets;
@@ -64,6 +68,7 @@ import org.apache.pivot.wtk.PushButton;
 import org.apache.pivot.wtk.ScrollPane;
 import org.apache.pivot.wtk.SortDirection;
 import org.apache.pivot.wtk.Span;
+import org.apache.pivot.wtk.StackPane;
 import org.apache.pivot.wtk.TableView;
 import org.apache.pivot.wtk.TableViewSelectionListener;
 import org.apache.pivot.wtk.TableViewSortListener;
@@ -500,25 +505,23 @@ public class TerraFileBrowserSkin extend
      */
     public static class IncludeFileFilter implements Filter<File> {
         private String match;
-        private Filter<File> excludeFileFilter;
 
         public IncludeFileFilter() {
-            this(null, null);
+            this(null);
         }
 
-        public IncludeFileFilter(String match, Filter<File> excludeFileFilter) {
+        public IncludeFileFilter(String match) {
             this.match = (match == null ? null : match.toLowerCase());
-            this.excludeFileFilter = excludeFileFilter;
         }
 
         @Override
         public boolean include(File file) {
-            String name = file.getName();
-            name = name.toLowerCase();
-
             boolean include = true;
 
             if (match != null) {
+                String name = file.getName();
+                name = name.toLowerCase();
+
                 if (match.startsWith("*")) {
                     if (match.length() == 1) {
                         include = true;
@@ -530,23 +533,63 @@ public class TerraFileBrowserSkin extend
                 }
             }
 
+            return include;
+        }
+    }
+
+    public static class FullFileFilter implements FileFilter {
+        private Filter<File> includeFileFilter;
+        private Filter<File> excludeFileFilter;
+
+        public FullFileFilter(Filter<File> includeFileFilter, Filter<File> excludeFileFilter) {
+            this.includeFileFilter = includeFileFilter;
+            this.excludeFileFilter = excludeFileFilter;
+        }
+
+        @Override
+        public boolean accept(File file) {
+            boolean include = HIDDEN_FILE_FILTER.accept(file);
+            if (include
+                && includeFileFilter != null) {
+                include = includeFileFilter.include(file);
+            }
             if (include
                 && excludeFileFilter != null) {
                 include = !excludeFileFilter.include(file);
             }
-
             return include;
         }
     }
 
-    private class RefreshFileListTask extends Task<File[]> {
+    private class RefreshFileListTask extends Task<ArrayList<File>> {
+        private Filter<File> includeFileFilter;
+        private Filter<File> excludeFileFilter;
+        private FileComparator fileComparator;
+
+        public RefreshFileListTask(Filter<File> includeFileFilter,
+                Filter<File> excludeFileFilter,
+                FileComparator fileComparator) {
+            this.includeFileFilter = includeFileFilter;
+            this.excludeFileFilter = excludeFileFilter;
+            this.fileComparator = fileComparator;
+        }
+
         @Override
-        public File[] execute() {
+        public ArrayList<File> execute() {
             FileBrowser fileBrowser = (FileBrowser)getComponent();
             File rootDirectory = fileBrowser.getRootDirectory();
-            File[] files = rootDirectory.listFiles();
+            if (abort) {
+                throw new AbortException();
+            }
+
+            File[] files = rootDirectory.listFiles(new FullFileFilter(includeFileFilter, excludeFileFilter));
+            if (abort) {
+                throw new AbortException();
+            }
+
+            Arrays.sort(files, fileComparator);
 
-            return files;
+            return new ArrayList<File>(files, 0, files.length);
         }
     }
 
@@ -559,9 +602,13 @@ public class TerraFileBrowserSkin extend
     @BXML private PushButton goHomeButton = null;
     @BXML private TextInput searchTextInput = null;
 
+    @BXML private StackPane fileStackPane = null;
     @BXML private ScrollPane fileScrollPane = null;
     @BXML private TableView fileTableView = null;
 
+    private ActivityIndicator indicator = null;
+    private GridPane activityGrid = null;
+
     private boolean keyboardFolderTraversalEnabled = true;
     private boolean hideDisabledFiles = false;
 
@@ -965,12 +1012,10 @@ public class TerraFileBrowserSkin extend
 
         goHomeButton.setEnabled(!rootDirectory.equals(HOME_DIRECTORY));
 
-        searchTextInput.setText("");
-
         fileScrollPane.setScrollTop(0);
         fileScrollPane.setScrollLeft(0);
 
-        refreshFileList();
+        searchTextInput.setText("");
 
         fileTableView.requestFocus();
     }
@@ -1046,51 +1091,61 @@ public class TerraFileBrowserSkin extend
         // Cancel any outstanding task
         if (refreshFileListTask != null) {
             refreshFileListTask.abort();
+
+            if (indicator != null) {
+                indicator.setActive(false);
+                fileStackPane.remove(fileStackPane.getLength() - 1, 1);
+            }
+        }
+
+        if (indicator == null) {
+            indicator = new ActivityIndicator();
+            activityGrid = new GridPane(5);
+            GridPane.Row row1 = new GridPane.Row();
+            GridPane.Row row2 = new GridPane.Row();
+            GridPane.Row row3 = new GridPane.Row();
+            for (int i = 0; i < 5; i++) {
+                row1.add(new GridPane.Filler());
+                if (i == 2)
+                    row2.add(indicator);
+                else
+                    row2.add(new GridPane.Filler());
+                row3.add(new GridPane.Filler());
+            }
+            activityGrid.getRows().add(row1);
+            activityGrid.getRows().add(row2);
+            activityGrid.getRows().add(row3);
         }
+        fileStackPane.add(activityGrid);
+        indicator.setActive(true);
 
         fileTableView.setTableData(new ArrayList<File>());
 
-        refreshFileListTask = new RefreshFileListTask();
-        refreshFileListTask.execute(new TaskAdapter<File[]>(new TaskListener<File[]>() {
+        String text = searchTextInput.getText().trim();
+        Filter<File> disabledFileFilter = hideDisabledFiles ? ((FileBrowser) getComponent()).getDisabledFileFilter() : null;
+        Filter<File> includeFileFilter = text.length() != 0 ? new IncludeFileFilter(text) : null;
+
+        TableView.SortDictionary sort = fileTableView.getSort();
+
+        final FileComparator fileComparator;
+        if (sort.isEmpty()) {
+            fileComparator = null;
+        } else {
+            Dictionary.Pair<String, SortDirection> pair = fileTableView.getSort().get(0);
+            fileComparator = new FileComparator(pair.key, pair.value);
+        }
+
+        refreshFileListTask = new RefreshFileListTask(includeFileFilter, disabledFileFilter, fileComparator);
+        refreshFileListTask.execute(new TaskAdapter<ArrayList<File>>(new TaskListener<ArrayList<File>>() {
             @SuppressWarnings("unchecked")
             @Override
-            public void taskExecuted(Task<File[]> task) {
+            public void taskExecuted(Task<ArrayList<File>> task) {
                 if (task == refreshFileListTask) {
-                    File files[] = task.getResult();
-
-                    String text = searchTextInput.getText().trim();
-                    IncludeFileFilter includeFileFilter = new IncludeFileFilter(text.length() == 0 ? null : text,
-                        hideDisabledFiles ? ((FileBrowser) getComponent()).getDisabledFileFilter() : null);
-
-                    TableView.SortDictionary sort = fileTableView.getSort();
-
-                    final FileComparator fileComparator;
-                    if (sort.isEmpty()) {
-                        fileComparator = null;
-                    } else {
-                        Dictionary.Pair<String, SortDirection> pair = fileTableView.getSort().get(0);
-                        fileComparator = new FileComparator(pair.key, pair.value);
-                    }
+                    indicator.setActive(false);
+                    fileStackPane.remove(fileStackPane.getLength() - 1, 1);
 
-                    for (int i = 0; i < files.length; i++) {
-                        final File file = files[i];
-
-                        if (includeFileFilter.include(file) && HIDDEN_FILE_FILTER.accept(file)) {
-                            ArrayList<File> fileTableData = (ArrayList<File>)fileTableView.getTableData();
-
-                            int index;
-                            if (fileComparator == null) {
-                                index = fileTableData.getLength();
-                            } else {
-                                index = ArrayList.binarySearch(fileTableData, file, fileComparator);
-                                if (index < 0) {
-                                    index = -(index + 1);
-                                }
-                            }
-
-                            fileTableData.insert(file, index);
-                        }
-                    }
+                    ArrayList<File> fileList = task.getResult();
+                    fileTableView.setTableData(fileList);
 
                     updateSelectedFiles((FileBrowser) getComponent());
 
@@ -1099,8 +1154,11 @@ public class TerraFileBrowserSkin extend
             }
 
             @Override
-            public void executeFailed(Task<File[]> task) {
+            public void executeFailed(Task<ArrayList<File>> task) {
                 if (task == refreshFileListTask) {
+                    indicator.setActive(false);
+                    fileStackPane.remove(fileStackPane.getLength() - 1, 1);
+
                     refreshFileListTask = null;
                 }
             }

Modified: pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/terra_file_browser_skin.bxml
URL: http://svn.apache.org/viewvc/pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/terra_file_browser_skin.bxml?rev=1346574&r1=1346573&r2=1346574&view=diff
==============================================================================
--- pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/terra_file_browser_skin.bxml (original)
+++ pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/terra_file_browser_skin.bxml Tue Jun  5 20:30:20 2012
@@ -81,33 +81,35 @@ limitations under the License.
 
     <TablePane.Row height="1*">
         <Border styles="{color:10}">
-            <ScrollPane bxml:id="fileScrollPane"
-                horizontalScrollBarPolicy="fill" verticalScrollBarPolicy="fill_to_capacity">
-                <TableView bxml:id="fileTableView"
-                    styles="{showHorizontalGridLines:false, showVerticalGridLines:false}">
-                    <columns>
-                        <TableView.Column name="name" width="3*" headerData="%fileName">
-                            <cellRenderer>
-                                <terra:TerraFileBrowserSkin.TableViewFileRenderer/>
-                            </cellRenderer>
-                        </TableView.Column>
-                        <TableView.Column name="size" width="1*" headerData="%size">
-                            <cellRenderer>
-                                <terra:TerraFileBrowserSkin.TableViewFileRenderer/>
-                            </cellRenderer>
-                        </TableView.Column>
-                        <TableView.Column name="lastModified" width="2*" headerData="%lastModified">
-                            <cellRenderer>
-                                <terra:TerraFileBrowserSkin.TableViewFileRenderer/>
-                            </cellRenderer>
-                        </TableView.Column>
-                    </columns>
-                </TableView>
+            <StackPane bxml:id="fileStackPane">
+                <ScrollPane bxml:id="fileScrollPane"
+                    horizontalScrollBarPolicy="fill" verticalScrollBarPolicy="fill_to_capacity">
+                    <TableView bxml:id="fileTableView"
+                        styles="{showHorizontalGridLines:false, showVerticalGridLines:false}">
+                        <columns>
+                            <TableView.Column name="name" width="3*" headerData="%fileName">
+                                <cellRenderer>
+                                    <terra:TerraFileBrowserSkin.TableViewFileRenderer/>
+                                </cellRenderer>
+                            </TableView.Column>
+                            <TableView.Column name="size" width="1*" headerData="%size">
+                                <cellRenderer>
+                                    <terra:TerraFileBrowserSkin.TableViewFileRenderer/>
+                                </cellRenderer>
+                            </TableView.Column>
+                            <TableView.Column name="lastModified" width="2*" headerData="%lastModified">
+                                <cellRenderer>
+                                    <terra:TerraFileBrowserSkin.TableViewFileRenderer/>
+                                </cellRenderer>
+                            </TableView.Column>
+                        </columns>
+                    </TableView>
 
-                <columnHeader>
-                    <TableViewHeader tableView="$fileTableView" sortMode="single_column"/>
-                </columnHeader>
-            </ScrollPane>
+                    <columnHeader>
+                        <TableViewHeader tableView="$fileTableView" sortMode="single_column"/>
+                    </columnHeader>
+                </ScrollPane>
+            </StackPane>
         </Border>
     </TablePane.Row>
 </TablePane>