}
}
+ /**
+ * Sets the tab index.
+ *
+ * @param tabIndex
+ * the tab index to set
+ */
+ public void setTabIndex(int tabIndex) {
+ getListBox().setTabIndex(tabIndex);
+ }
+
/**
* Gets the underlying ListBox widget that this widget wraps.
*
getWidget().setReadOnly(isReadOnly());
}
+ @OnStateChange("tabIndex")
+ void updateTabIndex() {
+ getWidget().setTabIndex(getState().tabIndex);
+ }
}
}
@OnStateChange("readOnly")
- @SuppressWarnings("deprecation")
void updateWidgetReadOnly() {
getWidget().getListBox().setEnabled(isEnabled() && !isReadOnly());
}
getWidget().setSelectedItem(getState().selectedItemKey);
}
+ @OnStateChange("tabIndex")
+ void updateTabIndex() {
+ getWidget().setTabIndex(getState().tabIndex);
+ }
+
@Override
public NativeSelectState getState() {
return (NativeSelectState) super.getState();
@Override
public void onStateChanged(StateChangeEvent stateChangeEvent) {
super.onStateChanged(stateChangeEvent);
+ getWidget().setTabIndex(getState().tabIndex);
getWidget().client = getConnection();
}
getWidget().setReadOnly(isReadOnly());
}
+ @OnStateChange("tabIndex")
+ void updateTabIndex() {
+ getWidget().setTabIndex(getState().tabIndex);
+ }
+
@Override
public void layoutVertically() {
if (isUndefinedHeight()) {
import com.vaadin.server.data.Query;
import com.vaadin.shared.extension.abstractlisting.AbstractListingExtensionState;
import com.vaadin.shared.ui.abstractlisting.AbstractListingState;
+import com.vaadin.ui.Component.Focusable;
import com.vaadin.ui.declarative.DesignAttributeHandler;
import com.vaadin.ui.declarative.DesignContext;
import com.vaadin.ui.declarative.DesignException;
*
* @see Listing
*/
-public abstract class AbstractListing<T> extends AbstractComponent {
+public abstract class AbstractListing<T> extends AbstractComponent
+ implements Focusable {
/**
* The item icon caption provider.
*/
protected AbstractListingState getState(boolean markAsDirty) {
return (AbstractListingState) super.getState(markAsDirty);
}
+
+ @Override
+ public void focus() {
+ super.focus();
+ }
+
+ @Override
+ public int getTabIndex() {
+ return getState(false).tabIndex;
+ }
+
+ @Override
+ public void setTabIndex(int tabIndex) {
+ getState().tabIndex = tabIndex;
+ }
}
* <p>
* Notice that this interface does not provide an accessor that would
* allow finding out the currently focused component. Focus information
- * can be acquired for some (but not all) {@code LegacyField} components
- * through the {@link com.vaadin.event.FieldEvents.FocusListener} and
+ * can be acquired for some (but not all) components through the
+ * {@link com.vaadin.event.FieldEvents.FocusListener} and
* {@link com.vaadin.event.FieldEvents.BlurListener} interfaces.
* </p>
*
enableItem.setChecked(true);
createSelectionMenu(stateMenu);
+
+ stateMenu.addItem("Set focus", item -> grid.focus());
+ MenuItem tabIndexMenu = stateMenu.addItem("Tab index", null);
+ addGridMethodMenu(tabIndexMenu, "0", 0, grid::setTabIndex);
+ addGridMethodMenu(tabIndexMenu, "-1", -1, grid::setTabIndex);
+ addGridMethodMenu(tabIndexMenu, "10", 10, grid::setTabIndex);
}
private void createRowStyleMenu(MenuItem rowStyleMenu) {
--- /dev/null
+package com.vaadin.tests.focusable;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public abstract class AbstractFocusableComponentTest extends MultiBrowserTest {
+
+ @Before
+ public void setUp() {
+ openTestURL();
+ }
+
+ @Test
+ public void testProgrammaticFocus() {
+ selectMenuPath("Component", "State", "Set focus");
+ assertTrue("Component should be focused", isFocused());
+ }
+
+ @Test
+ public void testTabIndex() {
+ assertEquals("0", getTabIndex());
+
+ selectMenuPath("Component", "State", "Tab index", "-1");
+ assertEquals("-1", getTabIndex());
+
+ selectMenuPath("Component", "State", "Tab index", "10");
+ assertEquals("10", getTabIndex());
+ }
+
+ protected String getTabIndex() {
+ return getFocusElement().getAttribute("tabindex");
+ }
+
+ protected boolean isFocused() {
+ return getFocusElement().equals(getDriver().switchTo().activeElement());
+ }
+
+ protected abstract WebElement getFocusElement();
+}
--- /dev/null
+package com.vaadin.tests.focusable;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.tests.components.checkbox.CheckBoxGroupTestUI;
+
+public class CheckBoxGroupFocusableTest extends AbstractFocusableComponentTest {
+
+ @Override
+ protected Class<?> getUIClass() {
+ return CheckBoxGroupTestUI.class;
+ }
+
+ @Override
+ protected WebElement getFocusElement() {
+ return findElement(By.xpath("//input[@type='checkbox']"));
+ }
+}
--- /dev/null
+package com.vaadin.tests.focusable;
+
+import com.vaadin.testbench.customelements.GridElement;
+import com.vaadin.testbench.elements.GridElement.GridCellElement;
+import com.vaadin.tests.components.grid.basics.GridBasics;
+
+public class GridFocusableTest extends AbstractFocusableComponentTest {
+
+ @Override
+ protected Class<?> getUIClass() {
+ return GridBasics.class;
+ }
+
+ @Override
+ protected String getTabIndex() {
+ return $(GridElement.class).first().getAttribute("tabindex");
+ }
+
+ @Override
+ protected boolean isFocused() {
+ return getFocusElement().isFocused();
+ }
+
+ @Override
+ protected GridCellElement getFocusElement() {
+ return $(GridElement.class).first().getCell(0, 0);
+ }
+}
--- /dev/null
+package com.vaadin.tests.focusable;
+
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.By;
+import com.vaadin.tests.components.listselect.ListSelectTestUI;
+
+public class ListSelectFocusableTest extends AbstractFocusableComponentTest {
+
+ @Override
+ protected Class<?> getUIClass() {
+ return ListSelectTestUI.class;
+ }
+
+ @Override
+ protected WebElement getFocusElement() {
+ return findElement(By.className("v-select-select"));
+ }
+}
--- /dev/null
+package com.vaadin.tests.focusable;
+
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.By;
+import com.vaadin.tests.components.nativeselect.NativeSelects;
+
+public class NativeSelectFocusableTest extends AbstractFocusableComponentTest {
+
+ @Override
+ protected Class<?> getUIClass() {
+ return NativeSelects.class;
+ }
+
+ @Override
+ protected WebElement getFocusElement() {
+ return findElement(By.className("v-select-select"));
+ }
+}
--- /dev/null
+package com.vaadin.tests.focusable;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.tests.components.radiobutton.RadioButtonGroupTestUI;
+
+public class RadioButtonGroupFocusableTest extends AbstractFocusableComponentTest {
+
+ @Override
+ protected Class<?> getUIClass() {
+ return RadioButtonGroupTestUI.class;
+ }
+
+ @Override
+ protected WebElement getFocusElement() {
+ return findElement(By.xpath("//input[@type='radio']"));
+ }
+}
--- /dev/null
+package com.vaadin.tests.focusable;
+
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.By;
+import com.vaadin.tests.components.twincolselect.TwinColSelectTestUI;
+
+public class TwinColSelectFocusableTest
+ extends AbstractFocusableComponentTest {
+
+ @Override
+ protected Class<?> getUIClass() {
+ return TwinColSelectTestUI.class;
+ }
+
+ @Override
+ protected WebElement getFocusElement() {
+ return findElement(By.className("v-select-twincol-options"));
+ }
+}