X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fbe%2Fnikiroo%2Ffanfix_swing%2Fgui%2FBooksPanel.java;h=20e28af116f4aba190ad0e643eacc47019ef4812;hb=89c5b3e28f9f73777541157adf4e4b4fe25ad50d;hp=579f394702aa9a7d4a45f6fcd13cca3d743342d5;hpb=59253323f07e6a67ef6c8e197fd1065a81c7069a;p=fanfix.git diff --git a/src/be/nikiroo/fanfix_swing/gui/BooksPanel.java b/src/be/nikiroo/fanfix_swing/gui/BooksPanel.java index 579f394..20e28af 100644 --- a/src/be/nikiroo/fanfix_swing/gui/BooksPanel.java +++ b/src/be/nikiroo/fanfix_swing/gui/BooksPanel.java @@ -2,6 +2,7 @@ package be.nikiroo.fanfix_swing.gui; import java.awt.BorderLayout; import java.awt.Component; +import java.awt.Dimension; import java.awt.Image; import java.awt.Point; import java.awt.event.ActionEvent; @@ -10,19 +11,15 @@ import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.HashMap; -import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.Queue; import java.util.concurrent.ExecutionException; import javax.swing.DefaultListModel; import javax.swing.JList; -import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.ListCellRenderer; import javax.swing.ListSelectionModel; -import javax.swing.SwingUtilities; import javax.swing.SwingWorker; import be.nikiroo.fanfix.Instance; @@ -33,10 +30,12 @@ import be.nikiroo.fanfix_swing.gui.book.BookBlock; import be.nikiroo.fanfix_swing.gui.book.BookInfo; import be.nikiroo.fanfix_swing.gui.book.BookLine; import be.nikiroo.fanfix_swing.gui.book.BookPopup; +import be.nikiroo.fanfix_swing.gui.utils.DelayWorker; +import be.nikiroo.fanfix_swing.gui.utils.ListenerPanel; import be.nikiroo.fanfix_swing.gui.utils.UiHelper; -public class BooksPanel extends JPanel { - class ListModel extends DefaultListModel { +public class BooksPanel extends ListenerPanel { + private class ListModel extends DefaultListModel { public void fireElementChanged(BookInfo element) { int index = indexOf(element); if (index >= 0) { @@ -45,6 +44,8 @@ public class BooksPanel extends JPanel { } } + static public final String INVALIDATE_CACHE = "invalidate_cache"; + private List bookInfos = new ArrayList(); private Map books = new HashMap(); private boolean seeWordCount; @@ -53,12 +54,10 @@ public class BooksPanel extends JPanel { private JList list; private int hoveredIndex = -1; private ListModel data = new ListModel(); + private DelayWorker bookCoverUpdater; private SearchBar searchBar; - private Queue updateBookQueue = new LinkedList(); - private Object updateBookQueueLock = new Object(); - public BooksPanel(boolean listMode) { setLayout(new BorderLayout()); @@ -68,66 +67,27 @@ public class BooksPanel extends JPanel { searchBar.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - reload(searchBar.getText()); + filter(searchBar.getText()); } }); + bookCoverUpdater = new DelayWorker(20); + bookCoverUpdater.start(); add(UiHelper.scroll(initList(listMode)), BorderLayout.CENTER); - - Thread bookBlocksUpdater = new Thread(new Runnable() { - @Override - public void run() { - while (true) { - BasicLibrary lib = Instance.getInstance().getLibrary(); - while (true) { - final BookBlock book; - synchronized (updateBookQueueLock) { - if (!updateBookQueue.isEmpty()) { - book = updateBookQueue.remove(); - } else { - book = null; - break; - } - } - - try { - final Image coverImage = BookBlock.generateCoverImage(lib, book.getInfo()); - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - try { - book.setCoverImage(coverImage); - data.fireElementChanged(book.getInfo()); - } catch (Exception e) { - } - } - }); - } catch (Exception e) { - } - } - - try { - Thread.sleep(10); - } catch (InterruptedException e) { - } - } - } - }); - bookBlocksUpdater.setName("BookBlocks visual updater"); - bookBlocksUpdater.setDaemon(true); - bookBlocksUpdater.start(); } // null or empty -> all sources // sources hierarchy supported ("source/" will includes all "source" and // "source/*") - public void load(final List sources, final List authors, final List tags) { + public void load(final List sources, final List authors, + final List tags) { new SwingWorker, Void>() { @Override protected List doInBackground() throws Exception { List bookInfos = new ArrayList(); BasicLibrary lib = Instance.getInstance().getLibrary(); - for (MetaData meta : lib.getList(null).filter(sources, authors, tags)) { + for (MetaData meta : lib.getList().filter(sources, authors, + tags)) { bookInfos.add(BookInfo.fromMeta(lib, meta)); } @@ -151,18 +111,18 @@ public class BooksPanel extends JPanel { public void load(List bookInfos) { this.bookInfos.clear(); this.bookInfos.addAll(bookInfos); - synchronized (updateBookQueueLock) { - updateBookQueue.clear(); - } + bookCoverUpdater.clear(); - reload(searchBar.getText()); + filter(searchBar.getText()); } // cannot be NULL - private void reload(String filter) { + 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); } } @@ -181,7 +141,8 @@ public class BooksPanel extends JPanel { /** * The secondary value content: word count or author. * - * @param seeWordCount TRUE to see word counts, FALSE to see authors + * @param seeWordCount + * TRUE to see word counts, FALSE to see authors */ public void setSeeWordCount(boolean seeWordCount) { if (this.seeWordCount != seeWordCount) { @@ -198,36 +159,43 @@ public class BooksPanel extends JPanel { private JList initList(boolean listMode) { final JList list = new JList(data); - final JPopupMenu popup = new BookPopup(Instance.getInstance().getLibrary(), new BookPopup.Informer() { - @Override - public void setCached(BookInfo book, boolean cached) { - book.setCached(cached); - fireElementChanged(book); - } + final JPopupMenu popup = new BookPopup( + Instance.getInstance().getLibrary(), new BookPopup.Informer() { + @Override + public void setCached(BookInfo book, boolean cached) { + book.setCached(cached); + fireElementChanged(book); + } - public void fireElementChanged(BookInfo book) { - data.fireElementChanged(book); - } + public void fireElementChanged(BookInfo book) { + data.fireElementChanged(book); + } - @Override - public List getSelected() { - List selected = new ArrayList(); - for (int index : list.getSelectedIndices()) { - selected.add(data.get(index)); - } + @Override + public List getSelected() { + List selected = new ArrayList(); + for (int index : list.getSelectedIndices()) { + selected.add(data.get(index)); + } - return selected; - } + return selected; + } - @Override - public BookInfo getUniqueSelected() { - List selected = getSelected(); - if (selected.size() == 1) { - return selected.get(0); - } - return null; - } - }); + @Override + public BookInfo getUniqueSelected() { + List selected = getSelected(); + if (selected.size() == 1) { + return selected.get(0); + } + return null; + } + + @Override + public void invalidateCache() { + // TODO: also reset the popup menu for sources/author + fireActionPerformed(INVALIDATE_CACHE); + } + }); list.addMouseMotionListener(new MouseAdapter() { @Override @@ -275,20 +243,22 @@ public class BooksPanel extends JPanel { final BookInfo book = data.get(index); BasicLibrary lib = Instance.getInstance().getLibrary(); - Actions.openExternal(lib, book.getMeta(), BooksPanel.this, new Runnable() { - @Override - public void run() { - book.setCached(true); - data.fireElementChanged(book); - } - }); + Actions.openExternal(lib, book.getMeta(), BooksPanel.this, + new Runnable() { + @Override + public void run() { + book.setCached(true); + data.fireElementChanged(book); + } + }); } } private void check(MouseEvent e) { if (e.isPopupTrigger()) { if (list.getSelectedIndices().length <= 1) { - list.setSelectedIndex(list.locationToIndex(e.getPoint())); + list.setSelectedIndex( + list.locationToIndex(e.getPoint())); } popup.show(list, e.getX(), e.getY()); @@ -309,7 +279,8 @@ public class BooksPanel extends JPanel { private ListCellRenderer generateRenderer() { return new ListCellRenderer() { @Override - public Component getListCellRendererComponent(JList list, BookInfo value, int index, + public Component getListCellRendererComponent( + JList list, BookInfo value, int index, boolean isSelected, boolean cellHasFocus) { BookLine book = books.get(value); if (book == null) { @@ -317,9 +288,7 @@ public class BooksPanel extends JPanel { book = new BookLine(value, seeWordCount); } else { book = new BookBlock(value, seeWordCount); - synchronized (updateBookQueueLock) { - updateBookQueue.add((BookBlock) book); - } + startUpdateBookCover((BookBlock) book); } books.put(value, book); } @@ -331,6 +300,27 @@ public class BooksPanel extends JPanel { }; } + private void startUpdateBookCover(final BookBlock book) { + bookCoverUpdater.delay(book.getInfo().getId(), + new SwingWorker() { + @Override + protected Image doInBackground() throws Exception { + BasicLibrary lib = Instance.getInstance().getLibrary(); + return BookBlock.generateCoverImage(lib, + book.getInfo()); + } + + protected void done() { + try { + book.setCoverImage(get()); + data.fireElementChanged(book.getInfo()); + } catch (Exception e) { + // TODO ? probably just log + } + } + }); + } + public boolean isListMode() { return listMode; } @@ -338,12 +328,27 @@ public class BooksPanel extends JPanel { public void setListMode(boolean listMode) { this.listMode = listMode; books.clear(); - list.setLayoutOrientation(listMode ? JList.VERTICAL : JList.HORIZONTAL_WRAP); + list.setLayoutOrientation( + listMode ? JList.VERTICAL : JList.HORIZONTAL_WRAP); + StringBuilder longString = new StringBuilder(); + for (int i = 0; i < 20; i++) { + longString.append( + "Some long string, which is 50 chars long itself..."); + } if (listMode) { - synchronized (updateBookQueueLock) { - updateBookQueue.clear(); - } + bookCoverUpdater.clear(); + Dimension sz = new BookLine( + BookInfo.fromSource(null, longString.toString()), true) + .getPreferredSize(); + list.setFixedCellHeight((int) sz.getHeight()); + list.setFixedCellWidth(list.getWidth()); + } else { + Dimension sz = new BookBlock( + BookInfo.fromSource(null, longString.toString()), true) + .getPreferredSize(); + list.setFixedCellHeight((int) sz.getHeight()); + list.setFixedCellWidth((int) sz.getWidth()); } } }