fix filter re-add data problem
[fanfix.git] / src / be / nikiroo / fanfix_swing / gui / browser / BasicTab.java
index d467a91792ea78d83107dcd1952785e9fe73b9b9..9b2bf789ac8ab05a75ae89c3a1b67a65fb91ba14 100644 (file)
@@ -8,14 +8,10 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
 import javax.swing.JTree;
 import javax.swing.SwingWorker;
-import javax.swing.UIDefaults;
 import javax.swing.event.TreeSelectionEvent;
 import javax.swing.event.TreeSelectionListener;
-import javax.swing.plaf.TreeUI;
 import javax.swing.plaf.basic.BasicTreeUI;
 import javax.swing.tree.DefaultMutableTreeNode;
 import javax.swing.tree.DefaultTreeCellRenderer;
@@ -23,15 +19,16 @@ import javax.swing.tree.DefaultTreeModel;
 import javax.swing.tree.TreeCellRenderer;
 import javax.swing.tree.TreePath;
 
-import be.nikiroo.fanfix.Instance;
 import be.nikiroo.fanfix_swing.gui.SearchBar;
+import be.nikiroo.fanfix_swing.gui.utils.ListenerPanel;
 import be.nikiroo.fanfix_swing.gui.utils.TreeCellSpanner;
+import be.nikiroo.fanfix_swing.gui.utils.TreeSnapshot;
 import be.nikiroo.fanfix_swing.gui.utils.UiHelper;
 import be.nikiroo.fanfix_swing.images.IconGenerator;
 import be.nikiroo.fanfix_swing.images.IconGenerator.Icon;
 import be.nikiroo.fanfix_swing.images.IconGenerator.Size;
 
