X-Git-Url: http://git.nikiroo.be/?p=fanfix.git;a=blobdiff_plain;f=src%2Fbe%2Fnikiroo%2Futils%2Fui%2FListModel.java;h=7cc23b8c34b78262b33b5dc065e525d6e2a1ce90;hp=cf16d5f0a111e660171102b3efad3bdefe1d6d48;hb=5ddc36eacad78641be59db473f9bae9bad47eb20;hpb=0cf9d0459e5e67ef3f97c57cb5acb51fb5da97d7 diff --git a/src/be/nikiroo/utils/ui/ListModel.java b/src/be/nikiroo/utils/ui/ListModel.java index cf16d5f..7cc23b8 100644 --- a/src/be/nikiroo/utils/ui/ListModel.java +++ b/src/be/nikiroo/utils/ui/ListModel.java @@ -14,9 +14,9 @@ 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; +import be.nikiroo.utils.ui.compat.DefaultListModel6; +import be.nikiroo.utils.ui.compat.JList6; +import be.nikiroo.utils.ui.compat.ListCellRenderer6; /** * A {@link javax.swing.ListModel} that can maintain 2 lists; one with the @@ -34,6 +34,9 @@ import be.nikiroo.utils.compat.ListCellRenderer6; 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 @@ -112,6 +115,8 @@ public class ListModel extends DefaultListModel6 { private List items = new ArrayList(); private boolean keepSelection = true; + private DelayWorker tooltipWatcher; + private JPopupMenu popup; private TooltipCreator tooltipCreator; private Window tooltip; @@ -129,50 +134,6 @@ public class ListModel extends DefaultListModel6 { 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}. *

@@ -185,84 +146,21 @@ public class ListModel extends DefaultListModel6 { * 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) { + public ListModel(final JList list) { this.list = list; - this.tooltipCreator = tooltipCreator; list.setModel(this); - final DelayWorker tooltipWatcher = new DelayWorker(500); - if (tooltipCreator != null) { - tooltipWatcher.start(); - } + // We always have it ready + tooltipWatcher = new DelayWorker(DELAY_TOOLTIP_MS); + tooltipWatcher.start(); list.addMouseMotionListener(new MouseAdapter() { @Override public void mouseMoved(final MouseEvent me) { - if (popup != null && popup.isShowing()) + if (ListModel.this.popup != null + && ListModel.this.popup.isShowing()) return; Point p = new Point(me.getX(), me.getY()); @@ -274,6 +172,8 @@ public class ListModel extends DefaultListModel6 { fireElementChanged(index); if (ListModel.this.tooltipCreator != null) { + showTooltip(null); + tooltipWatcher.delay("tooltip", new SwingWorker() { @Override @@ -284,18 +184,20 @@ public class ListModel extends DefaultListModel6 { @Override protected void done() { - Window oldTooltip = tooltip; - tooltip = null; - if (oldTooltip != null) { - oldTooltip.setVisible(false); - } + showTooltip(null); if (index < 0 || index != hoveredIndex) { return; } - tooltip = newTooltip(index, me); + if (ListModel.this.popup != null + && ListModel.this.popup + .isShowing()) { + return; + } + + showTooltip(newTooltip(index, me)); } }); } @@ -316,7 +218,8 @@ public class ListModel extends DefaultListModel6 { @Override public void mouseExited(MouseEvent e) { - if (popup != null && popup.isShowing()) + if (ListModel.this.popup != null + && ListModel.this.popup.isShowing()) return; if (hoveredIndex > -1) { @@ -327,7 +230,7 @@ public class ListModel extends DefaultListModel6 { } private void check(MouseEvent e) { - if (popup == null) { + if (ListModel.this.popup == null) { return; } @@ -337,7 +240,8 @@ public class ListModel extends DefaultListModel6 { list.locationToIndex(e.getPoint())); } - popup.show(list, e.getX(), e.getY()); + showTooltip(null); + ListModel.this.popup.show(list, e.getX(), e.getY()); } } @@ -369,6 +273,46 @@ public class ListModel extends DefaultListModel6 { this.keepSelection = keepSelection; } + /** + * The popup to use and keep track of (can be NULL). + * + * @return the current popup + */ + public JPopupMenu getPopup() { + return popup; + } + + /** + * The popup to use and keep track of (can be NULL). + * + * @param popup + * the new popup + */ + public void setPopup(JPopupMenu popup) { + this.popup = popup; + } + + /** + * You can use a {@link TooltipCreator} if you want the list to display + * tooltips on mouse hover (can be NULL). + * + * @return the current {@link TooltipCreator} + */ + public TooltipCreator getTooltipCreator() { + return tooltipCreator; + } + + /** + * You can use a {@link TooltipCreator} if you want the list to display + * tooltips on mouse hover (can be NULL). + * + * @param tooltipCreator + * the new {@link TooltipCreator} + */ + public void setTooltipCreator(TooltipCreator tooltipCreator) { + this.tooltipCreator = tooltipCreator; + } + /** * Check if this element is currently under the mouse. * @@ -554,29 +498,45 @@ public class ListModel extends DefaultListModel6 { 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()); + if (promotedTooltip != null) { + promotedTooltip.setLocation(me.getXOnScreen(), + me.getYOnScreen()); + promotedTooltip.setVisible(true); + } + newTooltip.setVisible(false); - promotedTooltip.setVisible(true); } }); - newTooltip.setLocation(me.getXOnScreen(), me.getYOnScreen()); - newTooltip.setVisible(true); + newTooltip.setLocation(me.getXOnScreen(), me.getYOnScreen()); + showTooltip(newTooltip); } return newTooltip; } + private void showTooltip(Window tooltip) { + synchronized (tooltipWatcher) { + if (this.tooltip != null) { + this.tooltip.setVisible(false); + this.tooltip.dispose(); + } + + this.tooltip = tooltip; + + if (tooltip != null) { + tooltip.setVisible(true); + } + } + } + /** * Generate a {@link ListCellRenderer} that supports {@link Hoverable} * elements.