diff options
author | Henri Sara <hesara@vaadin.com> | 2015-11-11 10:50:11 +0200 |
---|---|---|
committer | Henri Sara <hesara@vaadin.com> | 2016-01-15 14:42:58 +0200 |
commit | dbe6b5b266571f223bffd0354dbce651a5650411 (patch) | |
tree | 749277336c3db2dc1d00cc1dd33136385147de8e | |
parent | dca930baca68ec965407b7ab113eb0ef674452b5 (diff) | |
download | vaadin-framework-dbe6b5b266571f223bffd0354dbce651a5650411.tar.gz vaadin-framework-dbe6b5b266571f223bffd0354dbce651a5650411.zip |
Use a separate data received handler in VFilterSelect (#19929)
Move parts of the request handling to a separate handler
class that keeps track of the current communication state etc.
This is an intermediate change. Later changes should move
waitingForFilteringResponse etc. to the handler.
Change-Id: I762d15cc4b54ead3003e6d9d913e2a975256644c
-rw-r--r-- | client/src/com/vaadin/client/ui/VFilterSelect.java | 181 | ||||
-rw-r--r-- | client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java | 94 |
2 files changed, 156 insertions, 119 deletions
diff --git a/client/src/com/vaadin/client/ui/VFilterSelect.java b/client/src/com/vaadin/client/ui/VFilterSelect.java index 888c66bb87..525e5b3432 100644 --- a/client/src/com/vaadin/client/ui/VFilterSelect.java +++ b/client/src/com/vaadin/client/ui/VFilterSelect.java @@ -925,7 +925,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, /** * Send the current selection to the server. Triggered when a selection - * is made or on a blur event. + * is made with the ENTER key. */ public void doSelectedItemAction() { debug("VFS.SM: doSelectedItemAction()"); @@ -946,22 +946,30 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, return; } - setUpdateSelectionWhenReponseIsReceived(isWaitingForFilteringResponse()); - if (!isWaitingForFilteringResponse()) { + doPostFilterWhenReady(); + } + + /** + * Perform the post-filter action either now (if not waiting for a + * server response) or when a response is received. + */ + private void doPostFilterWhenReady() { + if (isWaitingForFilteringResponse()) { + dataReceivedHandler.setUpdateOnDataReceived(true); + } else { + dataReceivedHandler.setUpdateOnDataReceived(false); doPostFilterSelectedItemAction(); } } /** - * Triggered after a selection has been made + * Triggered after a selection has been made. */ public void doPostFilterSelectedItemAction() { debug("VFS.SM: doPostFilterSelectedItemAction()"); final MenuItem item = getSelectedItem(); final String enteredItemValue = tb.getText(); - setUpdateSelectionWhenReponseIsReceived(false); - // check for exact match in menu int p = getItems().size(); if (p > 0) { @@ -1163,6 +1171,128 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, } + /** + * Handler receiving notifications from the connector and updating the + * widget state accordingly. + * + * This class is still subject to change and should not be considered as + * public stable API. + * + * @since + */ + public class DataReceivedHandler { + + private Runnable navigationCallback = null; + /** + * Set true when popupopened has been clicked. Cleared on each + * UIDL-update. This handles the special case where are not filtering + * yet and the selected value has changed on the server-side. See #2119 + * <p> + * For internal use only. May be removed or replaced in the future. + */ + private boolean popupOpenerClicked = false; + private boolean updateOnDataReceived = false; + + /** + * Called by the connector when new data for the last requested filter + * is received from the server. + */ + public void dataReceived() { + suggestionPopup.showSuggestions(currentSuggestions, currentPage, + totalMatches); + + setWaitingForFilteringResponse(false); + + if (!popupOpenerClicked) { + navigateItemAfterPageChange(); + } + + if (updateOnDataReceived) { + updateOnDataReceived = false; + suggestionPopup.menu.doPostFilterSelectedItemAction(); + } + + popupOpenerClicked = false; + } + + /* + * This method navigates to the proper item in the combobox page. This + * should be executed after setSuggestions() method which is called from + * vFilterSelect.showSuggestions(). ShowSuggestions() method builds the + * page content. As far as setSuggestions() method is called as + * deferred, navigateItemAfterPageChange method should be also be called + * as deferred. #11333 + */ + private void navigateItemAfterPageChange() { + if (navigationCallback != null) { + // pageChangeCallback is not reset here but after any server + // request in case you are in between two requests both changing + // the page back and forth + + // we're paging w/ arrows + Scheduler.get().scheduleDeferred(new ScheduledCommand() { + @Override + public void execute() { + if (navigationCallback != null) { + navigationCallback.run(); + } + } + }); + } + } + + /** + * Called by the connector when any request has been sent to the server, + * before waiting for a reply. + */ + public void anyRequestSentToServer() { + navigationCallback = null; + } + + /** + * Set a callback that is invoked when a page change occurs if there + * have not been intervening requests to the server. The callback is + * reset when any additional request is made to the server. + * + * @param callback + */ + public void setNavigationCallback(Runnable callback) { + navigationCallback = callback; + } + + /** + * Record that the popup opener has been clicked and the popup should be + * opened on the next request. + * + * This handles the special case where are not filtering yet and the + * selected value has changed on the server-side. See #2119. The flag is + * cleared on each UIDL reply. + */ + public void popupOpenerClicked() { + popupOpenerClicked = true; + } + + /** + * Returns true if the popup opener has been clicked. This method is for + * internal use only and will most likely be removed in the future. + */ + public boolean isPopupOpenerClicked() { + return popupOpenerClicked; + } + + public void setUpdateOnDataReceived(boolean update) { + updateOnDataReceived = update; + } + + /** + * Called by the connector when it has finished handling any reply from + * the server, regardless of what was updated. + */ + public void serverReplyHandled() { + popupOpenerClicked = false; + } + } + @Deprecated public static final FilteringMode FILTERINGMODE_OFF = FilteringMode.OFF; @Deprecated @@ -1245,9 +1375,6 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, private boolean waitingForFilteringResponse = false; /** For internal use only. May be removed or replaced in the future. */ - private boolean updateSelectionWhenReponseIsReceived = false; - - /** For internal use only. May be removed or replaced in the future. */ public boolean initDone = false; /** For internal use only. May be removed or replaced in the future. */ @@ -1313,6 +1440,8 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, */ private boolean textInputEnabled = true; + private final DataReceivedHandler dataReceivedHandler = new DataReceivedHandler(); + /** * Default constructor. */ @@ -1587,7 +1716,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, debug("VFS: onSuggestionSelected(" + suggestion.caption + ": " + suggestion.key + ")"); } - setUpdateSelectionWhenReponseIsReceived(false); + dataReceivedHandler.setUpdateOnDataReceived(false); currentSuggestion = suggestion; String newKey; @@ -1858,7 +1987,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, private void selectPrevPage() { if (currentPage > 0) { filterOptions(currentPage - 1, lastFilter); - connector.setNavigateAfterPageReceivedCallback(new Runnable() { + dataReceivedHandler.setNavigationCallback(new Runnable() { @Override public void run() { suggestionPopup.selectLastItem(); @@ -1873,7 +2002,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, private void selectNextPage() { if (hasNextPage()) { filterOptions(currentPage + 1, lastFilter); - connector.setNavigateAfterPageReceivedCallback(new Runnable() { + dataReceivedHandler.setNavigationCallback(new Runnable() { @Override public void run() { suggestionPopup.selectFirstItem(); @@ -1969,7 +2098,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, boolean immediate = focused || !connector.hasEventListener(EventId.FOCUS); filterOptions(-1, "", immediate); - connector.popupOpenerClicked(); + dataReceivedHandler.popupOpenerClicked(); lastFilter = ""; } DOM.eventPreventDefault(DOM.eventGetCurrentEvent()); @@ -2330,29 +2459,13 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, } /** - * For internal use only - this method will be removed in the future. - * - * This flag should not be set when not waiting for a reply from the server. - * - * @return true if the selection should be updated when a server response is - * received - */ - public boolean isUpdateSelectionWhenReponseIsReceived() { - return updateSelectionWhenReponseIsReceived; - } - - /** - * For internal use only - this method will be removed in the future. - * - * This flag should not be set when not waiting for a reply from the server. + * Returns a handler receiving notifications from the connector about + * communications. * - * @param updateSelectionWhenReponseIsReceived - * true if the selection should be updated when a server response - * is received + * @return the dataReceivedHandler */ - public void setUpdateSelectionWhenReponseIsReceived( - boolean updateSelectionWhenReponseIsReceived) { - this.updateSelectionWhenReponseIsReceived = updateSelectionWhenReponseIsReceived; + public DataReceivedHandler getDataReceivedHandler() { + return dataReceivedHandler; } } diff --git a/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java b/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java index df6e800893..e367834d1e 100644 --- a/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java +++ b/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java @@ -19,8 +19,6 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import com.google.gwt.core.client.Scheduler; -import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.vaadin.client.ApplicationConnection; import com.vaadin.client.Paintable; import com.vaadin.client.Profiler; @@ -54,17 +52,6 @@ public class ComboBoxConnector extends AbstractFieldConnector implements private boolean immediate; - private Runnable pageChangeCallback; - - /** - * Set true when popupopened has been clicked. Cleared on each UIDL-update. - * This handles the special case where are not filtering yet and the - * selected value has changed on the server-side. See #2119 - * <p> - * For internal use only. May be removed or replaced in the future. - */ - private boolean popupOpenerClicked; - @Override protected void init() { super.init(); @@ -215,31 +202,16 @@ public class ComboBoxConnector extends AbstractFieldConnector implements } } + // TODO even this condition should probably be moved to the handler if ((getWidget().isWaitingForFilteringResponse() && getWidget().lastFilter .toLowerCase().equals(uidl.getStringVariable("filter"))) || popupOpenAndCleared) { - - getWidget().suggestionPopup.showSuggestions( - getWidget().currentSuggestions, getWidget().currentPage, - getWidget().totalMatches); - - getWidget().setWaitingForFilteringResponse(false); - - if (!popupOpenerClicked) { - navigateItemAfterPageChange(); - } - - if (getWidget().isUpdateSelectionWhenReponseIsReceived()) { - getWidget().suggestionPopup.menu - .doPostFilterSelectedItemAction(); - } + getWidget().getDataReceivedHandler().dataReceived(); } // Calculate minimum textarea width getWidget().updateSuggestionPopupMinWidth(); - popupOpenerClicked = false; - /* * if this is our first time we need to recalculate the root width. */ @@ -255,32 +227,9 @@ public class ComboBoxConnector extends AbstractFieldConnector implements } getWidget().initDone = true; - } - /* - * This method navigates to the proper item in the combobox page. This - * should be executed after setSuggestions() method which is called from - * vFilterSelect.showSuggestions(). ShowSuggestions() method builds the page - * content. As far as setSuggestions() method is called as deferred, - * navigateItemAfterPageChange method should be also be called as deferred. - * #11333 - */ - private void navigateItemAfterPageChange() { - if (pageChangeCallback != null) { - // pageChangeCallback is not reset here but after any server request - // in case you are in between two requests both changing the page - // back and forth - - // we're paging w/ arrows - Scheduler.get().scheduleDeferred(new ScheduledCommand() { - @Override - public void execute() { - if (pageChangeCallback != null) { - pageChangeCallback.run(); - } - } - }); - } + // TODO this should perhaps be moved to be a part of dataReceived() + getWidget().getDataReceivedHandler().serverReplyHandled(); } private void performSelection(String selectedKey) { @@ -291,7 +240,8 @@ public class ComboBoxConnector extends AbstractFieldConnector implements continue; } if (!getWidget().isWaitingForFilteringResponse() - || popupOpenerClicked) { + || getWidget().getDataReceivedHandler() + .isPopupOpenerClicked()) { if (!suggestionKey.equals(getWidget().selectedOptionKey) || suggestion.getReplacementString().equals( getWidget().tb.getText()) @@ -320,7 +270,8 @@ public class ComboBoxConnector extends AbstractFieldConnector implements } private void resetSelection() { - if (!getWidget().isWaitingForFilteringResponse() || popupOpenerClicked) { + if (!getWidget().isWaitingForFilteringResponse() + || getWidget().getDataReceivedHandler().isPopupOpenerClicked()) { // select nulled if (!getWidget().focused) { /* @@ -478,19 +429,6 @@ public class ComboBoxConnector extends AbstractFieldConnector implements } } - /** - * Set a callback that is invoked when a page change occurs if there have - * not been intervening requests to the server. The callback is reset when - * any additional request is made to the server. - * - * @since - * @param callback - */ - public void setNavigateAfterPageReceivedCallback(Runnable callback) { - pageChangeCallback = callback; - - } - /* * Anything that should be set after the client updates the server. */ @@ -498,21 +436,7 @@ public class ComboBoxConnector extends AbstractFieldConnector implements // We need this here to be consistent with the all the calls. // Then set your specific selection type only after // a server request method call. - pageChangeCallback = null; - } - - /** - * Record that the popup opener has been clicked and the popup should be - * opened on the next request. - * - * This handles the special case where are not filtering yet and the - * selected value has changed on the server-side. See #2119. The flag is - * cleared on each UIDL reply. - * - * @since - */ - public void popupOpenerClicked() { - popupOpenerClicked = true; + getWidget().getDataReceivedHandler().anyRequestSentToServer(); } } |