-public abstract class BasicTab<T> extends JPanel {
+public abstract class BasicTab<T> extends ListenerPanel {
        private int totalCount = 0;
        private List<String> selectedElements = new ArrayList<String>();
        private T data;
@@ -40,6 +37,7 @@ public abstract class BasicTab<T> extends JPanel {
        private int index;
 
        private JTree tree;
+       private DefaultMutableTreeNode root;
        private SearchBar searchBar;
 
        public BasicTab(int index, String listenerCommand) {
@@ -51,11 +49,12 @@ public abstract class BasicTab<T> extends JPanel {
                data = createEmptyData();
                totalCount = 0;
 
-               final DefaultMutableTreeNode root = new DefaultMutableTreeNode();
+               root = new DefaultMutableTreeNode();
 
                tree = new JTree(root);
                tree.setUI(new BasicTreeUI());
-               TreeCellSpanner spanner = new TreeCellSpanner(tree, generateCellRenderer());
+               TreeCellSpanner spanner = new TreeCellSpanner(tree,
+                               generateCellRenderer());
                tree.setCellRenderer(spanner);
                tree.setRootVisible(false);
                tree.setShowsRootHandles(false);
@@ -81,7 +80,7 @@ public abstract class BasicTab<T> extends JPanel {
 
                                BasicTab.this.selectedElements = selectedElements;
 
-                               fireActionPerformed();
+                               fireActionPerformed(BasicTab.this.listenerCommand);
                        }
                });
 
@@ -92,27 +91,53 @@ public abstract class BasicTab<T> extends JPanel {
                searchBar.addActionListener(new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
-                               root.removeAllChildren();
-                               loadData(root, data, searchBar.getText());
-                               ((DefaultTreeModel) tree.getModel()).reload();
-                               fireActionPerformed();
+                               reloadData();
                        }
                });
 
+               reloadData();
+       }
+
+       public void reloadData() {
+               final TreeSnapshot snapshot = new TreeSnapshot(tree) {
+                       @Override
+                       protected boolean isSamePath(TreePath oldPath, TreePath newPath) {
+                               String oldString = oldPath.toString();
+                               if (oldString.endsWith("/]"))
+                                       oldString = oldString.substring(0, oldString.length() - 2)
+                                                       + "]";
+
+                               String newString = newPath.toString();
+                               if (newString.endsWith("/]"))
+                                       newString = newString.substring(0, newString.length() - 2)
+                                                       + "]";
+
+                               return oldString.equals(newString);
+                       }
+               };
                SwingWorker<Map<String, List<String>>, Integer> worker = new SwingWorker<Map<String, List<String>>, Integer>() {
                        @Override
-                       protected Map<String, List<String>> doInBackground() throws Exception {
-                               return Instance.getInstance().getLibrary().getSourcesGrouped();
+                       protected Map<String, List<String>> doInBackground()
+                                       throws Exception {
+                               fillData(data);
+                               return null;
                        }
 
                        @Override
                        protected void done() {
-                               fillData(data);
+                               try {
+                                       get();
+                               } catch (Exception e) {
+                                       // TODO: error
+                               }
+
                                root.removeAllChildren();
                                totalCount = loadData(root, data, searchBar.getText());
                                ((DefaultTreeModel) tree.getModel()).reload();
 
-                               fireActionPerformed();
+                               snapshot.apply();
+
+                               fireActionPerformed(listenerCommand);
                        }
                };
                worker.execute();
@@ -144,7 +169,8 @@ public abstract class BasicTab<T> extends JPanel {
                String count = "";
                if (totalCount > 0) {
                        int selected = selectedElements.size();
-                       count = " (" + (selected > 0 ? selected + "/" : "") + totalCount + ")";
+                       count = " (" + (selected > 0 ? selected + "/" : "") + totalCount
+                                       + ")";
                }
 
                return title + count;
@@ -158,41 +184,9 @@ public abstract class BasicTab<T> extends JPanel {
                tree.clearSelection();
        }
 
-       /**
-        * Adds the specified action listener to receive action events from this
-        * {@link SearchBar}.
-        *
-        * @param listener the action listener to be added
-        */
-       public synchronized void addActionListener(ActionListener listener) {
-               listenerList.add(ActionListener.class, listener);
-       }
-
-       /**
-        * Removes the specified action listener so that it no longer receives action
-        * events from this {@link SearchBar}.
-        *
-        * @param listener the action listener to be removed
-        */
-       public synchronized void removeActionListener(ActionListener listener) {
-               listenerList.remove(ActionListener.class, listener);
-       }
-
-       /**
-        * Notify the listeners of an action.
-        */
-       protected void fireActionPerformed() {
-               ActionEvent e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, listenerCommand);
-               Object[] listeners = listenerList.getListenerList();
-               for (int i = listeners.length - 2; i >= 0; i -= 2) {
-                       if (listeners[i] == ActionListener.class) {
-                               ((ActionListener) listeners[i + 1]).actionPerformed(e);
-                       }
-               }
-       }
-
        protected boolean checkFilter(String filter, String value) {
-               return (filter == null || filter.isEmpty() || value.toLowerCase().contains(filter.toLowerCase()));
+               return (filter == null || filter.isEmpty()
+                               || value.toLowerCase().contains(filter.toLowerCase()));
        }
 
        protected boolean checkFilter(String filter, List<String> list) {
@@ -205,18 +199,22 @@ public abstract class BasicTab<T> extends JPanel {
 
        protected abstract T createEmptyData();
 
+       // beware: you should update it OR clean/re-add it, but previous data may
+       // still be there
        protected abstract void fillData(T data);
 
        protected abstract String keyToElement(String key);
 
        protected abstract String keyToDisplay(String key);
 
-       protected abstract int loadData(DefaultMutableTreeNode root, T data, String filter);
+       protected abstract int loadData(DefaultMutableTreeNode root, T data,
+                       String filter);
 
        private TreeCellRenderer generateCellRenderer() {
                DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer() {
                        @Override
-                       public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded,
+                       public Component getTreeCellRendererComponent(JTree tree,
+                                       Object value, boolean selected, boolean expanded,
                                        boolean leaf, int row, boolean hasFocus) {
                                if (value instanceof DefaultMutableTreeNode) {
                                        if (((DefaultMutableTreeNode) value).getLevel() > 1) {
@@ -228,10 +226,10 @@ public abstract class BasicTab<T> extends JPanel {
                                }
 
                                String display = value == null ? "" : value.toString();
-                               if (!display.isEmpty())
-                                       display = keyToDisplay(display);
+                               display = keyToDisplay(display);
 
-                               return super.getTreeCellRendererComponent(tree, display, selected, expanded, leaf, row, hasFocus);
+                               return super.getTreeCellRendererComponent(tree, display,
+                                               selected, expanded, leaf, row, hasFocus);
                        }
                };