remove now duplicated utils from fanfix-swing (now in nikiroo-utils)
authorNiki Roo <niki@nikiroo.be>
Fri, 24 Apr 2020 15:42:43 +0000 (17:42 +0200)
committerNiki Roo <niki@nikiroo.be>
Fri, 24 Apr 2020 15:42:43 +0000 (17:42 +0200)
src/be/nikiroo/fanfix_swing/gui/utils/DelayWorker.java [deleted file]
src/be/nikiroo/fanfix_swing/gui/utils/ListModel.java [deleted file]
src/be/nikiroo/fanfix_swing/gui/utils/ListenerPanel.java [deleted file]
src/be/nikiroo/fanfix_swing/gui/utils/TreeCellSpanner.java [deleted file]
src/be/nikiroo/fanfix_swing/gui/utils/TreeModelTransformer.java [deleted file]
src/be/nikiroo/fanfix_swing/gui/utils/TreeSnapshot.java [deleted file]
src/be/nikiroo/fanfix_swing/gui/utils/UiHelper.java

diff --git a/src/be/nikiroo/fanfix_swing/gui/utils/DelayWorker.java b/src/be/nikiroo/fanfix_swing/gui/utils/DelayWorker.java
deleted file mode 100644 (file)
index 6d630c5..0000000
+++ /dev/null
@@ -1,220 +0,0 @@
-package be.nikiroo.fanfix_swing.gui.utils;
-
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.TreeSet;
-
-import javax.swing.SwingWorker;
-
-/**
- * This class helps you delay some graphical actions and execute the most recent
- * ones when under contention.
- * <p>
- * How does it work?
- * <ul>
- * <li>it takes an ID and an associated {@link SwingWorker} and will call
- * {@link SwingWorker#execute()} after a small delay (see
- * {@link DelayWorker#DelayWorker(int)})</li>
- * <li>if a second call to {@link DelayWorker#delay(String, SwingWorker)} comes
- * with the same ID before the first one is done, it will be put on a waiting
- * queue</li>
- * <li>if a third call still with the same ID comes, its associated worker will
- * <b>replace</b> the one in the queue (only one worker per ID in the queue,
- * always the latest one)</li>
- * <li>when the first worker is done, it will check the waiting queue and
- * execute that latest worker if any</li>
- * </ul>
- * 
- * @author niki
- *
- */
-@SuppressWarnings("rawtypes")
-public class DelayWorker {
-       private Map<String, SwingWorker> lazyEnCours;
-       private Object lazyEnCoursLock;
-
-       private TreeSet<String> wip;
-
-       private Object waiter;
-
-       private boolean cont;
-       private boolean paused;
-       private Thread loop;
-
-       /**
-        * Create a new {@link DelayWorker} with the given delay (in milliseconds)
-        * before each drain of the queue.
-        * 
-        * @param delayMs
-        *            the delay in milliseconds (can be 0, cannot be negative)
-        */
-       public DelayWorker(final int delayMs) {
-               if (delayMs < 0) {
-                       throw new IllegalArgumentException(
-                                       "A waiting delay cannot be negative");
-               }
-
-               lazyEnCours = new HashMap<String, SwingWorker>();
-               lazyEnCoursLock = new Object();
-               wip = new TreeSet<String>();
-               waiter = new Object();
-               cont = true;
-               paused = false;
-
-               loop = new Thread(new Runnable() {
-                       @Override
-                       public void run() {
-                               while (cont) {
-                                       try {
-                                               Thread.sleep(delayMs);
-                                       } catch (InterruptedException e) {
-                                       }
-
-                                       Map<String, SwingWorker> workers = new HashMap<String, SwingWorker>();
-                                       synchronized (lazyEnCoursLock) {
-                                               for (String key : new ArrayList<String>(
-                                                               lazyEnCours.keySet())) {
-                                                       if (!wip.contains(key)) {
-                                                               workers.put(key, lazyEnCours.remove(key));
-                                                       }
-                                               }
-                                       }
-
-                                       for (final String key : workers.keySet()) {
-                                               SwingWorker worker = workers.get(key);
-
-                                               synchronized (lazyEnCoursLock) {
-                                                       wip.add(key);
-                                               }
-
-                                               worker.addPropertyChangeListener(
-                                                               new PropertyChangeListener() {
-                                                                       @Override
-                                                                       public void propertyChange(
-                                                                                       PropertyChangeEvent evt) {
-                                                                               synchronized (lazyEnCoursLock) {
-                                                                                       wip.remove(key);
-                                                                               }
-                                                                               wakeup();
-                                                                       }
-                                                               });
-
-                                               // Start it, at last
-                                               worker.execute();
-                                       }
-
-                                       synchronized (waiter) {
-                                               do {
-                                                       try {
-                                                               if (cont)
-                                                                       waiter.wait();
-                                                       } catch (InterruptedException e) {
-                                                       }
-                                               } while (cont && paused);
-                                       }
-                               }
-                       }
-               });
-
-               loop.setDaemon(true);
-               loop.setName("Loop for DelayWorker");
-       }
-
-       /**
-        * Start the internal loop that will drain the processing queue. <b>MUST
-        * NOT</b> be started twice (but see {@link DelayWorker#pause()} and
-        * {@link DelayWorker#resume()} instead).
-        */
-       public void start() {
-               loop.start();
-       }
-
-       /**
-        * Pause the system until {@link DelayWorker#resume()} is called -- note
-        * that it will still continue on the processes currently scheduled to run,
-        * but will pause after that.
-        * <p>
-        * Can be called even if already paused, will just do nothing in that
-        * context.
-        */
-       public void pause() {
-               paused = true;
-       }
-
-       /**
-        * Check if the {@link DelayWorker} is currently paused.
-        * 
-        * @return TRUE if it is
-        */
-       public boolean isPaused() {
-               return paused;
-       }
-
-       /**
-        * Resume the system after a pause.
-        * <p>
-        * Can be called even if already running, will just do nothing in that
-        * context.
-        */
-       public void resume() {
-               synchronized (waiter) {
-                       paused = false;
-                       wakeup();
-               }
-       }
-
-       /**
-        * Stop the system.
-        * <p>
-        * Note: this is final, you <b>MUST NOT</b> call {@link DelayWorker#start()}
-        * a second time (but see {@link DelayWorker#pause()} and
-        * {@link DelayWorker#resume()} instead).
-        */
-       public void stop() {
-               synchronized (waiter) {
-                       cont = false;
-                       wakeup();
-               }
-       }
-
-       /**
-        * Clear all the processes that were put on the queue but not yet scheduled
-        * to be executed -- note that it will still continue on the processes
-        * currently scheduled to run.
-        */
-       public void clear() {
-               synchronized (lazyEnCoursLock) {
-                       lazyEnCours.clear();
-                       wip.clear();
-               }
-       }
-
-       /**
-        * Put a new process in the delay queue.
-        * 
-        * @param id
-        *            the ID of this process (if you want to skip workers when they
-        *            are superseded by a new one, you need to use the same ID key)
-        * @param worker
-        *            the process to delay
-        */
-       public void delay(final String id, final SwingWorker worker) {
-               synchronized (lazyEnCoursLock) {
-                       lazyEnCours.put(id, worker);
-               }
-
-               wakeup();
-       }
-
-       /**
-        * Wake up the loop thread.
-        */
-       private void wakeup() {
-               synchronized (waiter) {
-                       waiter.notifyAll();
-               }
-       }
-}
diff --git a/src/be/nikiroo/fanfix_swing/gui/utils/ListModel.java b/src/be/nikiroo/fanfix_swing/gui/utils/ListModel.java
deleted file mode 100644 (file)
index 6f9c196..0000000
+++ /dev/null
@@ -1,393 +0,0 @@
-package be.nikiroo.fanfix_swing.gui.utils;
-
-import java.awt.Component;
-import java.awt.Point;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import javax.swing.JList;
-import javax.swing.JPopupMenu;
-import javax.swing.ListCellRenderer;
-
-import be.nikiroo.utils.compat.DefaultListModel6;
-import be.nikiroo.utils.compat.JList6;
-import be.nikiroo.utils.compat.ListCellRenderer6;
-
-/**
- * A {@link javax.swing.ListModel} that can maintain 2 lists; one with the
- * actual data (the elements), and a second one with the items that are
- * currently displayed (the items).
- * <p>
- * It also offers filter options, supports hovered changes and some more utility
- * functions.
- * 
- * @author niki
- *
- * @param <T>
- *            the type of elements and items (the same type)
- */
-public class ListModel<T> extends DefaultListModel6<T> {
-       private static final long serialVersionUID = 1L;
-
-       /**
-        * A filter interface, to check for a condition (note that a Predicate class
-        * already exists in Java 1.8+, and is compatible with this one if you
-        * change the signatures -- but I support java 1.6+).
-        * 
-        * @author niki
-        *
-        * @param <T>
-        *            the type of elements and items (the same type)
-        */
-       public interface Predicate<T> {
-               /**
-                * Check if an item or an element pass a filter.
-                * 
-                * @param item
-                *            the item to test
-                * 
-                * @return TRUE if the test passed, FALSE if not
-                */
-               public boolean test(T item);
-       }
-
-       /**
-        * A simple interface your elements must implement if you want to use
-        * {@link ListModel#generateRenderer(ListModel)}.
-        * 
-        * @author niki
-        */
-       public interface Hoverable {
-               /**
-                * The element is currently selected.
-                * 
-                * @param selected
-                *            TRUE for selected, FALSE for unselected
-                */
-               public void setSelected(boolean selected);
-
-               /**
-                * The element is currently under the mouse cursor.
-                * 
-                * @param hovered
-                *            TRUE if it is, FALSE if not
-                */
-               public void setHovered(boolean hovered);
-       }
-
-       private int hoveredIndex;
-       private List<T> items = new ArrayList<T>();
-       private JList6<T> list;
-
-       /**
-        * Create a new {@link ListModel}.
-        * 
-        * @param list
-        *            the {@link JList} we will handle the data of (cannot be NULL)
-        */
-       @SuppressWarnings({ "unchecked", "rawtypes" }) // not compatible Java 1.6
-       public ListModel(JList list) {
-               this((JList6<T>) list);
-       }
-
-       /**
-        * Create a new {@link ListModel}.
-        * 
-        * @param list
-        *            the {@link JList} we will handle the data of (cannot be NULL)
-        * @param popup
-        *            the popup to use and keep track of (can be NULL)
-        */
-       @SuppressWarnings({ "unchecked", "rawtypes" }) // not compatible Java 1.6
-       public ListModel(final JList list, final JPopupMenu popup) {
-               this((JList6<T>) list, popup);
-       }
-
-       /**
-        * Create a new {@link ListModel}.
-        * 
-        * @param list
-        *            the {@link JList6} we will handle the data of (cannot be NULL)
-        */
-       public ListModel(JList6<T> list) {
-               this(list, null);
-       }
-
-       /**
-        * Create a new {@link ListModel}.
-        * 
-        * @param list
-        *            the {@link JList6} we will handle the data of (cannot be NULL)
-        * @param popup
-        *            the popup to use and keep track of (can be NULL)
-        */
-       public ListModel(final JList6<T> list, final JPopupMenu popup) {
-               this.list = list;
-               list.setModel(this);
-
-               list.addMouseMotionListener(new MouseAdapter() {
-                       @Override
-                       public void mouseMoved(MouseEvent me) {
-                               if (popup != null && popup.isShowing())
-                                       return;
-
-                               Point p = new Point(me.getX(), me.getY());
-                               int index = list.locationToIndex(p);
-                               if (index != hoveredIndex) {
-                                       int oldIndex = hoveredIndex;
-                                       hoveredIndex = index;
-                                       fireElementChanged(oldIndex);
-                                       fireElementChanged(index);
-                               }
-                       }
-               });
-
-               list.addMouseListener(new MouseAdapter() {
-                       @Override
-                       public void mousePressed(MouseEvent e) {
-                               check(e);
-                       }
-
-                       @Override
-                       public void mouseReleased(MouseEvent e) {
-                               check(e);
-                       }
-
-                       @Override
-                       public void mouseExited(MouseEvent e) {
-                               if (popup != null && popup.isShowing())
-                                       return;
-
-                               if (hoveredIndex > -1) {
-                                       int oldIndex = hoveredIndex;
-                                       hoveredIndex = -1;
-                                       fireElementChanged(oldIndex);
-                               }
-                       }
-
-                       private void check(MouseEvent e) {
-                               if (popup == null) {
-                                       return;
-                               }
-
-                               if (e.isPopupTrigger()) {
-                                       if (list.getSelectedIndices().length <= 1) {
-                                               list.setSelectedIndex(
-                                                               list.locationToIndex(e.getPoint()));
-                                       }
-
-                                       popup.show(list, e.getX(), e.getY());
-                               }
-                       }
-               });
-       }
-
-       /**
-        * Check if this element is currently under the mouse.
-        * 
-        * @param element
-        *            the element to check
-        * 
-        * @return TRUE if it is
-        */
-       public boolean isHovered(T element) {
-               return indexOf(element) == hoveredIndex;
-       }
-
-       /**
-        * Check if this element is currently under the mouse.
-        * 
-        * @param index
-        *            the index of the element to check
-        * 
-        * @return TRUE if it is
-        */
-       public boolean isHovered(int index) {
-               return index == hoveredIndex;
-       }
-
-       /**
-        * Add an item to the model.
-        * 
-        * @param item
-        *            the new item to add
-        */
-       public void addItem(T item) {
-               items.add(item);
-       }
-
-       /**
-        * Add items to the model.
-        * 
-        * @param items
-        *            the new items to add
-        */
-       public void addAllItems(Collection<T> items) {
-               this.items.addAll(items);
-       }
-
-       /**
-        * Removes the first occurrence of the specified element from this list, if
-        * it is present (optional operation).
-        * 
-        * @param item
-        *            the item to remove if possible (can be NULL)
-        * 
-        * @return TRUE if one element was removed, FALSE if not found
-        */
-       public boolean removeItem(T item) {
-               return items.remove(item);
-       }
-
-       /**
-        * Remove the items that pass the given filter (or all items if the filter
-        * is NULL).
-        * 
-        * @param filter
-        *            the filter (if the filter returns TRUE, the item will be
-        *            removed)
-        * 
-        * @return TRUE if at least one item was removed
-        */
-       public boolean removeItemIf(Predicate<T> filter) {
-               boolean changed = false;
-               if (filter == null) {
-                       changed = !items.isEmpty();
-                       clearItems();
-               } else {
-                       for (int i = 0; i < items.size(); i++) {
-                               if (filter.test(items.get(i))) {
-                                       items.remove(i--);
-                                       changed = true;
-                               }
-                       }
-               }
-
-               return changed;
-       }
-
-       /**
-        * Removes all the items from this model.
-        */
-       public void clearItems() {
-               items.clear();
-       }
-
-       /**
-        * Filter the current elements.
-        * <p>
-        * This method will clear all the elements then look into all the items:
-        * those that pass the given filter will be copied as elements.
-        * 
-        * @param filter
-        *            the filter to select which elements to keep; an item that pass
-        *            the filter will be copied as an element (can be NULL, in that
-        *            case all items will be copied as elements)
-        */
-       @SuppressWarnings("unchecked") // ListModel<T> and JList<T> are not java 1.6
-       public void filter(Predicate<T> filter) {
-               clear();
-               for (T item : items) {
-                       if (filter == null || filter.test(item)) {
-                               addElement(item);
-                       }
-               }
-
-               list.repaint();
-       }
-
-       /**
-        * Return the currently selected elements.
-        * 
-        * @return the selected elements
-        */
-       public List<T> getSelectedElements() {
-               List<T> selected = new ArrayList<T>();
-               for (int index : list.getSelectedIndices()) {
-                       selected.add(get(index));
-               }
-
-               return selected;
-       }
-
-       /**
-        * Return the selected element if <b>one</b> and <b>only one</b> element is
-        * selected. I.E., if zero, two or more elements are selected, NULL will be
-        * returned.
-        * 
-        * @return the element if it is the only selected element, NULL otherwise
-        */
-       public T getUniqueSelectedElement() {
-               List<T> selected = getSelectedElements();
-               if (selected.size() == 1) {
-                       return selected.get(0);
-               }
-
-               return null;
-       }
-
-       /**
-        * Notify that this element has been changed.
-        * 
-        * @param index
-        *            the index of the element
-        */
-       public void fireElementChanged(int index) {
-               if (index >= 0) {
-                       fireContentsChanged(this, index, index);
-               }
-       }
-
-       /**
-        * Notify that this element has been changed.
-        * 
-        * @param element
-        *            the element
-        */
-       public void fireElementChanged(T element) {
-               int index = indexOf(element);
-               if (index >= 0) {
-                       fireContentsChanged(this, index, index);
-               }
-       }
-
-       @SuppressWarnings("unchecked") // ListModel<T> and JList<T> are not java 1.6
-       @Override
-       public T get(int index) {
-               return (T) super.get(index);
-       }
-
-       /**
-        * Generate a {@link ListCellRenderer} that supports {@link Hoverable}
-        * elements.
-        * 
-        * @param <T>
-        *            the type of elements and items (the same type), which should
-        *            implement {@link Hoverable} (it will not cause issues if not,
-        *            but then, it will be a default renderer)
-        * @param model
-        *            the model to use
-        * 
-        * @return a suitable, {@link Hoverable} compatible renderer
-        */
-       static public <T extends Component> ListCellRenderer6<T> generateRenderer(
-                       final ListModel<T> model) {
-               return new ListCellRenderer6<T>() {
-                       @Override
-                       public Component getListCellRendererComponent(JList6<T> list,
-                                       T item, int index, boolean isSelected,
-                                       boolean cellHasFocus) {
-                               if (item instanceof Hoverable) {
-                                       Hoverable hoverable = (Hoverable) item;
-                                       hoverable.setSelected(isSelected);
-                                       hoverable.setHovered(model.isHovered(index));
-                               }
-
-                               return item;
-                       }
-               };
-       }
-}
diff --git a/src/be/nikiroo/fanfix_swing/gui/utils/ListenerPanel.java b/src/be/nikiroo/fanfix_swing/gui/utils/ListenerPanel.java
deleted file mode 100644 (file)
index 9dc8dfe..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-package be.nikiroo.fanfix_swing.gui.utils;
-
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.util.LinkedList;
-import java.util.Queue;
-
-import javax.swing.JPanel;
-
-/**
- * A {@link JPanel} with the default {@link ActionListener} add/remove/fire
- * methods.
- * <p>
- * Note that it will queue all events until at least one listener comes (or
- * comes back!); this first (or at least currently unique) listener will drain
- * the queue.
- * 
- * @author niki
- */
-public class ListenerPanel extends JPanel {
-       private static final long serialVersionUID = 1L;
-
-       /** Waiting queue until at least one listener is here to get the events. */
-       private final Queue<ActionEvent> waitingQueue;
-
-       /**
-        * Create a new {@link ListenerPanel}.
-        */
-       public ListenerPanel() {
-               waitingQueue = new LinkedList<ActionEvent>();
-       }
-
-       /**
-        * Check that this {@link ListenerPanel} currently has
-        * {@link ActionListener}s that listen on it.
-        * 
-        * @return TRUE if it has
-        */
-       public synchronized boolean hasListeners() {
-               return listenerList.getListenerList().length > 1;
-       }
-
-       /**
-        * Check how many events are currently waiting for an
-        * {@link ActionListener}.
-        * 
-        * @return the number of waiting events (can be 0)
-        */
-       public synchronized int getWaitingEventCount() {
-               return waitingQueue.size();
-       }
-
-       /**
-        * Adds the specified action listener to receive action events from this
-        * {@link ListenerPanel}.
-        *
-        * @param listener
-        *            the action listener to be added
-        */
-       public synchronized void addActionListener(ActionListener listener) {
-               if (!hasListeners()) {
-                       while (!waitingQueue.isEmpty()) {
-                               listener.actionPerformed(waitingQueue.remove());
-                       }
-               }
-
-               listenerList.add(ActionListener.class, listener);
-       }
-
-       /**
-        * Removes the specified action listener so that it no longer receives
-        * action events from this {@link ListenerPanel}.
-        *
-        * @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.
-        * 
-        * @param listenerCommand
-        *            A string that may specify a command (possibly one of several)
-        *            associated with the event
-        */
-       protected synchronized void fireActionPerformed(String listenerCommand) {
-               ActionEvent e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
-                               listenerCommand);
-
-               ActionListener[] listeners = getListeners(ActionListener.class);
-               if (listeners.length > 0) {
-                       for (ActionListener action : listeners) {
-                               action.actionPerformed(e);
-                       }
-               } else {
-                       waitingQueue.add(e);
-               }
-       }
-}
diff --git a/src/be/nikiroo/fanfix_swing/gui/utils/TreeCellSpanner.java b/src/be/nikiroo/fanfix_swing/gui/utils/TreeCellSpanner.java
deleted file mode 100644 (file)
index d3a7a84..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- *    This program is free software: you can redistribute it and/or modify
- *    it under the terms of the GNU Lesser General Public License as published
- *    by the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
- *
- *    You should have received a copy of the GNU Lesser General Public License
- *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-// Can be found at: https://code.google.com/archive/p/aephyr/source/default/source
-// package aephyr.swing;
-package be.nikiroo.fanfix_swing.gui.utils;
-
-import java.awt.*;
-import java.awt.event.*;
-
-import javax.swing.*;
-import javax.swing.tree.*;
-
-import java.util.*;
-
-public class TreeCellSpanner extends Container implements TreeCellRenderer, ComponentListener {
-       
-       public TreeCellSpanner(JTree tree, TreeCellRenderer renderer) {
-               if (tree == null || renderer == null)
-                       throw new NullPointerException();
-               this.tree = tree;
-               this.renderer = renderer;
-               treeParent = tree.getParent();
-               if (treeParent != null && treeParent instanceof JViewport) {
-                       treeParent.addComponentListener(this);
-               } else {
-                       treeParent = null;
-                       tree.addComponentListener(this);
-               }
-       }
-       
-       protected final JTree tree;
-       
-       private TreeCellRenderer renderer;
-       
-       private Component rendererComponent;
-       
-       private Container treeParent;
-       
-       private Map<TreePath,Integer> offsets = new HashMap<TreePath,Integer>();
-       
-       private TreePath path;
-       
-       public TreeCellRenderer getRenderer() {
-               return renderer;
-       }
-       
-       @Override
-       public Component getTreeCellRendererComponent(JTree tree, Object value,
-                       boolean selected, boolean expanded, boolean leaf, int row,
-                       boolean hasFocus) {
-               path = tree.getPathForRow(row);
-               if (path != null && path.getLastPathComponent() != value)
-                       path = null;
-               rendererComponent = renderer.getTreeCellRendererComponent(
-                               tree, value, selected, expanded, leaf, row, hasFocus);
-               if (getComponentCount() < 1 || getComponent(0) != rendererComponent) {
-                       removeAll();
-                       add(rendererComponent);
-               }
-               return this;
-       }
-       
-       @Override
-       public void doLayout() {
-               int x = getX();
-               if (x < 0)
-                       return;
-               if (path != null) {
-                       Integer offset = offsets.get(path);
-                       if (offset == null || offset.intValue() != x) {
-                               offsets.put(path, x);
-                               fireTreePathChanged(path);
-                       }
-               }
-               rendererComponent.setBounds(getX(), getY(), getWidth(), getHeight());
-       }
-       
-       @Override
-       public void paint(Graphics g) {
-               if (rendererComponent != null)
-                       rendererComponent.paint(g);
-       }
-       
-       @Override
-       public Dimension getPreferredSize() {
-               Dimension s = rendererComponent.getPreferredSize();
-               // check if path count is greater than 1 to exclude the root
-               if (path != null && path.getPathCount() > 1) {
-                       Integer offset = offsets.get(path);
-                       if (offset != null) {
-                               int width;
-                               if (tree.getParent() == treeParent) {
-                                       width = treeParent.getWidth();
-                               } else {
-                                       if (treeParent != null) {
-                                               treeParent.removeComponentListener(this);
-                                               tree.addComponentListener(this);
-                                               treeParent = null;
-                                       }
-                                       if (tree.getParent() instanceof JViewport) {
-                                               treeParent = tree.getParent();
-                                               tree.removeComponentListener(this);
-                                               treeParent.addComponentListener(this);
-                                               width = treeParent.getWidth();
-                                       } else {
-                                               width = tree.getWidth();
-                                       }
-                               }
-                               s.width = width - offset;
-                       }
-               }
-               return s;
-       }
-
-       
-       protected void fireTreePathChanged(TreePath path) {
-               if (path.getPathCount() > 1) {
-                       // this cannot be used for the root node or else
-                       // the entire tree will keep being revalidated ad infinitum
-                       TreeModel model = tree.getModel();
-                       Object node = path.getLastPathComponent();
-                       if (node instanceof TreeNode && (model instanceof DefaultTreeModel
-                                       || (model instanceof TreeModelTransformer<?> &&
-                                       (model=((TreeModelTransformer<?>)model).getModel()) instanceof DefaultTreeModel))) {
-                               ((DefaultTreeModel)model).nodeChanged((TreeNode)node);
-                       } else {
-                               model.valueForPathChanged(path, node.toString());
-                       }
-               } else {
-                       // root!
-                       
-               }
-       }
-
-       
-       private int lastWidth;
-
-       @Override
-       public void componentHidden(ComponentEvent e) {}
-
-       @Override
-       public void componentMoved(ComponentEvent e) {}
-
-       @Override
-       public void componentResized(ComponentEvent e) {
-               if (e.getComponent().getWidth() != lastWidth) {
-                       lastWidth = e.getComponent().getWidth();
-                       for (int row=tree.getRowCount(); --row>=0;) {
-                               fireTreePathChanged(tree.getPathForRow(row));
-                       }
-               }
-       }
-
-       @Override
-       public void componentShown(ComponentEvent e) {}
-       
-}
diff --git a/src/be/nikiroo/fanfix_swing/gui/utils/TreeModelTransformer.java b/src/be/nikiroo/fanfix_swing/gui/utils/TreeModelTransformer.java
deleted file mode 100644 (file)
index b339f66..0000000
+++ /dev/null
@@ -1,1217 +0,0 @@
-/*
- *    This program is free software: you can redistribute it and/or modify
- *    it under the terms of the GNU Lesser General Public License as published
- *    by the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
- *
- *    You should have received a copy of the GNU Lesser General Public License
- *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-// Can be found at: https://code.google.com/archive/p/aephyr/source/default/source
-// package aephyr.swing;
-package be.nikiroo.fanfix_swing.gui.utils;
-
-import java.text.Collator;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.swing.JTree;
-import javax.swing.SortOrder;
-import javax.swing.event.EventListenerList;
-import javax.swing.event.TreeExpansionEvent;
-import javax.swing.event.TreeExpansionListener;
-import javax.swing.event.TreeModelEvent;
-import javax.swing.event.TreeModelListener;
-import javax.swing.event.TreeWillExpandListener;
-import javax.swing.tree.ExpandVetoException;
-import javax.swing.tree.TreeModel;
-import javax.swing.tree.TreePath;
-
-
-public class TreeModelTransformer<N> implements TreeModel {
-
-       public TreeModelTransformer(JTree tree, TreeModel model) {
-               if (tree == null)
-                       throw new IllegalArgumentException();
-               if (model == null)
-                       throw new IllegalArgumentException();
-               this.tree = tree;
-               this.model = model;
-               handler = createHandler();
-               addListeners();
-       }
-       
-       private JTree tree;
-       
-       private TreeModel model;
-
-       private Handler handler;
-       
-       private Filter<N> filter;
-       
-       private TreePath filterStartPath;
-       
-       private int filterDepthLimit;
-       
-       private SortOrder sortOrder = SortOrder.UNSORTED;
-       
-       private Map<Object,Converter> converters;
-       
-       protected EventListenerList listenerList = new EventListenerList();
-
-       protected Handler createHandler() {
-               return new Handler();
-       }
-       
-       protected void addListeners() {
-               tree.addTreeExpansionListener(handler);
-               model.addTreeModelListener(handler);
-       }
-
-       protected void removeListeners() {
-               tree.removeTreeExpansionListener(handler);
-               model.removeTreeModelListener(handler);
-       }
-       
-       public void dispose() {
-               removeListeners();
-       }
-       
-       public TreeModel getModel() {
-               return model;
-       }
-
-       private Converter getConverter(Object node) {
-               return converters == null ? null : converters.get(node);
-       }
-
-       int convertRowIndexToView(Object parent, int index) {
-               Converter converter = getConverter(parent);
-               if (converter != null)
-                       return converter.convertRowIndexToView(index);
-               return index;
-       }
-
-       int convertRowIndexToModel(Object parent, int index) {
-               Converter converter = getConverter(parent);
-               if (converter != null)
-                       return converter.convertRowIndexToModel(index);
-               return index;
-       }
-
-       @Override
-       public Object getChild(Object parent, int index) {
-               return model.getChild(parent, convertRowIndexToModel(parent, index));
-       }
-
-       @Override
-       public int getChildCount(Object parent) {
-               Converter converter = getConverter(parent);
-               if (converter != null)
-                       return converter.getChildCount();
-               return model.getChildCount(parent);
-       }
-
-       @Override
-       public int getIndexOfChild(Object parent, Object child) {
-               int index = model.getIndexOfChild(parent, child);
-               if (index < 0)
-                       return -1;
-               return convertRowIndexToView(parent, index);
-       }
-
-       @Override
-       public Object getRoot() {
-               return model.getRoot();
-       }
-
-       @Override
-       public boolean isLeaf(Object node) {
-               return model.isLeaf(node);
-       }
-
-       @Override
-       public void valueForPathChanged(TreePath path, Object newValue) {
-               model.valueForPathChanged(path, newValue);
-       }
-
-       @Override
-       public void addTreeModelListener(TreeModelListener l) {
-               listenerList.add(TreeModelListener.class, l);
-       }
-       
-       @Override
-       public void removeTreeModelListener(TreeModelListener l) {
-               listenerList.remove(TreeModelListener.class, l);
-       }
-       
-       /**
-        * Set the comparator that compares nodes in sorting.
-        * @param comparator
-        * @see #getComparator()
-        */
-       public void setComparator(Comparator<N> comparator) {
-               handler.setComparator(comparator);
-       }
-       
-       /**
-        * @return comparator that compares nodes
-        * @see #setComparator(Comparator)
-        */
-       public Comparator<N> getComparator() {
-               return handler.getComparator();
-       }
-       
-       public void setSortOrder(SortOrder newOrder) {
-               SortOrder oldOrder = sortOrder;
-               if (oldOrder == newOrder)
-                       return;
-               sortOrder = newOrder;
-               ArrayList<TreePath> paths = null;
-               switch (newOrder) {
-               case ASCENDING:
-                       if (oldOrder == SortOrder.DESCENDING) {
-                               flip();
-                       } else {
-                               paths = sort();
-                       }
-                       break;
-               case DESCENDING:
-                       if (oldOrder == SortOrder.ASCENDING) {
-                               flip();
-                       } else {
-                               paths = sort();
-                       }
-                       break;
-               case UNSORTED:
-                       unsort();
-                       break;
-               }
-               fireTreeStructureChangedAndExpand(new TreePath(getRoot()), paths, true);
-       }
-       
-       public SortOrder getSortOrder() {
-               return sortOrder;
-       }
-       
-       public void toggleSortOrder() {
-               setSortOrder(sortOrder == SortOrder.ASCENDING ?
-                               SortOrder.DESCENDING : SortOrder.ASCENDING);
-       }
-       
-       
-       /**
-        * Flip all sorted paths.
-        */
-       private void flip() {
-               for (Converter c : converters.values()) {
-                       flip(c.viewToModel);
-               }
-       }
-
-       /**
-        * Flip array.
-        * @param array
-        */
-       private static void flip(int[] array) {
-               for (int left=0, right=array.length-1;
-                               left<right; left++, right--) {
-                       int tmp = array[left];
-                       array[left] = array[right];
-                       array[right] = tmp;
-               }
-       }
-       
-       private void unsort() {
-               if (filter == null) {
-                       converters = null;
-               } else {
-                       Iterator<Converter> cons = converters.values().iterator();
-                       while (cons.hasNext()) {
-                               Converter converter = cons.next();
-                               if (!converter.isFiltered()) {
-                                       cons.remove();
-                               } else {
-                                       Arrays.sort(converter.viewToModel);
-                               }
-                       }
-               }
-       }
-       
-       /**
-        * Sort root and expanded descendants.
-        * @return list of paths that were sorted
-        */
-       private ArrayList<TreePath> sort() {
-               if (converters == null)
-                       converters = createConvertersMap(); //new IdentityHashMap<Object,Converter>();
-               return sortHierarchy(new TreePath(model.getRoot()));
-       }
-
-       /**
-        * Sort path and expanded descendants.
-        * @param path
-        * @return list of paths that were sorted
-        */
-       private ArrayList<TreePath> sortHierarchy(TreePath path) {
-               ValueIndexPair<N>[] pairs = createValueIndexPairArray(20);
-               ArrayList<TreePath> list = new ArrayList<TreePath>();
-               pairs = sort(path.getLastPathComponent(), pairs);
-               list.add(path);
-               Enumeration<TreePath> paths = tree.getExpandedDescendants(path);
-               if (paths != null)
-                       while (paths.hasMoreElements()) {
-                               path = paths.nextElement();
-                               pairs = sort(path.getLastPathComponent(), pairs);
-                               list.add(path);
-                       }
-               return list;
-       }
-       
-       private ValueIndexPair<N>[] sort(Object node, ValueIndexPair<N>[] pairs) {
-               Converter converter = getConverter(node);
-               TreeModel mdl = model;
-               int[] vtm;
-               if (converter != null) {
-                       vtm = converter.viewToModel;
-                       if (pairs.length < vtm.length)
-                               pairs = createValueIndexPairArray(vtm.length);
-                       for (int i=vtm.length; --i>=0;) {
-                               int idx = vtm[i];
-                               pairs[i].index = idx;
-                               pairs[i].value = (N)mdl.getChild(node, idx);
-                       }
-               } else {
-                       int count = mdl.getChildCount(node);
-                       if (count <= 0)
-                               return pairs;
-                       if (pairs.length < count)
-                               pairs = createValueIndexPairArray(count);
-                       for (int i=count; --i>=0;) {
-                               pairs[i].index = i;
-                               pairs[i].value = (N)mdl.getChild(node, i);
-                       }
-                       vtm = new int[count];
-               }
-               Arrays.sort(pairs, 0, vtm.length, handler);
-               for (int i=vtm.length; --i>=0;)
-                       vtm[i] = pairs[i].index;
-               if (converter == null) {
-                       converters.put(node, new Converter(vtm, false));
-               }
-               if (sortOrder == SortOrder.DESCENDING)
-                       flip(vtm);
-               return pairs;
-       }
-       
-       private ValueIndexPair<N>[] createValueIndexPairArray(int len) {
-               ValueIndexPair<N>[] pairs = new ValueIndexPair[len];
-               for (int i=len; --i>=0;)
-                       pairs[i] = new ValueIndexPair<N>();
-               return pairs;
-       }
-       
-       public void setFilter(Filter<N> filter) {
-               setFilter(filter, null);
-       }
-       
-       public void setFilter(Filter<N> filter, TreePath startingPath) {
-               setFilter(filter, null, -1);
-       }
-       
-       public void setFilter(Filter<N> filter, TreePath startingPath, int depthLimit) {
-               if (filter == null && startingPath != null)
-                       throw new IllegalArgumentException();
-               if (startingPath != null && startingPath.getPathCount() == 1)
-                       startingPath = null;
-               Filter<N> oldFilter = this.filter;
-               TreePath oldStartPath = filterStartPath;
-               this.filter = filter;
-               filterStartPath = startingPath;
-               filterDepthLimit = depthLimit;
-               applyFilter(oldFilter, oldStartPath, null, true);
-       }
-       
-       public Filter<N> getFilter() {
-               return filter;
-       }
-       
-       public TreePath getFilterStartPath() {
-               return filterStartPath;
-       }
-       
-       private void applyFilter(Filter<N> oldFilter, TreePath oldStartPath, Collection<TreePath> expanded, boolean sort) {
-               TreePath startingPath = filterStartPath;
-               ArrayList<TreePath> expand = null;
-               if (filter == null) {
-                       converters = null;
-               } else {
-                       if (converters == null || startingPath == null) {
-                               converters = createConvertersMap();
-                       } else if (oldFilter != null) {
-                               // unfilter the oldStartPath if oldStartPath isn't descendant of startingPath
-                               if (oldStartPath == null) {
-                                       converters = createConvertersMap();
-                                       fireTreeStructureChangedAndExpand(new TreePath(getRoot()), null, true);
-                               } else if (!startingPath.isDescendant(oldStartPath)) {
-                                       Object node = oldStartPath.getLastPathComponent();
-                                       handler.removeConverter(getConverter(node), node);
-                                       fireTreeStructureChangedAndExpand(oldStartPath, null, true);
-                               }
-                       }
-                       expand = new ArrayList<TreePath>();
-                       TreePath path = startingPath != null ? startingPath : new TreePath(getRoot());
-                       if (!applyFilter(filter, path, expand, filterDepthLimit)) {
-                               converters.put(path.getLastPathComponent(), new Converter(Converter.EMPTY, true));
-                       }
-               }
-               if (startingPath == null)
-                       startingPath = new TreePath(getRoot());
-               fireTreeStructureChanged(startingPath);
-               if (expanded != null)
-                       expand.retainAll(expanded);
-               expandPaths(expand);
-               if (sort && sortOrder != SortOrder.UNSORTED) {
-                       if (filter == null)
-                               converters = createConvertersMap();
-                       if (startingPath.getPathCount() > 1 && oldFilter != null) {
-                               // upgrade startingPath or sort oldStartPath
-                               if (oldStartPath == null) {
-                                       startingPath = new TreePath(getRoot());
-                               } else if (oldStartPath.isDescendant(startingPath)) {
-                                       startingPath = oldStartPath;
-                               } else if (!startingPath.isDescendant(oldStartPath)) {
-                                       expand = sortHierarchy(oldStartPath);
-                                       fireTreeStructureChanged(oldStartPath);
-                                       expandPaths(expand);
-                               }
-                       }
-                       expand = sortHierarchy(startingPath);
-                       fireTreeStructureChanged(startingPath);
-                       expandPaths(expand);
-               }
-
-       }
-       
-       private boolean applyFilter(Filter<N> filter, TreePath path, ArrayList<TreePath> expand) {
-               int depthLimit = filterDepthLimit;
-               if (depthLimit >= 0) {
-                       depthLimit -= filterStartPath.getPathCount() - path.getPathCount();
-                       if (depthLimit <= 0)
-                               return false;
-               }
-               return applyFilter(filter, path, expand, depthLimit);
-       }
-       
-       private boolean applyFilter(Filter<N> filter, TreePath path, ArrayList<TreePath> expand, int depthLimit) {
-               Object node = path.getLastPathComponent();
-               int count = model.getChildCount(node);
-               int[] viewToModel = null;
-               int viewIndex = 0;
-               boolean needsExpand = false;
-               boolean isExpanded = false;
-               if (depthLimit > 0)
-                       depthLimit--;
-               for (int i=0; i<count; i++) {
-                       Object child = model.getChild(node, i);
-                       boolean leaf = model.isLeaf(child);
-                       if (filter.acceptNode(path, (N)child, leaf)) {
-                               if (viewToModel == null)
-                                       viewToModel = new int[count-i];
-                               viewToModel[viewIndex++] = i;
-                               needsExpand = true;
-                       } else if (depthLimit != 0 && !leaf) {
-                               if (applyFilter(filter, path.pathByAddingChild(child), expand, depthLimit)) {
-                                       if (viewToModel == null)
-                                               viewToModel = new int[count-i];
-                                       viewToModel[viewIndex++] = i;
-                                       isExpanded = true;
-                               }
-                       }
-               }
-               if (needsExpand && expand != null && !isExpanded && path.getPathCount() > 1) {
-                       expand.add(path);
-               }
-               if (viewToModel != null) {
-                       if (viewIndex < viewToModel.length)
-                               viewToModel = Arrays.copyOf(viewToModel, viewIndex);
-                       // a node must have a converter to signify that tree modifications
-                       // need to query the filter, so have to put in converter
-                       // even if viewIndex == viewToModel.length
-                       converters.put(node, new Converter(viewToModel, true));
-                       return true;
-               }
-               return false;
-       }
-
-       
-       private void expandPaths(ArrayList<TreePath> paths) {
-               if (paths == null || paths.isEmpty())
-                       return;
-               JTree tre = tree;
-               for (TreePath path : paths)
-                       tre.expandPath(path);
-       }
-       
-       
-       private void fireTreeStructureChangedAndExpand(TreePath path, ArrayList<TreePath> list, boolean retainSelection) {
-               Enumeration<TreePath> paths = list != null ?
-                               Collections.enumeration(list) : tree.getExpandedDescendants(path);
-               TreePath[] sel = retainSelection ? tree.getSelectionPaths() : null;
-               fireTreeStructureChanged(path);
-               if (paths != null)
-                       while (paths.hasMoreElements())
-                               tree.expandPath(paths.nextElement());
-               if (sel != null)
-                       tree.setSelectionPaths(sel);
-       }
-
-       
-       
-       protected void fireTreeStructureChanged(TreePath path) {
-               Object[] listeners = listenerList.getListenerList();
-               TreeModelEvent e = null;
-               for (int i = listeners.length-2; i>=0; i-=2) {
-                       if (listeners[i]==TreeModelListener.class) {
-                               if (e == null)
-                                       e = new TreeModelEvent(this, path, null, null);
-                               ((TreeModelListener)listeners[i+1]).treeStructureChanged(e);
-                       }
-               }
-       }
-       
-       protected void fireTreeNodesChanged(TreePath path, int[] childIndices, Object[] childNodes) {
-               Object[] listeners = listenerList.getListenerList();
-               TreeModelEvent e = null;
-               for (int i = listeners.length-2; i>=0; i-=2) {
-                       if (listeners[i]==TreeModelListener.class) {
-                               if (e == null)
-                                       e = new TreeModelEvent(this, path, childIndices, childNodes);
-                               ((TreeModelListener)listeners[i+1]).treeNodesChanged(e);
-                       }
-               }
-       }
-       
-       protected void fireTreeNodesInserted(TreePath path, int[] childIndices, Object[] childNodes) {
-               Object[] listeners = listenerList.getListenerList();
-               TreeModelEvent e = null;
-               for (int i = listeners.length-2; i>=0; i-=2) {
-                       if (listeners[i]==TreeModelListener.class) {
-                               if (e == null)
-                                       e = new TreeModelEvent(this, path, childIndices, childNodes);
-                               ((TreeModelListener)listeners[i+1]).treeNodesInserted(e);
-                       }
-               }
-       }
-
-       protected void fireTreeNodesRemoved(TreePath path, int[] childIndices, Object[] childNodes) {
-               Object[] listeners = listenerList.getListenerList();
-               TreeModelEvent e = null;
-               for (int i = listeners.length-2; i>=0; i-=2) {
-                       if (listeners[i]==TreeModelListener.class) {
-                               if (e == null)
-                                       e = new TreeModelEvent(this, path, childIndices, childNodes);
-                               ((TreeModelListener)listeners[i+1]).treeNodesRemoved(e);
-                       }
-               }
-       }
-       
-       
-       protected class Handler implements Comparator<ValueIndexPair<N>>,
-                       TreeModelListener, TreeExpansionListener {
-               
-               private Comparator<N> comparator;
-               
-               private Collator collator = Collator.getInstance();
-               
-               void setComparator(Comparator<N> cmp) {
-                       comparator = cmp;
-                       collator = cmp == null ? Collator.getInstance() : null;
-               }
-               
-               Comparator<N> getComparator() {
-                       return comparator;
-               }
-               
-               // TODO, maybe switch to TreeWillExpandListener?
-               // TreeExpansionListener was used in case an expanded node
-               // had children that would also be expanded, but it is impossible
-               // for hidden nodes' expansion state to survive a SortOrder change
-               // since they are all erased when the tree structure change event
-               // is fired after changing the SortOrder.
-               
-               @Override
-               public void treeCollapsed(TreeExpansionEvent e) {}
-
-               @Override
-               public void treeExpanded(TreeExpansionEvent e) {
-                       if (sortOrder != SortOrder.UNSORTED) {
-                               TreePath path = e.getPath();
-                               Converter converter = getConverter(path.getLastPathComponent());
-                               if (converter == null) {
-                                       ArrayList<TreePath> paths = sortHierarchy(path);
-                                       fireTreeStructureChangedAndExpand(path, paths, false);
-                               }
-                       }
-               }
-               
-               private boolean isFiltered(Object node) {
-                       Converter c = getConverter(node);
-                       return c == null ? false : c.isFiltered();
-               }
-               
-               private boolean acceptable(TreePath path, Object[] childNodes, int index, ArrayList<TreePath> expand) {
-                       return acceptable(path, childNodes, index) ||
-                                       applyFilter(filter, path.pathByAddingChild(childNodes[index]), expand);
-               }
-               
-               @Override
-               public void treeNodesChanged(TreeModelEvent e) {
-                       treeNodesChanged(e.getTreePath(), e.getChildIndices(), e.getChildren());
-               }
-               
-               protected void treeNodesChanged(TreePath path, int[] childIndices, Object[] childNodes) {
-                       if (childIndices == null) {
-                               // path should be root path
-                               // reapply filter
-                               if (filter != null)
-                                       applyFilter(null, null, null, true);
-                               return;
-                       }
-                       Converter converter = getConverter(path.getLastPathComponent());
-                       ArrayList<TreePath> expand = null;
-                       if (converter != null) {
-                               expand = new ArrayList<TreePath>();
-                               int childIndex = 0;
-                               for (int i=0; i<childIndices.length; i++) {
-                                       int idx = converter.convertRowIndexToView(childIndices[i]);
-                                       if (idx >= 0) {
-                                               // see if the filter dislikes the nodes new state
-                                               if (converter.isFiltered() &&
-                                                               !isFiltered(childNodes[i]) &&
-                                                               !acceptable(path, childNodes, i)) {
-                                                       // maybe it likes a child nodes state
-                                                       if (!applyFilter(filter, path.pathByAddingChild(childNodes[i]), expand))
-                                                               remove(path, childNodes[i]);
-                                                       continue;
-                                               }
-                                               childNodes[childIndex] = childNodes[i];
-                                               childIndices[childIndex++] = idx;
-                                       } else if (acceptable(path, childNodes, i, expand)) {
-                                               int viewIndex = insert(path.getLastPathComponent(),
-                                                               childNodes[i], childIndices[i], converter);
-                                               fireTreeNodesInserted(path, indices(viewIndex), nodes(childNodes[i]));
-                                       }
-                               }
-                               if (childIndex == 0) {
-                                       maybeFireStructureChange(path, expand);
-                                       return;
-                               }
-                               if (sortOrder != SortOrder.UNSORTED && converter.getChildCount() > 1) {
-                                       sort(path.getLastPathComponent(), createValueIndexPairArray(converter.getChildCount()));
-                                       fireTreeStructureChangedAndExpand(path, null, true);
-                                       expandPaths(expand);
-                                       return;
-                               }
-                               if (childIndex != childIndices.length) {
-                                       childIndices = Arrays.copyOf(childIndices, childIndex);
-                                       childNodes = Arrays.copyOf(childNodes, childIndex);
-                               }
-                       } else if (filter != null && isFilteredOut(path)) {
-                               // see if the filter likes the nodes new states
-                               expand = new ArrayList<TreePath>();
-                               int[] vtm = null;
-                               int idx = 0;
-                               for (int i=0; i<childIndices.length; i++) {
-                                       if (acceptable(path, childNodes, i, expand)) {
-                                               if (vtm == null)
-                                                       vtm = new int[childIndices.length-i];
-                                               vtm[idx++] = childIndices[i];
-                                       }
-                               }
-                               // filter in path if appropriate
-                               if (vtm != null)
-                                       filterIn(vtm, idx, path, expand);
-                               return;
-                       }
-                       // must fire tree nodes changed even if a
-                       // structure change will be fired because the
-                       // expanded paths need to be updated first
-                       fireTreeNodesChanged(path, childIndices, childNodes);
-                       maybeFireStructureChange(path, expand);
-               }
-               
-               /**
-                * Helper method for treeNodesChanged...
-                * @param path
-                * @param expand
-                */
-               private void maybeFireStructureChange(TreePath path, ArrayList<TreePath> expand) {
-                       if (expand != null && !expand.isEmpty()) {
-                               Enumeration<TreePath> expanded = tree.getExpandedDescendants(path);
-                               fireTreeStructureChanged(path);
-                               if (expanded != null)
-                                       while (expanded.hasMoreElements())
-                                               tree.expandPath(expanded.nextElement());
-                               expandPaths(expand);
-                       }
-               }
-               
-               @Override
-               public void treeNodesInserted(TreeModelEvent e) {
-                       treeNodesInserted(e.getTreePath(), e.getChildIndices(), e.getChildren());
-               }
-
-               protected void treeNodesInserted(TreePath path, int[] childIndices, Object[] childNodes) {
-                       Object parent = path.getLastPathComponent();
-                       Converter converter = getConverter(parent);
-                       ArrayList<TreePath> expand = null;
-                       if (converter != null) {
-//                             if (childIndices.length > 3 && !converter.isFiltered()
-//                                             && childIndices.length > converter.getChildCount()/10) {
-//                                     TreePath expand = sortHierarchy(path);
-//                                     fireTreeStructureChangedAndExpand(expand);
-//                                     return;
-//                             }
-                               int childIndex = 0;
-                               for (int i=0; i<childIndices.length; i++) {
-                                       if (converter.isFiltered()) {
-                                               // path hasn't met the filter criteria, so childNodes must be filtered
-                                               if (expand == null)
-                                                       expand = new ArrayList<TreePath>();
-                                               if (!applyFilter(filter, path.pathByAddingChild(childNodes[i]), expand))
-                                                       continue;
-                                       }
-                                       // shift the appropriate cached modelIndices
-                                       int[] vtm = converter.viewToModel;
-                                       int modelIndex = childIndices[i];
-                                       for (int j=vtm.length; --j>=0;) {
-                                               if (vtm[j] >= modelIndex)
-                                                       vtm[j] += 1;
-                                       }
-                                       // insert modelIndex to converter
-                                       int viewIndex = insert(parent, childNodes[i], modelIndex, converter);
-                                       childNodes[childIndex] = childNodes[i];
-                                       childIndices[childIndex++] = viewIndex;
-                               }
-                               if (childIndex == 0)
-                                       return;
-                               if (childIndex != childIndices.length) {
-                                       childIndices = Arrays.copyOf(childIndices, childIndex);
-                                       childNodes = Arrays.copyOf(childNodes, childIndex);
-                               }
-                               if (childIndex > 1 && sortOrder != SortOrder.UNSORTED) {
-                                       sort(childIndices, childNodes);
-                               }
-                       } else if (filter != null && isFilteredOut(path)) {
-                               // apply filter to inserted nodes
-                               int[] vtm = null;
-                               int idx = 0;
-                               expand = new ArrayList<TreePath>();
-                               for (int i=0; i<childIndices.length; i++) {
-                                       if (acceptable(path, childNodes, i, expand)) {
-                                               if (vtm == null)
-                                                       vtm = new int[childIndices.length-i];
-                                               vtm[idx++] = childIndices[i];
-                                       }
-                               }
-                               // filter in path if appropriate
-                               if (vtm != null)
-                                       filterIn(vtm, idx, path, expand);
-                               return;
-                       }
-                       fireTreeNodesInserted(path, childIndices, childNodes);
-                       expandPaths(expand);
-               }
-               
-               @Override
-               public void treeNodesRemoved(TreeModelEvent e) {
-                       treeNodesRemoved(e.getTreePath(), e.getChildIndices(), e.getChildren());
-               }
-               
-
-               private boolean isFilterStartPath(TreePath path) {
-                       if (filterStartPath == null)
-                               return path.getPathCount() == 1;
-                       return filterStartPath.equals(path);
-               }
-               
-               protected void treeNodesRemoved(TreePath path, int[] childIndices, Object[] childNodes) {
-                       Object parent = path.getLastPathComponent();
-                       Converter converter = getConverter(parent);
-                       if (converter != null) {
-                               int len = 0;
-                               for (int i=0; i<childNodes.length; i++) {
-                                       removeConverter(childNodes[i]);
-                                       int viewIndex = converter.convertRowIndexToView(childIndices[i]);
-                                       if (viewIndex >= 0) {
-                                               childNodes[len] = childNodes[i];
-                                               childIndices[len++] = viewIndex;
-                                       }
-                               }
-                               if (len == 0)
-                                       return;
-                               if (converter.isFiltered() && converter.getChildCount() == len) {
-                                       ArrayList<TreePath> expand = new ArrayList<TreePath>();
-                                       if (applyFilter(filter, path, expand)) {
-                                               expand.retainAll(getExpandedPaths(path));
-                                               if (sortOrder != SortOrder.UNSORTED)
-                                                       sortHierarchy(path);
-                                               fireTreeStructureChangedAndExpand(path, expand, true);
-                                       } else if (isFilterStartPath(path)) {
-                                               converters.put(parent, new Converter(Converter.EMPTY, true));
-                                               fireTreeStructureChanged(path);
-                                       } else {
-                                               remove(path.getParentPath(), parent);
-                                       }
-                                       return;
-                               }
-                               if (len != childIndices.length) {
-                                       childIndices = Arrays.copyOf(childIndices, len);
-                                       childNodes = Arrays.copyOf(childNodes, len);
-                               }
-                               if (len > 1 && sortOrder != SortOrder.UNSORTED) {
-                                       sort(childIndices, childNodes);
-                               }
-                               if (childIndices.length == 1) {
-                                       converter.remove(converter.convertRowIndexToModel(childIndices[0]));
-                               } else {
-                                       converter.remove(childIndices);
-                               }
-                       } else if (filter != null && isFilteredOut(path)) {
-                               return;
-                       }
-                       fireTreeNodesRemoved(path, childIndices, childNodes);
-               }
-               
-               private Collection<TreePath> getExpandedPaths(TreePath path) {
-                       Enumeration<TreePath> en = tree.getExpandedDescendants(path);
-                       if (en == null)
-                               return Collections.emptySet();
-                       HashSet<TreePath> expanded = new HashSet<TreePath>();
-                       while (en.hasMoreElements())
-                               expanded.add(en.nextElement());
-                       return expanded;
-               }
-
-               @Override
-               public void treeStructureChanged(TreeModelEvent e) {
-                       if (converters != null) {
-                               // not enough information to properly clean up
-                               // reapply filter/sort
-                               converters = createConvertersMap();
-                               TreePath[] sel = tree.getSelectionPaths();
-                               if (filter != null) {
-                                       applyFilter(null, null, getExpandedPaths(new TreePath(getRoot())), false);
-                               }
-                               if (sortOrder != SortOrder.UNSORTED) {
-                                       TreePath path = new TreePath(getRoot());
-                                       ArrayList<TreePath> expand = sortHierarchy(path);
-                                       fireTreeStructureChangedAndExpand(path, expand, false);
-                               }
-                               if (sel != null) {
-                                       tree.clearSelection();
-                                       TreePath changedPath = e.getTreePath();
-                                       for (TreePath path : sel) {
-                                               if (!changedPath.isDescendant(path))
-                                                       tree.addSelectionPath(path);
-                                       }
-                               }
-                       } else {
-                               fireTreeStructureChanged(e.getTreePath());
-                       }
-               }
-               
-
-               @Override
-               public final int compare(ValueIndexPair<N> a, ValueIndexPair<N> b) {
-                       return compareNodes(a.value, b.value);
-               }
-
-               
-               protected int compareNodes(N a, N b) {
-                       if (comparator != null)
-                               return comparator.compare(a, b);
-                       return collator.compare(a.toString(), b.toString());
-               }
-
-               private void removeConverter(Object node) {
-                       Converter c = getConverter(node);
-                       if (c != null)
-                               removeConverter(c, node);
-               }
-               
-               private void removeConverter(Converter converter, Object node) {
-                       for (int i=converter.getChildCount(); --i>=0;) {
-                               int index = converter.convertRowIndexToModel(i);
-                               Object child = model.getChild(node, index);
-                               Converter c = getConverter(child);
-                               if (c != null)
-                                       removeConverter(c, child);
-                       }
-                       converters.remove(node);
-               }
-               
-               private boolean isFilteredOut(TreePath path) {
-                       if (filterStartPath != null && !filterStartPath.isDescendant(path))
-                               return false;
-                       TreePath parent = path.getParentPath();
-                       // root should always have a converter if filter is non-null,
-                       // so if parent is ever null, there is a bug somewhere else
-                       Converter c = getConverter(parent.getLastPathComponent());
-                       if (c != null) {
-                               return getIndexOfChild(
-                                               parent.getLastPathComponent(),
-                                               path.getLastPathComponent()) < 0;
-                       }
-                       return isFilteredOut(parent);
-               }
-               
-               private void filterIn(int[] vtm, int vtmLength, TreePath path, ArrayList<TreePath> expand) {
-                       Object node = path.getLastPathComponent();
-                       if (vtmLength != vtm.length)
-                               vtm = Arrays.copyOf(vtm, vtmLength);
-                       Converter converter = new Converter(vtm, true);
-                       converters.put(node, converter);
-                       insert(path.getParentPath(), node);
-                       tree.expandPath(path);
-                       expandPaths(expand);
-               }
-
-               private boolean acceptable(TreePath path, Object[] nodes, int index) {
-                       Object node = nodes[index];
-                       return filter.acceptNode(path, (N)node, model.isLeaf(node));
-               }
-               
-               private int ascInsertionIndex(int[] vtm, Object parent, N node, int idx) {
-                       for (int i=vtm.length; --i>=0;) {
-                               int cmp = compareNodes(node, (N)model.getChild(parent, vtm[i]));
-                               if (cmp > 0 || (cmp == 0 && idx > vtm[i])) {
-                                       return i+1;
-                               }
-                       }
-                       return 0;
-               }
-               
-               
-               private int dscInsertionIndex(int[] vtm, Object parent, N node, int idx) {
-                       for (int i=vtm.length; --i>=0;) {
-                               int cmp = compareNodes(node, (N)model.getChild(parent, vtm[i]));
-                               if (cmp < 0) {
-                                       return i+1;
-                               } else if (cmp == 0 && idx < vtm[i]) {
-                                       return i;
-                               }
-                       }
-                       return 0;
-               }
-
-               
-               /**
-                * Inserts the specified path and node and any parent paths as necessary.
-                * <p>
-                * Fires appropriate event.
-                * @param path
-                * @param node
-                */
-               private void insert(TreePath path, Object node) {
-                       Object parent = path.getLastPathComponent();
-                       Converter converter = converters.get(parent);
-                       int modelIndex = model.getIndexOfChild(parent, node);
-                       if (converter == null) {
-                               converter = new Converter(indices(modelIndex), true);
-                               converters.put(parent, converter);
-                               insert(path.getParentPath(), parent);
-                       } else {
-                               int viewIndex = insert(parent, node, modelIndex, converter);
-                               fireTreeNodesInserted(path, indices(viewIndex), nodes(node));
-                       }
-               }
-               
-               /**
-                * Inserts node into parent in correct sort order.
-                * <p>
-                * Responsibility of caller to fire appropriate event with the returned viewIndex.
-                * @param path
-                * @param node
-                * @param modelIndex
-                * @param converter
-                * @return viewIndex
-                */
-               private int insert(Object parent, Object node, int modelIndex, Converter converter) {
-                       int[] vtm = converter.viewToModel;
-                       int viewIndex;
-                       switch (sortOrder) {
-                       case ASCENDING:
-                               viewIndex = ascInsertionIndex(vtm, parent, (N)node, modelIndex);
-                               break;
-                       case DESCENDING:
-                               viewIndex = dscInsertionIndex(vtm, parent, (N)node, modelIndex);
-                               break;
-                       default: case UNSORTED:
-                               viewIndex = unsortedInsertionIndex(vtm, modelIndex);
-                               break;
-                       }
-                       int[] a = new int[vtm.length+1];
-                       System.arraycopy(vtm, 0, a, 0, viewIndex);
-                       System.arraycopy(vtm, viewIndex, a, viewIndex+1, vtm.length-viewIndex);
-                       a[viewIndex] = modelIndex;
-                       converter.viewToModel = a;
-                       return viewIndex;
-               }
-               
-               private void remove(TreePath path, Object node) {
-                       Object parent = path.getLastPathComponent();
-                       if (path.getPathCount() == 1 || (filterStartPath != null && filterStartPath.equals(path))) {
-                               removeConverter(node);
-                               converters.put(parent, new Converter(Converter.EMPTY, true));
-                               fireTreeNodesRemoved(path, indices(0), nodes(node));
-                               return;
-                       }
-                       Converter converter = converters.get(parent);
-                       int modelIndex = model.getIndexOfChild(parent, node);
-                       int viewIndex = converter.remove(modelIndex);
-                       switch (viewIndex) {
-                       default:
-                               removeConverter(node);
-                               fireTreeNodesRemoved(path, indices(viewIndex), nodes(node));
-                               break;
-                       case Converter.ONLY_INDEX:
-//                             if (path.getParentPath() == null) {
-//                                     // reached filter root
-//                                     removeConverter(node);
-//                                     converters.put(parent, new Converter(Converter.EMPTY, true));
-//                                     fireTreeNodesRemoved(path, indices(0), nodes(node));
-//                                     return;
-//                             }
-                               remove(path.getParentPath(), parent);
-                               break;
-                       case Converter.INDEX_NOT_FOUND:
-                               removeConverter(node);
-                       }
-               }
-               
-               
-               
-       }
-       
-       
-
-       private static int unsortedInsertionIndex(int[] vtm, int idx) {
-               for (int i=vtm.length; --i>=0;)
-                       if (vtm[i] < idx)
-                               return i+1;
-               return 0;
-       }
-       
-       private static void sort(int[] childIndices, Object[] childNodes) {
-               int len = childIndices.length;
-               ValueIndexPair[] pairs = new ValueIndexPair[len];
-               for (int i=len; --i>=0;)
-                       pairs[i] = new ValueIndexPair<Object>(childIndices[i], childNodes[i]);
-               Arrays.sort(pairs);
-               for (int i=len; --i>=0;) {
-                       childIndices[i] = pairs[i].index;
-                       childNodes[i] = pairs[i].value;
-               }
-       }
-       
-       private static int[] indices(int...indices) {
-               return indices;
-       }
-       
-       private static Object[] nodes(Object...nodes) {
-               return nodes;
-       }
-       
-
-
-       
-       /**
-        * This class has a dual purpose, both related to comparing/sorting.
-        * <p>
-        * The Handler class sorts an array of ValueIndexPair based on the value.
-        * Used for sorting the view.
-        * <p>
-        * ValueIndexPair sorts itself based on the index.
-        * Used for sorting childIndices for fire* methods.
-        */
-       private static class ValueIndexPair<N> implements Comparable<ValueIndexPair<N>> {
-               ValueIndexPair() {}
-               
-               ValueIndexPair(int idx, N val) {
-                       index = idx;
-                       value = val;
-               }
-               
-               N value;
-               
-               int index;
-               
-               public int compareTo(ValueIndexPair<N> o) {
-                       return index - o.index;
-               }
-       }
-       
-       private static class Converter {
-               
-               static final int[] EMPTY = new int[0];
-               
-               static final int ONLY_INDEX = -2;
-               
-               static final int INDEX_NOT_FOUND = -1;
-               
-               Converter(int[] vtm, boolean filtered) {
-                       viewToModel = vtm;
-                       isFiltered = filtered;
-               }
-               
-               private int[] viewToModel;
-               
-               private boolean isFiltered;
-               
-//             public boolean equals(Converter conv) {
-//                     if (conv == null)
-//                             return false;
-//                     if (isFiltered != conv.isFiltered)
-//                             return false;
-//                     return Arrays.equals(viewToModel, conv.viewToModel);
-//             }
-               
-               boolean isFiltered() {
-                       return isFiltered;
-               }
-               
-               void remove(int viewIndices[]) {
-                       int len = viewToModel.length - viewIndices.length;
-                       if (len == 0) {
-                               viewToModel = EMPTY;
-                       } else {
-                               int[] oldVTM = viewToModel;
-                               int[] newVTM = new int[len];
-                               for (int oldIndex=0, newIndex=0, removeIndex=0;
-                                               newIndex<newVTM.length;
-                                               newIndex++, oldIndex++) {
-                                       while (removeIndex < viewIndices.length && oldIndex == viewIndices[removeIndex]) {
-                                               int idx = oldVTM[oldIndex];
-                                               removeIndex++;
-                                               oldIndex++;
-                                               for (int i=newIndex; --i>=0;)
-                                                       if (newVTM[i] > idx)
-                                                               newVTM[i]--;
-                                               for (int i=oldIndex; i<oldVTM.length; i++)
-                                                       if (oldVTM[i] > idx)
-                                                               oldVTM[i]--;
-                                       }
-                                       newVTM[newIndex] = oldVTM[oldIndex];
-                               }
-                               viewToModel = newVTM;
-                       }
-               }
-               
-               /**
-                * @param modelIndex
-                * @return viewIndex that was removed<br>
-                *              or <code>ONLY_INDEX</code> if the modelIndex is the only one in the view<br>
-                *              or <code>INDEX_NOT_FOUND</code> if the modelIndex is not in the view
-                */
-               int remove(int modelIndex) {
-                       int[] vtm = viewToModel;
-                       for (int i=vtm.length; --i>=0;) {
-                               if (vtm[i] > modelIndex) {
-                                       vtm[i] -= 1;
-                               } else if (vtm[i] == modelIndex) {
-                                       if (vtm.length == 1) {
-                                               viewToModel = EMPTY;
-                                               return ONLY_INDEX;
-                                       }
-                                       int viewIndex = i;
-                                       while (--i>=0) {
-                                               if (vtm[i] > modelIndex)
-                                                       vtm[i] -= 1;
-                                       }
-                                       int[] a = new int[vtm.length-1];
-                                       if (viewIndex > 0)
-                                               System.arraycopy(vtm, 0, a, 0, viewIndex);
-                                       int len = a.length-viewIndex;
-                                       if (len > 0)
-                                               System.arraycopy(vtm, viewIndex+1, a, viewIndex, len);
-                                       viewToModel = a;
-                                       return viewIndex;
-                               }
-                       }
-                       return INDEX_NOT_FOUND;
-               }
-               
-               
-               int getChildCount() {
-                       return viewToModel.length;
-               }
-               
-               /**
-                * @param modelIndex
-                * @return viewIndex corresponding to modelIndex<br>
-                *              or <code>INDEX_NOT_FOUND</code> if the modelIndex is not in the view
-                */
-               int convertRowIndexToView(int modelIndex) {
-                       int[] vtm = viewToModel;
-                       for (int i=vtm.length; --i>=0;) {
-                               if (vtm[i] == modelIndex)
-                                       return i;
-                       }
-                       return INDEX_NOT_FOUND;
-               }
-               
-               int convertRowIndexToModel(int viewIndex) {
-                       return viewToModel[viewIndex];
-               }
-       }
-
-       public interface Filter<N> {
-               boolean acceptNode(TreePath parent, N node, boolean leaf);
-       }
-
-       public static class RegexFilter<N> implements Filter<N> {
-               
-               public RegexFilter(Pattern pattern, boolean leaf) {
-                       matcher = pattern.matcher("");
-                       leafOnly = leaf;
-               }
-               
-               private Matcher matcher;
-               
-               private boolean leafOnly;
-               
-               public boolean acceptNode(TreePath parent, N node, boolean leaf) {
-                       if (leafOnly && !leaf)
-                               return false;
-                       matcher.reset(getStringValue(node));
-                       return matcher.find();
-               }
-               
-               protected String getStringValue(N node) {
-                       return node.toString();
-               }
-       }
-       
-
-       private static Map<Object,Converter> createConvertersMap() {
-               return new HashMap<Object,Converter>();
-       }
-}
diff --git a/src/be/nikiroo/fanfix_swing/gui/utils/TreeSnapshot.java b/src/be/nikiroo/fanfix_swing/gui/utils/TreeSnapshot.java
deleted file mode 100644 (file)
index ad734a1..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-package be.nikiroo.fanfix_swing.gui.utils;
-
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
-import javax.swing.JTree;
-import javax.swing.tree.TreeModel;
-import javax.swing.tree.TreeNode;
-import javax.swing.tree.TreePath;
-
-public class TreeSnapshot {
-       private interface NodeAction {
-               public void run(TreeNode node);
-       }
-
-       private JTree tree;
-       private TreePath[] selectionPaths;
-       private List<TreePath> expanded;
-
-       public TreeSnapshot(JTree tree) {
-               this.tree = tree;
-
-               selectionPaths = tree.getSelectionPaths();
-               if (selectionPaths == null) {
-                       selectionPaths = new TreePath[0];
-               }
-
-               expanded = new ArrayList<TreePath>();
-               forEach(tree, new NodeAction() {
-                       @Override
-                       public void run(TreeNode node) {
-                               TreePath path = nodeToPath(node);
-                               if (path != null) {
-                                       if (TreeSnapshot.this.tree.isExpanded(path)) {
-                                               expanded.add(path);
-                                       }
-                               }
-                       }
-               });
-       }
-
-       public void apply() {
-               applyTo(tree);
-       }
-
-       public void applyTo(JTree tree) {
-               final List<TreePath> newExpanded = new ArrayList<TreePath>();
-               final List<TreePath> newSlectionPaths = new ArrayList<TreePath>();
-
-               forEach(tree, new NodeAction() {
-                       @Override
-                       public void run(TreeNode newNode) {
-                               TreePath newPath = nodeToPath(newNode);
-                               if (newPath != null) {
-                                       for (TreePath path : selectionPaths) {
-                                               if (isSamePath(path, newPath)) {
-                                                       newSlectionPaths.add(newPath);
-                                                       if (expanded.contains(path)) {
-                                                               newExpanded.add(newPath);
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-               });
-
-               for (TreePath newPath : newExpanded) {
-                       tree.expandPath(newPath);
-               }
-
-               tree.setSelectionPaths(newSlectionPaths.toArray(new TreePath[0]));
-       }
-
-       // You can override this
-       protected boolean isSamePath(TreePath oldPath, TreePath newPath) {
-               return newPath.toString().equals(oldPath.toString());
-       }
-
-       private void forEach(JTree tree, NodeAction action) {
-               forEach(tree.getModel(), tree.getModel().getRoot(), action);
-       }
-
-       private void forEach(TreeModel model, Object parent, NodeAction action) {
-               if (!(parent instanceof TreeNode))
-                       return;
-
-               TreeNode node = (TreeNode) parent;
-
-               action.run(node);
-               int count = model.getChildCount(node);
-               for (int i = 0; i < count; i++) {
-                       Object child = model.getChild(node, i);
-                       forEach(model, child, action);
-               }
-       }
-
-       private static TreePath nodeToPath(TreeNode node) {
-               List<Object> nodes = new LinkedList<Object>();
-               if (node != null) {
-                       nodes.add(node);
-                       node = node.getParent();
-                       while (node != null) {
-                               nodes.add(0, node);
-                               node = node.getParent();
-                       }
-               }
-
-               return nodes.isEmpty() ? null : new TreePath(nodes.toArray());
-       }
-
-       @Override
-       public String toString() {
-               StringBuilder builder = new StringBuilder();
-               builder.append("Tree Snapshot of: ").append(tree).append("\n");
-               builder.append("Selected paths:\n");
-               for (TreePath path : selectionPaths) {
-                       builder.append("\t").append(path).append("\n");
-               }
-               builder.append("Expanded paths:\n");
-               for (TreePath epath : expanded) {
-                       builder.append("\t").append(epath).append("\n");
-               }
-
-               return builder.toString();
-       }
-}
index 08a65b0710b76e0cca1d2aaa7ceabbad89d2fbf0..7cc0a3d2a32ea79caaca8ac34af08bd203fe4f59 100644 (file)
@@ -4,10 +4,7 @@ import java.awt.Color;
 import java.awt.Component;
 
 import javax.swing.JButton;
-import javax.swing.JComponent;
 import javax.swing.JOptionPane;
-import javax.swing.JScrollPane;
-import javax.swing.JTree;
 import javax.swing.SwingUtilities;
 
 import be.nikiroo.fanfix.Instance;
@@ -37,14 +34,6 @@ public class UiHelper {
                button.setBackground(pressed ? buttonPressed : buttonNormal);
        }
 
-       static public JComponent scroll(JComponent pane) {
-               JScrollPane scroll = new JScrollPane(pane);
-               scroll.getVerticalScrollBar().setUnitIncrement(16);
-               scroll.setHorizontalScrollBarPolicy(
-                               JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
-               return scroll;
-       }
-
        /**
         * Display an error message and log the linked {@link Exception}.
         *