X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;ds=inline;f=ui%2FListModel.java;h=d76c5dc2c169a595e6a90b48d41b110bac7d6a46;hb=HEAD;hp=7103dbac9a911203d92a1677795f481e8d9d07b2;hpb=ae474ca4ecdbbb4fbf45712cd650f99f91de649f;p=fanfix.git
diff --git a/ui/ListModel.java b/ui/ListModel.java
deleted file mode 100644
index 7103dba..0000000
--- a/ui/ListModel.java
+++ /dev/null
@@ -1,624 +0,0 @@
-package be.nikiroo.utils.ui;
-
-import java.awt.Component;
-import java.awt.Point;
-import java.awt.Window;
-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 javax.swing.SwingWorker;
-
-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).
- *
- * It also offers filter options, supports hovered changes and some more utility
- * functions.
- *
- * @author niki
- *
- * @param
- * the type of elements and items (the same type)
- */
-public class ListModel extends DefaultListModel6 {
- private static final long serialVersionUID = 1L;
-
- /** How long to wait before displaying a tooltip, in milliseconds. */
- private static final int DELAY_TOOLTIP_MS = 1000;
-
- /**
- * 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
- * the type of elements and items (the same type)
- */
- public interface Predicate {
- /**
- * 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);
- }
-
- /**
- * An interface required to support tooltips on this {@link ListModel}.
- *
- * @author niki
- *
- * @param
- * the type of elements and items (the same type)
- */
- public interface TooltipCreator {
- /**
- * Generate a tooltip {@link Window} for this element.
- *
- * Note that the tooltip can be of two modes: undecorated or standalone.
- * An undecorated tooltip will be taken care of by this
- * {@link ListModel}, but a standalone one is supposed to be its own
- * Dialog or Frame (it won't be automatically closed).
- *
- * @param t
- * the element to generate a tooltip for
- * @param undecorated
- * TRUE for undecorated tooltip, FALSE for standalone
- * tooltips
- *
- * @return the generated tooltip or NULL for none
- */
- public Window generateTooltip(T t, boolean undecorated);
- }
-
- private int hoveredIndex;
- private List items = new ArrayList();
- private boolean keepSelection = true;
-
- private TooltipCreator tooltipCreator;
- private Window tooltip;
-
- @SuppressWarnings("rawtypes") // JList> not compatible Java 1.6
- private JList list;
-
- /**
- * Create a new {@link ListModel}.
- *
- * @param list
- * the {@link JList6} we will handle the data of (cannot be NULL)
- */
- @SuppressWarnings("rawtypes") // JList> not compatible Java 1.6
- public ListModel(JList6 list) {
- this((JList) list);
- }
-
- /**
- * 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)
- */
- @SuppressWarnings("rawtypes") // JList> not compatible Java 1.6
- public ListModel(JList6 list, JPopupMenu popup) {
- this((JList) list, popup);
- }
-
- /**
- * Create a new {@link ListModel}.
- *
- * @param list
- * the {@link JList6} we will handle the data of (cannot be NULL)
- * @param tooltipCreator
- * use this if you want the list to display tooltips on hover
- * (can be NULL)
- */
- @SuppressWarnings("rawtypes") // JList> not compatible Java 1.6
- public ListModel(JList6 list, TooltipCreator tooltipCreator) {
- this((JList) list, null, tooltipCreator);
- }
-
- /**
- * 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)
- * @param tooltipCreator
- * use this if you want the list to display tooltips on hover
- * (can be NULL)
- */
- @SuppressWarnings("rawtypes") // JList> not compatible Java 1.6
- public ListModel(JList6 list, JPopupMenu popup,
- TooltipCreator tooltipCreator) {
- this((JList) list, popup, tooltipCreator);
- }
-
- /**
- * Create a new {@link ListModel}.
- *
- * Note that you must take care of passing a {@link JList} that only handles
- * elements of the type of this {@link ListModel} -- you can also use
- * {@link ListModel#ListModel(JList6)} instead.
- *
- * @param list
- * the {@link JList} we will handle the data of (cannot be NULL,
- * must only contain elements of the type of this
- * {@link ListModel})
- */
- @SuppressWarnings("rawtypes") // JList> not compatible Java 1.6
- public ListModel(JList list) {
- this(list, null, null);
- }
-
- /**
- * Create a new {@link ListModel}.
- *
- * Note that you must take care of passing a {@link JList} that only handles
- * elements of the type of this {@link ListModel} -- you can also use
- * {@link ListModel#ListModel(JList6, JPopupMenu)} instead.
- *
- * @param list
- * the {@link JList} we will handle the data of (cannot be NULL,
- * must only contain elements of the type of this
- * {@link ListModel})
- * @param popup
- * the popup to use and keep track of (can be NULL)
- */
- @SuppressWarnings("rawtypes") // JList> not in Java 1.6
- public ListModel(JList list, JPopupMenu popup) {
- this(list, popup, null);
- }
-
- /**
- * Create a new {@link ListModel}.
- *
- * Note that you must take care of passing a {@link JList} that only handles
- * elements of the type of this {@link ListModel} -- you can also use
- * {@link ListModel#ListModel(JList6, JPopupMenu)} instead.
- *
- * @param list
- * the {@link JList} we will handle the data of (cannot be NULL,
- * must only contain elements of the type of this
- * {@link ListModel})
- * @param tooltipCreator
- * use this if you want the list to display tooltips on hover
- * (can be NULL)
- */
- @SuppressWarnings("rawtypes") // JList> not in Java 1.6
- public ListModel(JList list, TooltipCreator tooltipCreator) {
- this(list, null, tooltipCreator);
- }
-
- /**
- * Create a new {@link ListModel}.
- *
- * Note that you must take care of passing a {@link JList} that only handles
- * elements of the type of this {@link ListModel} -- you can also use
- * {@link ListModel#ListModel(JList6, JPopupMenu)} instead.
- *
- * @param list
- * the {@link JList} we will handle the data of (cannot be NULL,
- * must only contain elements of the type of this
- * {@link ListModel})
- * @param popup
- * the popup to use and keep track of (can be NULL)
- * @param tooltipCreator
- * use this if you want the list to display tooltips on hover
- * (can be NULL)
- */
- @SuppressWarnings({ "unchecked", "rawtypes" }) // JList> not in Java 1.6
- public ListModel(final JList list, final JPopupMenu popup,
- TooltipCreator tooltipCreator) {
- this.list = list;
- this.tooltipCreator = tooltipCreator;
-
- list.setModel(this);
-
- final DelayWorker tooltipWatcher = new DelayWorker(DELAY_TOOLTIP_MS);
- if (tooltipCreator != null) {
- tooltipWatcher.start();
- }
-
- list.addMouseMotionListener(new MouseAdapter() {
- @Override
- public void mouseMoved(final MouseEvent me) {
- if (popup != null && popup.isShowing())
- return;
-
- Point p = new Point(me.getX(), me.getY());
- final int index = list.locationToIndex(p);
- if (index != hoveredIndex) {
- int oldIndex = hoveredIndex;
- hoveredIndex = index;
- fireElementChanged(oldIndex);
- fireElementChanged(index);
-
- Window oldTooltip = tooltip;
- tooltip = null;
- if (oldTooltip != null) {
- oldTooltip.setVisible(false);
- }
-
- if (ListModel.this.tooltipCreator != null) {
- tooltipWatcher.delay("tooltip",
- new SwingWorker() {
- @Override
- protected Void doInBackground()
- throws Exception {
- return null;
- }
-
- @Override
- protected void done() {
- if (index < 0
- || index != hoveredIndex) {
- return;
- }
-
- if (popup != null
- && popup.isShowing()) {
- return;
- }
-
- tooltip = newTooltip(index, me);
- }
- });
- }
- }
- }
- });
-
- 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()));
- }
-
- Window oldTooltip = tooltip;
- tooltip = null;
- if (oldTooltip != null) {
- oldTooltip.setVisible(false);
- }
-
- popup.show(list, e.getX(), e.getY());
- }
- }
-
- });
- }
-
- /**
- * (Try and) keep the elements that were selected when filtering.
- *
- * This will use toString on the elements to identify them, and can be a bit
- * resource intensive.
- *
- * @return TRUE if we do
- */
- public boolean isKeepSelection() {
- return keepSelection;
- }
-
- /**
- * (Try and) keep the elements that were selected when filtering.
- *
- * This will use toString on the elements to identify them, and can be a bit
- * resource intensive.
- *
- * @param keepSelection
- * TRUE to try and keep them selected
- */
- public void setKeepSelection(boolean keepSelection) {
- this.keepSelection = keepSelection;
- }
-
- /**
- * 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 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 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.
- *
- * 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") // JList> not compatible Java 1.6
- public void filter(Predicate filter) {
- ListSnapshot snapshot = null;
-
- if (keepSelection)
- snapshot = new ListSnapshot(list);
-
- clear();
- for (T item : items) {
- if (filter == null || filter.test(item)) {
- addElement(item);
- }
- }
-
- if (keepSelection)
- snapshot.apply();
-
- list.repaint();
- }
-
- /**
- * Return the currently selected elements.
- *
- * @return the selected elements
- */
- public List getSelectedElements() {
- List selected = new ArrayList();
- for (int index : list.getSelectedIndices()) {
- selected.add(get(index));
- }
-
- return selected;
- }
-
- /**
- * Return the selected element if one and only one 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 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") // JList> not compatible Java 1.6
- @Override
- public T get(int index) {
- return (T) super.get(index);
- }
-
- private Window newTooltip(final int index, final MouseEvent me) {
- final T value = ListModel.this.get(index);
-
- final Window newTooltip = tooltipCreator.generateTooltip(value, true);
-
- if (newTooltip != null) {
- newTooltip.addMouseListener(new MouseAdapter() {
- @Override
- public void mouseClicked(MouseEvent e) {
-
- Window promotedTooltip = tooltipCreator
- .generateTooltip(value, false);
- promotedTooltip.setLocation(newTooltip.getLocation());
- newTooltip.setVisible(false);
- promotedTooltip.setVisible(true);
- }
- });
- newTooltip.setLocation(me.getXOnScreen(), me.getYOnScreen());
-
- newTooltip.setVisible(true);
- }
-
- return newTooltip;
- }
-
- /**
- * Generate a {@link ListCellRenderer} that supports {@link Hoverable}
- * elements.
- *
- * @param
- * 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 ListCellRenderer6 generateRenderer(
- final ListModel model) {
- return new ListCellRenderer6() {
- @Override
- public Component getListCellRendererComponent(JList6 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;
- }
- };
- }
-}