aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArtur <artur@vaadin.com>2017-06-29 09:06:24 +0300
committerHenri Sara <henri.sara@gmail.com>2017-06-29 09:06:24 +0300
commite7898f59177e9e7f13f2c26fb2d44e8ae489f6cb (patch)
tree7c2442f3c93e3e5d4a4b993e419b24aba1db5def
parent173ac5b1def8785ac5b1c5b1fdd08b8bdf09b936 (diff)
downloadvaadin-framework-e7898f59177e9e7f13f2c26fb2d44e8ae489f6cb.tar.gz
vaadin-framework-e7898f59177e9e7f13f2c26fb2d44e8ae489f6cb.zip
Add isUserOriginated to SelectedTabChangeEvent (#9580)
Fixes #9545
-rw-r--r--server/src/main/java/com/vaadin/data/HasUserOriginated.java35
-rw-r--r--server/src/main/java/com/vaadin/data/HasValue.java15
-rw-r--r--server/src/main/java/com/vaadin/ui/TabSheet.java115
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/tabsheet/TabSheetTest.java52
4 files changed, 174 insertions, 43 deletions
diff --git a/server/src/main/java/com/vaadin/data/HasUserOriginated.java b/server/src/main/java/com/vaadin/data/HasUserOriginated.java
new file mode 100644
index 0000000000..e7d6d125b5
--- /dev/null
+++ b/server/src/main/java/com/vaadin/data/HasUserOriginated.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2000-2016 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.data;
+
+import java.io.Serializable;
+
+/**
+ * Marker for events which provides information of the event origin.
+ *
+ * @since
+ */
+public interface HasUserOriginated extends Serializable {
+ /**
+ * Returns whether this event was triggered by user interaction, on the
+ * client side, or programmatically, on the server side.
+ *
+ * @return {@code true} if this event originates from the client,
+ * {@code false} otherwise.
+ */
+ public boolean isUserOriginated();
+
+}
diff --git a/server/src/main/java/com/vaadin/data/HasValue.java b/server/src/main/java/com/vaadin/data/HasValue.java
index de2f86550f..b2ce098f6f 100644
--- a/server/src/main/java/com/vaadin/data/HasValue.java
+++ b/server/src/main/java/com/vaadin/data/HasValue.java
@@ -47,7 +47,8 @@ public interface HasValue<V> extends Serializable {
* @param <V>
* the value type
*/
- public class ValueChangeEvent<V> extends EventObject {
+ public class ValueChangeEvent<V> extends EventObject
+ implements HasUserOriginated {
private final boolean userOriginated;
private final Component component;
@@ -101,7 +102,7 @@ public interface HasValue<V> extends Serializable {
/**
* Returns the value of the source before this value change event
* occurred.
- *
+ *
* @return the value previously held by the source of this event
*/
public V getOldValue() {
@@ -117,13 +118,7 @@ public interface HasValue<V> extends Serializable {
return value;
}
- /**
- * Returns whether this event was triggered by user interaction, on the
- * client side, or programmatically, on the server side.
- *
- * @return {@code true} if this event originates from the client,
- * {@code false} otherwise.
- */
+ @Override
public boolean isUserOriginated() {
return userOriginated;
}
@@ -224,7 +219,7 @@ public interface HasValue<V> extends Serializable {
* Returns the current value of this object, wrapped in an {@code Optional}.
* <p>
* The {@code Optional} will be empty if the value is {@code null} or
- * {@code isEmpty()} returns {@code true}.
+ * {@code isEmpty()} returns {@code true}.
*
* @return the current value, wrapped in an {@code Optional}
*/
diff --git a/server/src/main/java/com/vaadin/ui/TabSheet.java b/server/src/main/java/com/vaadin/ui/TabSheet.java
index ec018e5fbf..550c5fc8ca 100644
--- a/server/src/main/java/com/vaadin/ui/TabSheet.java
+++ b/server/src/main/java/com/vaadin/ui/TabSheet.java
@@ -28,6 +28,7 @@ import java.util.Map;
import org.jsoup.nodes.Attributes;
import org.jsoup.nodes.Element;
+import com.vaadin.data.HasUserOriginated;
import com.vaadin.event.FieldEvents.BlurEvent;
import com.vaadin.event.FieldEvents.BlurListener;
import com.vaadin.event.FieldEvents.BlurNotifier;
@@ -87,7 +88,7 @@ public class TabSheet extends AbstractComponentContainer
@Override
public void setSelected(String key) {
- setSelectedTab(keyMapper.get(key));
+ setSelectedTab(keyMapper.get(key), true);
}
@Override
@@ -120,7 +121,7 @@ public class TabSheet extends AbstractComponentContainer
* Mapper between server-side component instances (tab contents) and keys
* given to the client that identify tabs.
*/
- private final KeyMapper<Component> keyMapper = new KeyMapper<>();
+ protected final KeyMapper<Component> keyMapper = new KeyMapper<>();
/**
* Handler to be called when a tab is closed.
@@ -227,7 +228,7 @@ public class TabSheet extends AbstractComponentContainer
// select the first enabled and visible tab, if any
updateSelection();
- fireSelectedTabChange();
+ fireSelectedTabChange(false);
}
}
}
@@ -389,7 +390,7 @@ public class TabSheet extends AbstractComponentContainer
if (selected == null) {
setSelected(tabComponent);
- fireSelectedTabChange();
+ fireSelectedTabChange(false);
}
super.addComponent(tabComponent);
@@ -525,17 +526,17 @@ public class TabSheet extends AbstractComponentContainer
}
/**
- * Returns the {@link Tab} (metadata) for a component. The {@link Tab}
+ * Returns the {@link Tab} (metadata) with the given index. The {@link Tab}
* object can be used for setting caption,icon, etc for the tab.
*
- * @param position
- * the position of the tab
- * @return The tab in the given position, or null if the position is out of
+ * @param index
+ * the index of the tab
+ * @return The tab with the given index, or null if the index is out of
* bounds.
*/
- public Tab getTab(int position) {
- if (position >= 0 && position < getComponentCount()) {
- return getTab(components.get(position));
+ public Tab getTab(int index) {
+ if (index >= 0 && index < getComponentCount()) {
+ return getTab(components.get(index));
} else {
return null;
}
@@ -545,13 +546,29 @@ public class TabSheet extends AbstractComponentContainer
* Sets the selected tab. The tab is identified by the tab content
* component. Does nothing if the tabsheet doesn't contain the component.
*
- * @param c
+ * @param component
+ * the component of the tab to select
*/
- public void setSelectedTab(Component c) {
- if (c != null && components.contains(c) && !c.equals(selected)) {
- setSelected(c);
+ public void setSelectedTab(Component component) {
+ setSelectedTab(component, false);
+ }
+
+ /**
+ * Sets the selected tab. The tab is identified by the tab content
+ * component. Does nothing if the tabsheet doesn't contain the component.
+ *
+ * @param component
+ * the component of the tab to select
+ * @param userOriginated
+ * <code>true</code> if the event originates from the client
+ * side, <code>false</code> otherwise
+ */
+ public void setSelectedTab(Component component, boolean userOriginated) {
+ if (component != null && components.contains(component)
+ && !component.equals(selected)) {
+ setSelected(component);
updateSelection();
- fireSelectedTabChange();
+ fireSelectedTabChange(userOriginated);
markAsDirty();
getRpcProxy(TabsheetClientRpc.class).revertToSharedStateSelection();
}
@@ -593,21 +610,23 @@ public class TabSheet extends AbstractComponentContainer
* the given tab.
*
* @param tab
+ * the tab to select
*/
public void setSelectedTab(Tab tab) {
if (tab != null) {
- setSelectedTab(tab.getComponent());
+ setSelectedTab(tab.getComponent(), false);
}
}
/**
- * Sets the selected tab, identified by its position. Does nothing if the
+ * Sets the selected tab, identified by its index. Does nothing if the
* position is out of bounds.
*
- * @param position
+ * @param index
+ * the index of the tab to select
*/
- public void setSelectedTab(int position) {
- setSelectedTab(getTab(position));
+ public void setSelectedTab(int index) {
+ setSelectedTab(getTab(index));
}
/**
@@ -742,7 +761,7 @@ public class TabSheet extends AbstractComponentContainer
// is changed.
// Other cases are handled implicitly by removeComponent() and
// addComponent()addTab()
- fireSelectedTabChange();
+ fireSelectedTabChange(false);
}
// Tab associations are not changed, but metadata is swapped between
@@ -779,26 +798,39 @@ public class TabSheet extends AbstractComponentContainer
* @author Vaadin Ltd.
* @since 3.0
*/
- public static class SelectedTabChangeEvent extends Component.Event {
+ public static class SelectedTabChangeEvent extends Component.Event
+ implements HasUserOriginated {
+
+ private final boolean userOriginated;
/**
- * New instance of selected tab change event
+ * Creates a new instance of the event.
*
* @param source
- * the Source of the event.
+ * the source of the event
+ * @param userOriginated
+ * <code>true</code> if the event originates from the client
+ * side, <code>false</code> otherwise
*/
- public SelectedTabChangeEvent(Component source) {
+ public SelectedTabChangeEvent(Component source,
+ boolean userOriginated) {
super(source);
+ this.userOriginated = userOriginated;
}
/**
- * TabSheet where the event occurred.
+ * The TabSheet where the event occurred.
*
- * @return the Source of the event.
+ * @return the TabSheet where the event occurred
*/
public TabSheet getTabSheet() {
return (TabSheet) getSource();
}
+
+ @Override
+ public boolean isUserOriginated() {
+ return userOriginated;
+ }
}
/**
@@ -857,10 +889,27 @@ public class TabSheet extends AbstractComponentContainer
}
/**
- * Sends an event that the currently selected tab has changed.
+ * Sends an event originating from the server, telling that the currently
+ * selected tab has changed.
+ *
+ * @deprecated use {@link #fireSelectedTabChange(boolean)} to indicate the
+ * origin of the event
*/
+ @Deprecated
protected void fireSelectedTabChange() {
- fireEvent(new SelectedTabChangeEvent(this));
+ fireSelectedTabChange(false);
+ }
+
+ /**
+ * Sends an event that the currently selected tab has changed.
+ *
+ * @param userOriginated
+ * <code>true</code> if the event originates from the client
+ * side, <code>false</code> otherwise
+ * @since
+ */
+ protected void fireSelectedTabChange(boolean userOriginated) {
+ fireEvent(new SelectedTabChangeEvent(this, userOriginated));
}
/**
@@ -1200,7 +1249,7 @@ public class TabSheet extends AbstractComponentContainer
tabState.enabled = enabled;
if (updateSelection()) {
- fireSelectedTabChange();
+ fireSelectedTabChange(false);
}
markAsDirty();
}
@@ -1215,7 +1264,7 @@ public class TabSheet extends AbstractComponentContainer
tabState.visible = visible;
if (updateSelection()) {
- fireSelectedTabChange();
+ fireSelectedTabChange(false);
}
markAsDirty();
}
@@ -1519,7 +1568,7 @@ public class TabSheet extends AbstractComponentContainer
boolean selected = DesignAttributeHandler.readAttribute("selected",
attr, Boolean.class);
if (selected) {
- this.setSelectedTab(tab.getComponent());
+ this.setSelectedTab(tab.getComponent(), false);
}
}
}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/tabsheet/TabSheetTest.java b/server/src/test/java/com/vaadin/tests/server/component/tabsheet/TabSheetTest.java
index b48a3477ab..91cfe7712a 100644
--- a/server/src/test/java/com/vaadin/tests/server/component/tabsheet/TabSheetTest.java
+++ b/server/src/test/java/com/vaadin/tests/server/component/tabsheet/TabSheetTest.java
@@ -6,11 +6,17 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import java.util.Iterator;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
import org.junit.Assert;
import org.junit.Test;
+import com.vaadin.shared.ui.tabsheet.TabsheetServerRpc;
+import com.vaadin.shared.ui.tabsheet.TabsheetState;
+import com.vaadin.ui.Button;
import com.vaadin.ui.Component;
+import com.vaadin.ui.ComponentTest;
import com.vaadin.ui.Label;
import com.vaadin.ui.TabSheet;
import com.vaadin.ui.TabSheet.SelectedTabChangeEvent;
@@ -284,4 +290,50 @@ public class TabSheetTest {
listener.assertActualComponentIs(lbl3);
assertEquals(lbl3, tabSheet.getSelectedTab());
}
+
+ public static class TestTabsheet extends TabSheet {
+ public TestTabsheet(Component... components) {
+ super(components);
+ }
+
+ public String getKey(Component c) {
+ return keyMapper.key(c);
+ }
+
+ @Override
+ public TabsheetState getState() {
+ return super.getState();
+ }
+ }
+
+ @Test
+ public void userOriginatedForSelectionEvent() {
+ AtomicBoolean userOriginated = new AtomicBoolean(false);
+ AtomicReference<Component> selected = new AtomicReference<>();
+
+ Button b1 = new Button("b1");
+ Button b2 = new Button("b2");
+ Button b3 = new Button("b3");
+ Button b4 = new Button("b4");
+ TestTabsheet tabsheet = new TestTabsheet(b1, b2, b3, b4);
+ tabsheet.addSelectedTabChangeListener(e -> {
+ userOriginated.set(e.isUserOriginated());
+ selected.set(e.getTabSheet().getSelectedTab());
+ });
+
+ tabsheet.setSelectedTab(b2);
+ Assert.assertFalse(userOriginated.get());
+ Assert.assertEquals(b2, selected.get());
+
+ TabsheetServerRpc rpc = ComponentTest.getRpcProxy(tabsheet,
+ TabsheetServerRpc.class);
+ rpc.setSelected(tabsheet.getKey(b1));
+ Assert.assertTrue(userOriginated.get());
+ Assert.assertEquals(b1, selected.get());
+
+ tabsheet.setSelectedTab(tabsheet.getTab(b4));
+ Assert.assertFalse(userOriginated.get());
+ Assert.assertEquals(b4, selected.get());
+
+ }
}