From 54e979756607ffb833b22785cc4bb07a16398878 Mon Sep 17 00:00:00 2001 From: bancika Date: Wed, 26 Oct 2016 12:04:04 +0200 Subject: [PATCH] search paging improvement --- .../cloud/presenter/PagingProvider.java | 40 +++++++++ .../src/org/diylc/images/IconLoader.java | 2 +- .../src/org/diylc/images/cloud_big.png | Bin 0 -> 6895 bytes ...sPane.java => AnimatedCloudGlassPane.java} | 6 +- .../cloud/view/browser/CloudBrowserFrame.java | 40 ++------- .../cloud/view/browser/ILazyProvider.java | 21 ----- .../view/browser/ResultsScrollPanel.java | 53 ++++++++++-- .../view/browser/SimpleCloudGlassPane.java | 79 ++++++++++++++++++ 8 files changed, 176 insertions(+), 65 deletions(-) create mode 100644 diylc/diylc-core/src/org/diylc/plugins/cloud/presenter/PagingProvider.java create mode 100644 diylc/diylc-swing/src/org/diylc/images/cloud_big.png rename diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/{CloudGlassPane.java => AnimatedCloudGlassPane.java} (92%) delete mode 100644 diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/ILazyProvider.java create mode 100644 diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/SimpleCloudGlassPane.java diff --git a/diylc/diylc-core/src/org/diylc/plugins/cloud/presenter/PagingProvider.java b/diylc/diylc-core/src/org/diylc/plugins/cloud/presenter/PagingProvider.java new file mode 100644 index 00000000..770b1f78 --- /dev/null +++ b/diylc/diylc-core/src/org/diylc/plugins/cloud/presenter/PagingProvider.java @@ -0,0 +1,40 @@ +package org.diylc.plugins.cloud.presenter; + +import java.util.List; + +import org.diylc.plugins.cloud.model.ProjectEntity; + +public class PagingProvider { + + private CloudPresenter cloudPresenter; + + private String searchFor; + private String category; + private String sort; + private int itemsPerPage = 10; + + private int currentPage; + private List currentResults; + + public PagingProvider(CloudPresenter cloudPresenter) { + this.cloudPresenter = cloudPresenter; + } + + public List startSession(String searchFor, String category, String sort) throws CloudException { + this.searchFor = searchFor; + this.category = category; + this.sort = sort; + this.currentPage = 1; + + return currentResults = cloudPresenter.search(searchFor, category, sort, currentPage, itemsPerPage); + } + + public boolean hasMoreData() { + return this.currentResults != null && this.currentResults.size() == itemsPerPage; + } + + public List requestMoreData() throws CloudException { + currentPage++; + return currentResults = cloudPresenter.search(searchFor, category, sort, currentPage, itemsPerPage); + } +} diff --git a/diylc/diylc-swing/src/org/diylc/images/IconLoader.java b/diylc/diylc-swing/src/org/diylc/images/IconLoader.java index a7a55879..6bf6f5f8 100644 --- a/diylc/diylc-swing/src/org/diylc/images/IconLoader.java +++ b/diylc/diylc-swing/src/org/diylc/images/IconLoader.java @@ -33,7 +33,7 @@ public enum IconLoader { "arrow.png"), Cloud("cloud.png"), CloudUp("cloud_up.png"), CloudGear("cloud_gear.png"), IdCardEdit( "id_card_edit.png"), KeyEdit("key_edit.png"), Find("find.png"), Dashboard("dashboard.png"), DataFind( "data_find.png"), CloudDownload("cloud-download.png"), NavLeftBlue("nav_left_blue.png"), NavRightBlue( - "nav_right_blue.png"), MissingImage("missing_image.png"), CloudBg("cloud_bg.png"); + "nav_right_blue.png"), MissingImage("missing_image.png"), CloudBg("cloud_bg.png"), CloudBig("cloud_big.png"); protected String name; diff --git a/diylc/diylc-swing/src/org/diylc/images/cloud_big.png b/diylc/diylc-swing/src/org/diylc/images/cloud_big.png new file mode 100644 index 0000000000000000000000000000000000000000..fdbfdf4636ef8bb7f14d383ec57d796a517778bd GIT binary patch literal 6895 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 literal 0 HcmV?d00001 diff --git a/diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/CloudGlassPane.java b/diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/AnimatedCloudGlassPane.java similarity index 92% rename from diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/CloudGlassPane.java rename to diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/AnimatedCloudGlassPane.java index c0efa715..6c178651 100644 --- a/diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/CloudGlassPane.java +++ b/diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/AnimatedCloudGlassPane.java @@ -28,9 +28,9 @@ import org.diylc.images.IconLoader; * * @author bancika */ -public class CloudGlassPane extends JPanel implements MouseListener, KeyListener { +public class AnimatedCloudGlassPane extends JPanel implements MouseListener, KeyListener { - public static final CloudGlassPane GLASS_PANE = new CloudGlassPane(); + public static final AnimatedCloudGlassPane GLASS_PANE = new AnimatedCloudGlassPane(); private static final long serialVersionUID = -5344758920442881290L; @@ -42,7 +42,7 @@ public class CloudGlassPane extends JPanel implements MouseListener, KeyListener private VolatileImage volatileImg; - public CloudGlassPane() { + public AnimatedCloudGlassPane() { addKeyListener(this); addMouseListener(this); setCursor(new Cursor(Cursor.WAIT_CURSOR)); diff --git a/diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/CloudBrowserFrame.java b/diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/CloudBrowserFrame.java index f9f68ad4..9c322f9c 100644 --- a/diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/CloudBrowserFrame.java +++ b/diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/CloudBrowserFrame.java @@ -27,6 +27,7 @@ import org.diylc.core.IView; import org.diylc.images.IconLoader; import org.diylc.plugins.cloud.model.ProjectEntity; import org.diylc.plugins.cloud.presenter.CloudPresenter; +import org.diylc.plugins.cloud.presenter.PagingProvider; import org.diylc.swing.ISwingUI; public class CloudBrowserFrame extends JFrame { @@ -45,15 +46,7 @@ public class CloudBrowserFrame extends JFrame { private IPlugInPort plugInPort; private CloudPresenter cloudPresenter; - - private List currentResults; - - // search criteria - private String searchFor; - private String category; - private String sort; - private int pageNumber; - private int itemsPerPage = 10; + private PagingProvider pagingProvider; private ISwingUI swingUI; @@ -64,11 +57,12 @@ public class CloudBrowserFrame extends JFrame { this.setPreferredSize(new Dimension(700, 640)); this.plugInPort = plugInPort; this.cloudPresenter = cloudPresenter; + this.pagingProvider = new PagingProvider(cloudPresenter); setContentPane(getSearchPanel()); this.pack(); this.setLocationRelativeTo(swingUI.getOwnerFrame()); - this.setGlassPane(new CloudGlassPane()); + this.setGlassPane(SimpleCloudGlassPane.GLASS_PANE); JRootPane rootPane = SwingUtilities.getRootPane(getSearchHeaderPanel().getGoButton()); rootPane.setDefaultButton(getSearchHeaderPanel().getGoButton()); @@ -144,11 +138,6 @@ public class CloudBrowserFrame extends JFrame { @Override public void actionPerformed(ActionEvent e) { - CloudBrowserFrame.this.pageNumber = 1; - CloudBrowserFrame.this.searchFor = getSearchHeaderPanel().getSearchText(); - CloudBrowserFrame.this.category = getSearchHeaderPanel().getCategory(); - CloudBrowserFrame.this.sort = getSearchHeaderPanel().getSorting(); - getResultsScrollPane().startOver(); search(); } }); @@ -158,29 +147,19 @@ public class CloudBrowserFrame extends JFrame { private ResultsScrollPanel getResultsScrollPane() { if (resultsScrollPane == null) { - resultsScrollPane = new ResultsScrollPanel(swingUI, this, plugInPort, new ILazyProvider() { - - @Override - public void requestMoreData() { - CloudBrowserFrame.this.pageNumber++; - CloudBrowserFrame.this.search(); - } - - @Override - public boolean hasMoreData() { - return currentResults.size() == itemsPerPage; - } - }); + resultsScrollPane = new ResultsScrollPanel(swingUI, this, plugInPort, pagingProvider); } return resultsScrollPane; } private void search() { + getResultsScrollPane().clearPrevious(); executeBackgroundTask(new ITask>() { @Override public List doInBackground() throws Exception { - return cloudPresenter.search(searchFor, category, sort, pageNumber, itemsPerPage); + return pagingProvider.startSession(getSearchHeaderPanel().getSearchText(), + getSearchHeaderPanel().getCategory(), getSearchHeaderPanel().getSorting()); } @Override @@ -191,8 +170,7 @@ public class CloudBrowserFrame extends JFrame { @Override public void complete(List result) { - CloudBrowserFrame.this.currentResults = result; - getResultsScrollPane().addData(result); + getResultsScrollPane().startSearch(result); } }); } diff --git a/diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/ILazyProvider.java b/diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/ILazyProvider.java deleted file mode 100644 index 341bb60e..00000000 --- a/diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/ILazyProvider.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.diylc.swing.plugins.cloud.view.browser; - -/*** - * Generic interface for dynamic data provider. - * - * @author Branislav Stojkovic - * - * @param - */ -public interface ILazyProvider { - - /** - * @return true if there's potentially more data at the source - */ - boolean hasMoreData(); - - /** - * call to request more data. New data batch should be sent asynchronously to this function call. - */ - void requestMoreData(); -} diff --git a/diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/ResultsScrollPanel.java b/diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/ResultsScrollPanel.java index 8b6ae4c2..ec248635 100644 --- a/diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/ResultsScrollPanel.java +++ b/diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/ResultsScrollPanel.java @@ -6,7 +6,6 @@ import java.awt.Graphics; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; -import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; @@ -29,6 +28,7 @@ import javax.swing.JScrollPane; import javax.swing.JSeparator; import javax.swing.JTextArea; import javax.swing.SwingConstants; +import javax.swing.SwingWorker; import org.apache.log4j.Logger; import org.diylc.common.IPlugInPort; @@ -36,6 +36,7 @@ import org.diylc.common.ITask; import org.diylc.core.IView; import org.diylc.images.IconLoader; import org.diylc.plugins.cloud.model.ProjectEntity; +import org.diylc.plugins.cloud.presenter.PagingProvider; import org.diylc.swing.ISwingUI; import org.diylc.swing.gui.DialogFactory; import org.diylc.swing.plugins.file.FileFilterEnum; @@ -63,10 +64,9 @@ public class ResultsScrollPanel extends JScrollPane { * This flag tells us whether the loadMoreLabel should invoke a new data pull or not. */ private boolean armed; - private ILazyProvider provider; + private PagingProvider provider; - public ResultsScrollPanel(ISwingUI mainUI, CloudBrowserFrame cloudUI, IPlugInPort plugInPort, - ILazyProvider provider) { + public ResultsScrollPanel(ISwingUI mainUI, CloudBrowserFrame cloudUI, IPlugInPort plugInPort, PagingProvider provider) { super(); this.mainUI = mainUI; this.cloudUI = cloudUI; @@ -78,18 +78,24 @@ public class ResultsScrollPanel extends JScrollPane { setViewportView(getResultsPanel()); } - public void startOver() { + public void clearPrevious() { currentLocation = 0; getResultsPanel().removeAll(); armed = false; + } + + public void startSearch(List projects) { GridBagConstraints gbc = new GridBagConstraints(); gbc.anchor = GridBagConstraints.NORTHWEST; gbc.gridx = 0; gbc.gridy = 10000; gbc.fill = GridBagConstraints.BOTH; - gbc.weightx = 0; + gbc.weightx = 1; gbc.weighty = 100; + gbc.gridwidth = 3; resultsPanel.add(getLoadMoreLabel(), gbc); + + addData(projects); } public void showNoMatches() { @@ -109,12 +115,15 @@ public class ResultsScrollPanel extends JScrollPane { if (projects == null || projects.isEmpty() && currentLocation == 0) { showNoMatches(); } else { + LOG.info("Adding " + projects.size() + " projects to display."); for (int i = 0; i < projects.size(); i++) { addProjectToDisplay(projects.get(i)); this.currentLocation++; } armed = true; - } + } + + getLoadMoreLabel().setText(provider.hasMoreData() ? "Loading more data..." : ""); } private JComponent addProjectToDisplay(final ProjectEntity project) { @@ -253,24 +262,50 @@ public class ResultsScrollPanel extends JScrollPane { gbc.insets = new Insets(2, 2, 2, 2); getResultsPanel().add(new JSeparator(), gbc); + getResultsPanel().invalidate(); + return thumbnailLabel; } private JLabel getLoadMoreLabel() { if (loadMoreLabel == null) { - loadMoreLabel = new JLabel("Load more...") { + loadMoreLabel = new JLabel("Loading more data...") { private static final long serialVersionUID = 1L; @Override public void paint(Graphics g) { + super.paint(g); if (armed && provider.hasMoreData()) { // disarm immediately so we don't trigger successive requests to the provider armed = false; - provider.requestMoreData(); + SwingWorker, Void> worker = new SwingWorker, Void>() { + + @Override + protected List doInBackground() throws Exception { + return provider.requestMoreData(); + } + + @Override + protected void done() { + try { + List newResults = get(); + if (newResults != null && !newResults.isEmpty()) + addData(newResults); + else + getLoadMoreLabel().setText(""); + } catch (Exception e) { + cloudUI.showMessage("Search failed! Detailed message is in the logs. Please report to the author.", + "Search Failed", IView.ERROR_MESSAGE); + } + } + }; + worker.execute(); } } }; + loadMoreLabel.setHorizontalAlignment(SwingConstants.CENTER); + loadMoreLabel.setFont(loadMoreLabel.getFont().deriveFont(10f)); } return loadMoreLabel; } diff --git a/diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/SimpleCloudGlassPane.java b/diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/SimpleCloudGlassPane.java new file mode 100644 index 00000000..c3413530 --- /dev/null +++ b/diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/SimpleCloudGlassPane.java @@ -0,0 +1,79 @@ +package org.diylc.swing.plugins.cloud.view.browser; + +import java.awt.Cursor; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.SwingConstants; + +import org.diylc.images.IconLoader; + +/** + * JPanel that shows cloud animation while visible. + * + * @author bancika + */ +public class SimpleCloudGlassPane extends JPanel implements MouseListener, KeyListener { + + public static final SimpleCloudGlassPane GLASS_PANE = new SimpleCloudGlassPane(); + + private static final long serialVersionUID = -5344758920442881290L; + + + public SimpleCloudGlassPane() { + addKeyListener(this); + addMouseListener(this); + setCursor(new Cursor(Cursor.WAIT_CURSOR)); + setOpaque(false); + + setLayout(new GridBagLayout()); + + GridBagConstraints gbc = new GridBagConstraints(); + gbc.gridx = 0; + gbc.gridy = 0; + gbc.anchor = GridBagConstraints.LAST_LINE_START; + gbc.fill = GridBagConstraints.HORIZONTAL; + gbc.weightx = 1; + gbc.weighty = 1; + JLabel cloudLabel = new JLabel(IconLoader.CloudBig.getIcon()); + cloudLabel.setHorizontalAlignment(SwingConstants.CENTER); + add(cloudLabel, gbc); + + gbc.gridy = 1; + gbc.weighty = 1.5; + gbc.anchor = GridBagConstraints.FIRST_LINE_START; + JLabel label = new JLabel("Querying the cloud..."); + label.setHorizontalAlignment(SwingConstants.CENTER); + add(label, gbc); + } + + @Override + public void mouseClicked(final MouseEvent pArg0) {} + + @Override + public void mouseEntered(final MouseEvent pArg0) {} + + @Override + public void mouseExited(final MouseEvent pArg0) {} + + @Override + public void mousePressed(final MouseEvent pArg0) {} + + @Override + public void mouseReleased(final MouseEvent pArg0) {} + + @Override + public void keyPressed(KeyEvent e) {} + + @Override + public void keyReleased(KeyEvent e) {} + + @Override + public void keyTyped(KeyEvent e) {} +}