From d6c8579cb5debbdf7657d405e6529ba324903fcd Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Wed, 8 Apr 2020 21:57:18 +0200 Subject: [PATCH] some update/refresh fixes --- .../nikiroo/fanfix_swing/gui/BooksPanel.java | 3 +- .../fanfix_swing/gui/BrowserPanel.java | 74 ++++++++----------- .../fanfix_swing/gui/DetailsPanel.java | 4 + .../fanfix_swing/gui/book/BookInfo.java | 6 +- .../fanfix_swing/gui/browser/BasicTab.java | 2 - .../fanfix_swing/gui/browser/SourceTab.java | 6 +- .../fanfix_swing/gui/utils/ListenerPanel.java | 54 ++++++++++++-- 7 files changed, 93 insertions(+), 56 deletions(-) diff --git a/src/be/nikiroo/fanfix_swing/gui/BooksPanel.java b/src/be/nikiroo/fanfix_swing/gui/BooksPanel.java index 8a88213..04ee86f 100644 --- a/src/be/nikiroo/fanfix_swing/gui/BooksPanel.java +++ b/src/be/nikiroo/fanfix_swing/gui/BooksPanel.java @@ -164,7 +164,8 @@ public class BooksPanel extends ListenerPanel { private void filter(String filter) { data.clear(); for (BookInfo bookInfo : bookInfos) { - if (filter.isEmpty() || bookInfo.getMainInfo().toLowerCase().contains(filter.toLowerCase())) { + if (bookInfo.getMainInfo() == null || filter.isEmpty() + || bookInfo.getMainInfo().toLowerCase().contains(filter.toLowerCase())) { data.addElement(bookInfo); } } diff --git a/src/be/nikiroo/fanfix_swing/gui/BrowserPanel.java b/src/be/nikiroo/fanfix_swing/gui/BrowserPanel.java index 9a6ee1a..c8b1713 100644 --- a/src/be/nikiroo/fanfix_swing/gui/BrowserPanel.java +++ b/src/be/nikiroo/fanfix_swing/gui/BrowserPanel.java @@ -8,7 +8,6 @@ import java.awt.event.ActionListener; import java.util.List; import javax.swing.JButton; -import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.JTabbedPane; import javax.swing.event.ChangeEvent; @@ -21,6 +20,7 @@ import be.nikiroo.fanfix_swing.gui.browser.AuthorTab; import be.nikiroo.fanfix_swing.gui.browser.BasicTab; import be.nikiroo.fanfix_swing.gui.browser.SourceTab; import be.nikiroo.fanfix_swing.gui.browser.TagsTab; +import be.nikiroo.fanfix_swing.gui.utils.ListenerPanel; import be.nikiroo.fanfix_swing.gui.utils.UiHelper; /** @@ -29,7 +29,7 @@ import be.nikiroo.fanfix_swing.gui.utils.UiHelper; * * @author niki */ -public class BrowserPanel extends JPanel { +public class BrowserPanel extends ListenerPanel { private static final long serialVersionUID = 1L; /** @@ -53,6 +53,13 @@ public class BrowserPanel extends JPanel { * the scope of a tag. */ static public final String TAGS_SELECTION = "tags_selection"; + /** + * The {@link ActionEvent} you receive from + * {@link BrowserPanel#addActionListener(ActionListener)} can return this as a + * command (see {@link ActionEvent#getActionCommand()}) if they were created in + * the scope of a tab change. + */ + static public final String TAB_CHANGE = "tab_change"; private JTabbedPane tabs; private SourceTab sourceTab; @@ -75,9 +82,9 @@ public class BrowserPanel extends JPanel { tabs.add(authorTab = new AuthorTab(index++, AUTHOR_SELECTION)); tabs.add(tagsTab = new TagsTab(index++, TAGS_SELECTION)); - setText(tabs, sourceTab, "Sources", "Tooltip for Sources"); - setText(tabs, authorTab, "Authors", "Tooltip for Authors"); - setText(tabs, tagsTab, "Tags", "Tooltip for Tags"); + configureTab(tabs, sourceTab, "Sources", "Tooltip for Sources"); + configureTab(tabs, authorTab, "Authors", "Tooltip for Authors"); + configureTab(tabs, tagsTab, "Tags", "Tooltip for Tags"); JPanel options = new JPanel(); options.setLayout(new BorderLayout()); @@ -107,6 +114,8 @@ public class BrowserPanel extends JPanel { if (!keepSelection) { unselect(); } + + fireActionPerformed(TAB_CHANGE); } }); } @@ -122,26 +131,30 @@ public class BrowserPanel extends JPanel { } } - private void setText(JTabbedPane tabs, @SuppressWarnings("rawtypes") BasicTab tab, String name, String tooltip) { + private void configureTab(JTabbedPane tabs, @SuppressWarnings("rawtypes") BasicTab tab, String name, + String tooltip) { tab.setBaseTitle(name); tabs.setTitleAt(tab.getIndex(), tab.getTitle()); tabs.setToolTipTextAt(tab.getIndex(), tooltip); - listenTitleChange(tabs, tab); + listenTabs(tabs, tab); } - private void listenTitleChange(final JTabbedPane tabs, @SuppressWarnings("rawtypes") final BasicTab tab) { + private void listenTabs(final JTabbedPane tabs, @SuppressWarnings("rawtypes") final BasicTab tab) { tab.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { tabs.setTitleAt(tab.getIndex(), tab.getTitle()); + fireActionPerformed(e.getActionCommand()); } }); } /** - * Get the {@link BookInfo} to highlight, even if more than one are selected. + * Get the {@link BookInfo} to highlight, even if none or more than one are + * selected. *

- * Return NULL when nothing is selected. + * Return a special "all" {@link BookInfo} of the correct type when nothing is + * selected. * * @return the {@link BookInfo} to highlight, can be NULL */ @@ -156,17 +169,16 @@ public class BrowserPanel extends JPanel { } } - if (selected1 != null) { - BasicLibrary lib = Instance.getInstance().getLibrary(); - if (tabs.getSelectedComponent() == sourceTab) { - return BookInfo.fromSource(lib, selected1); - } else if (tabs.getSelectedComponent() == authorTab) { - return BookInfo.fromAuthor(lib, selected1); - } else if (tabs.getSelectedComponent() == tagsTab) { - return BookInfo.fromTag(lib, selected1); - } + BasicLibrary lib = Instance.getInstance().getLibrary(); + if (tabs.getSelectedComponent() == sourceTab) { + return BookInfo.fromSource(lib, selected1); + } else if (tabs.getSelectedComponent() == authorTab) { + return BookInfo.fromAuthor(lib, selected1); + } else if (tabs.getSelectedComponent() == tagsTab) { + return BookInfo.fromTag(lib, selected1); } + // ...what? return null; } @@ -205,28 +217,4 @@ public class BrowserPanel extends JPanel { authorTab.reloadData(); tagsTab.reloadData(); } - - /** - * Adds the specified action listener to receive action events from this - * {@link SearchBar}. - * - * @param listener the action listener to be added - */ - public synchronized void addActionListener(ActionListener listener) { - sourceTab.addActionListener(listener); - authorTab.addActionListener(listener); - tagsTab.addActionListener(listener); - } - - /** - * Removes the specified action listener so that it no longer receives action - * events from this {@link SearchBar}. - * - * @param listener the action listener to be removed - */ - public synchronized void removeActionListener(ActionListener listener) { - sourceTab.removeActionListener(listener); - authorTab.removeActionListener(listener); - tagsTab.removeActionListener(listener); - } } diff --git a/src/be/nikiroo/fanfix_swing/gui/DetailsPanel.java b/src/be/nikiroo/fanfix_swing/gui/DetailsPanel.java index ced9c3b..751e37f 100644 --- a/src/be/nikiroo/fanfix_swing/gui/DetailsPanel.java +++ b/src/be/nikiroo/fanfix_swing/gui/DetailsPanel.java @@ -85,11 +85,15 @@ public class DetailsPanel extends JPanel { if (info == null) { name.setText(null); opt.setText(null); + } else if (info.getMainInfo() == null) { + name.setText("All the " + info.getType().toString().toLowerCase() + "s"); + opt.setText(info.getSecondaryInfo(true)); } else { final String myId = info.getId(); name.setText(info.getMainInfo()); opt.setText(info.getSecondaryInfo(true)); + new SwingWorker() { @Override protected Image doInBackground() throws Exception { diff --git a/src/be/nikiroo/fanfix_swing/gui/book/BookInfo.java b/src/be/nikiroo/fanfix_swing/gui/book/BookInfo.java index de57e84..6859cfa 100644 --- a/src/be/nikiroo/fanfix_swing/gui/book/BookInfo.java +++ b/src/be/nikiroo/fanfix_swing/gui/book/BookInfo.java @@ -234,7 +234,7 @@ public class BookInfo { * @return the book */ static public BookInfo fromSource(BasicLibrary lib, String source) { - BookInfo info = new BookInfo(Type.SOURCE, "source_" + source, source); + BookInfo info = new BookInfo(Type.SOURCE, "source_" + (source == null ? "" : source), source); int size = 0; try { @@ -261,7 +261,7 @@ public class BookInfo { * @return the book */ static public BookInfo fromAuthor(BasicLibrary lib, String author) { - BookInfo info = new BookInfo(Type.AUTHOR, "author_" + author, author); + BookInfo info = new BookInfo(Type.AUTHOR, "author_" + (author == null ? "" : author), author); int size = 0; try { @@ -288,7 +288,7 @@ public class BookInfo { * @return the book */ static public BookInfo fromTag(BasicLibrary lib, String tag) { - BookInfo info = new BookInfo(Type.TAG, "tag_" + tag, tag); + BookInfo info = new BookInfo(Type.TAG, "tag_" + (tag == null ? "" : tag), tag); int size = 0; try { diff --git a/src/be/nikiroo/fanfix_swing/gui/browser/BasicTab.java b/src/be/nikiroo/fanfix_swing/gui/browser/BasicTab.java index 24b0d1f..86b4a02 100644 --- a/src/be/nikiroo/fanfix_swing/gui/browser/BasicTab.java +++ b/src/be/nikiroo/fanfix_swing/gui/browser/BasicTab.java @@ -127,8 +127,6 @@ public abstract class BasicTab extends ListenerPanel { // TODO: error } - // TODO: update is flickering... - root.removeAllChildren(); totalCount = loadData(root, data, searchBar.getText()); ((DefaultTreeModel) tree.getModel()).reload(); diff --git a/src/be/nikiroo/fanfix_swing/gui/browser/SourceTab.java b/src/be/nikiroo/fanfix_swing/gui/browser/SourceTab.java index 63907dc..ffa5e41 100644 --- a/src/be/nikiroo/fanfix_swing/gui/browser/SourceTab.java +++ b/src/be/nikiroo/fanfix_swing/gui/browser/SourceTab.java @@ -66,10 +66,12 @@ public class SourceTab extends BasicTab>> { int count = 0; for (String source : sourcesGrouped.keySet()) { if (checkFilter(filter, source) || checkFilter(filter, sourcesGrouped.get(source))) { - boolean hasChildren = sourcesGrouped.get(source).size() > 1; + List children = sourcesGrouped.get(source); + boolean hasChildren = (children.size() > 1) + || (children.size() == 1 && !children.get(0).trim().isEmpty()); DefaultMutableTreeNode sourceNode = new DefaultMutableTreeNode(">" + source + (hasChildren ? "/" : "")); root.add(sourceNode); - for (String subSource : sourcesGrouped.get(source)) { + for (String subSource : children) { if (checkFilter(filter, source) || checkFilter(filter, subSource)) { count = count + 1; if (subSource.isEmpty() && sourcesGrouped.get(source).size() > 1) { diff --git a/src/be/nikiroo/fanfix_swing/gui/utils/ListenerPanel.java b/src/be/nikiroo/fanfix_swing/gui/utils/ListenerPanel.java index 7ed5f86..98202b2 100644 --- a/src/be/nikiroo/fanfix_swing/gui/utils/ListenerPanel.java +++ b/src/be/nikiroo/fanfix_swing/gui/utils/ListenerPanel.java @@ -2,6 +2,8 @@ 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; @@ -10,12 +12,44 @@ import be.nikiroo.fanfix_swing.gui.SearchBar; /** * A {@link JPanel} with the default {@link ActionListener} add/remove/fire * methods. + *

+ * Note that it will queue all events until at least one listener comes (or + * comes back!); this first (or at least curently unique) listener will drain + * the queue. * * @author niki */ public class ListenerPanel extends JPanel { private static final long serialVersionUID = 1L; + private final Queue waitingQueue; + + /** + * Create a new {@link ListenerPanel}. + */ + public ListenerPanel() { + waitingQueue = new LinkedList(); + } + + /** + * 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 SearchBar}. @@ -23,6 +57,12 @@ public class ListenerPanel extends JPanel { * @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); } @@ -42,13 +82,17 @@ public class ListenerPanel extends JPanel { * @param listenerCommand A string that may specify a command (possibly one of * several) associated with the event */ - protected void fireActionPerformed(String listenerCommand) { + protected synchronized void fireActionPerformed(String listenerCommand) { ActionEvent e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, listenerCommand); - Object[] listeners = listenerList.getListenerList(); - for (int i = listeners.length - 2; i >= 0; i -= 2) { - if (listeners[i] == ActionListener.class) { - ((ActionListener) listeners[i + 1]).actionPerformed(e); + if (hasListeners()) { + Object[] listeners = listenerList.getListenerList(); + for (int i = listeners.length - 2; i >= 0; i -= 2) { + if (listeners[i] == ActionListener.class) { + ((ActionListener) listeners[i + 1]).actionPerformed(e); + } } + } else { + waitingQueue.add(e); } } } -- 2.27.0