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;
@Override
public void setSelected(String key) {
- setSelectedTab(keyMapper.get(key));
+ setSelectedTab(keyMapper.get(key), true);
}
@Override
* 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.
// select the first enabled and visible tab, if any
updateSelection();
- fireSelectedTabChange();
+ fireSelectedTabChange(false);
}
}
}
if (selected == null) {
setSelected(tabComponent);
- fireSelectedTabChange();
+ fireSelectedTabChange(false);
}
super.addComponent(tabComponent);
}
/**
- * 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;
}
* 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();
}
* 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));
}
/**
// 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
* @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;
+ }
}
/**
}
/**
- * 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));
}
/**
tabState.enabled = enabled;
if (updateSelection()) {
- fireSelectedTabChange();
+ fireSelectedTabChange(false);
}
markAsDirty();
}
tabState.visible = visible;
if (updateSelection()) {
- fireSelectedTabChange();
+ fireSelectedTabChange(false);
}
markAsDirty();
}
boolean selected = DesignAttributeHandler.readAttribute("selected",
attr, Boolean.class);
if (selected) {
- this.setSelectedTab(tab.getComponent());
+ this.setSelectedTab(tab.getComponent(), false);
}
}
}
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;
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());
+
+ }
}