* Add missing FocusShortcutListener Was removed from 8.0 and not readded. Fixes #8297 * Update Release note for this changetags/8.7.0.alpha1
enhancements. Below is a list of the most notable changes:</p> | enhancements. Below is a list of the most notable changes:</p> | ||||
<ul> | <ul> | ||||
<li>Improvements in <tt>MenuBar</tt> client-side customization.</tt></li> | |||||
<li>Support for improved version of <tt>ContextMenu</tt> add-on (version 3.0.0.beta1).</li> | |||||
<li>Rewrite <tt>OSGi</tt> bundles activation mechanism to follow <tt>OSGi</tt> best practices</li> | |||||
<li>Change the return type of <tt>Grid.asMultiSelect</tt> and <tt>Grid.asSingleSelect</tt> that has API to access the features of corresponding selection model</li> | |||||
<li>Add support for <tt>FocusShortcutListener</tt></li> | |||||
<li>Performance improvements for the Vaadin 7 compatibility Grid, picked from the Vaadin 7 branch.</li> | <li>Performance improvements for the Vaadin 7 compatibility Grid, picked from the Vaadin 7 branch.</li> | ||||
<li>Fixes to Vaadin 7 compatibility Grid issues #10343 and #10998, picked from the Vaadin 7 branch.</li> | <li>Fixes to Vaadin 7 compatibility Grid issues #10343 and #10998, picked from the Vaadin 7 branch.</li> | ||||
</ul> | </ul> | ||||
</p> | </p> | ||||
<p> | <p> | ||||
For enhancements introduced in Vaadin Framework 8.5, see the <a | |||||
href="http://vaadin.com/download/release/8.5/8.5.0/release-notes.html">Release | |||||
Notes for Vaadin Framework 8.5.0</a>. | |||||
For enhancements introduced in Vaadin Framework 8.6, see the <a | |||||
href="http://vaadin.com/download/release/8.6/8.6.0/release-notes.html">Release | |||||
Notes for Vaadin Framework 8.6.0</a>. | |||||
For migrating from previous framework versions, see <a href="#incompatible">the list of incompatible changes</a> and <a href="#migrating">how to migrate | For migrating from previous framework versions, see <a href="#incompatible">the list of incompatible changes</a> and <a href="#migrating">how to migrate | ||||
to Vaadin Framework 8</a>. | to Vaadin Framework 8</a>. | ||||
</p> | </p> | ||||
<li><tt>VaadinIcons.SEARCH_MINUS</tt> and <tt>VaadinIcons.SEARCH_PLUS</tt> codes were changed due typo fix</li> | <li><tt>VaadinIcons.SEARCH_MINUS</tt> and <tt>VaadinIcons.SEARCH_PLUS</tt> codes were changed due typo fix</li> | ||||
</ul> | </ul> | ||||
<h2>For incompatible or behavior-altering changes in 8.5, please see <a href="https://vaadin.com/download/release/8.5/8.5.0/release-notes.html#incompatible">8.5 release notes</a></h2> | |||||
<h2>For incompatible or behavior-altering changes in 8.6, please see <a href="https://vaadin.com/download/release/8.6/8.6.0/release-notes.html#incompatible">8.6 release notes</a></h2> | |||||
<h3 id="knownissues">Known Issues and Limitations</h3> | <h3 id="knownissues">Known Issues and Limitations</h3> | ||||
<ul> | <ul> |
* A ready-made {@link ShortcutListener} that focuses the given | * A ready-made {@link ShortcutListener} that focuses the given | ||||
* {@link Focusable} (usually a {@link Field}) when the keyboard shortcut is | * {@link Focusable} (usually a {@link Field}) when the keyboard shortcut is | ||||
* invoked. | * invoked. | ||||
* | |||||
* | |||||
* @deprecated Replaced in 8.0 with {@link com.vaadin.event.FocusShortcut} | |||||
*/ | */ | ||||
@Deprecated | @Deprecated | ||||
public static class FocusShortcut extends ShortcutListener { | public static class FocusShortcut extends ShortcutListener { |
[[advanced.shortcuts.focus]] | [[advanced.shortcuts.focus]] | ||||
== Field Focus Shortcuts | == Field Focus Shortcuts | ||||
You can define a shortcut key that sets the focus to a field component (any | |||||
component that inherits [classname]#AbstractField#) by adding a | |||||
[classname]#FocusShortcut# as a shortcut listener to the field. | |||||
You can define a shortcut key that sets the focus to any focusable component (implements [interface]#Focusable#), usually field components, by adding a | |||||
[interface]#FocusShortcut# as a shortcut listener to the component. | |||||
The constructor of the [classname]#FocusShortcut# takes the field component as | |||||
The constructor of the [classname]#FocusShortcut# takes the focusable component as | |||||
its first parameter, followed by the key code, and an optional list of modifier | its first parameter, followed by the key code, and an optional list of modifier | ||||
keys, as listed in <<advanced.shortcuts.keycodes>>. | keys, as listed in <<advanced.shortcuts.keycodes>>. | ||||
// A field with Alt+N bound to it | // A field with Alt+N bound to it | ||||
TextField name = new TextField("Name (Alt+N)"); | TextField name = new TextField("Name (Alt+N)"); | ||||
name.addShortcutListener( | name.addShortcutListener( | ||||
new AbstractField.FocusShortcut(name, KeyCode.N, | |||||
new FocusShortcut(name, KeyCode.N, | |||||
ModifierKey.ALT)); | ModifierKey.ALT)); | ||||
layout.addComponent(name); | layout.addComponent(name); | ||||
---- | ---- | ||||
// A field with Alt+A bound to it, using shorthand notation | // A field with Alt+A bound to it, using shorthand notation | ||||
TextField address = new TextField("Address (Alt+A)"); | TextField address = new TextField("Address (Alt+A)"); | ||||
address.addShortcutListener( | address.addShortcutListener( | ||||
new AbstractField.FocusShortcut(address, "&Address")); | |||||
new FocusShortcut(address, "&Address")); | |||||
---- | ---- | ||||
This is especially useful for internationalization, so that you can determine | This is especially useful for internationalization, so that you can determine | ||||
---- | ---- | ||||
TextField name = new TextField("Name (Ctrl+Shift+N)"); | TextField name = new TextField("Name (Ctrl+Shift+N)"); | ||||
name.addShortcutListener( | name.addShortcutListener( | ||||
new AbstractField.FocusShortcut(name, KeyCode.N, | |||||
new FocusShortcut(name, KeyCode.N, | |||||
ModifierKey.CTRL, | ModifierKey.CTRL, | ||||
ModifierKey.SHIFT)); | ModifierKey.SHIFT)); | ||||
---- | ---- |
/* | |||||
* Copyright 2000-2018 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.event; | |||||
import com.vaadin.ui.Component.Focusable; | |||||
/** | |||||
* A ready-made {@link ShortcutListener} that focuses the given | |||||
* {@link Focusable} (usually a {@link Field}) when the keyboard shortcut is | |||||
* invoked. | |||||
* | |||||
* @author Vaadin Ltd | |||||
* @since | |||||
*/ | |||||
public class FocusShortcut extends ShortcutListener { | |||||
protected Focusable focusable; | |||||
/** | |||||
* Creates a keyboard shortcut for focusing the given {@link Focusable} | |||||
* using the shorthand notation defined in {@link ShortcutAction}. | |||||
* | |||||
* @param focusable | |||||
* to focused when the shortcut is invoked | |||||
* @param shorthandCaption | |||||
* caption with keycode and modifiers indicated | |||||
*/ | |||||
public FocusShortcut(Focusable focusable, String shorthandCaption) { | |||||
super(shorthandCaption); | |||||
this.focusable = focusable; | |||||
} | |||||
/** | |||||
* Creates a keyboard shortcut for focusing the given {@link Focusable}. | |||||
* | |||||
* @param focusable | |||||
* to focused when the shortcut is invoked | |||||
* @param keyCode | |||||
* keycode that invokes the shortcut | |||||
* @param modifiers | |||||
* modifiers required to invoke the shortcut | |||||
*/ | |||||
public FocusShortcut(Focusable focusable, int keyCode, int... modifiers) { | |||||
super(null, keyCode, modifiers); | |||||
this.focusable = focusable; | |||||
} | |||||
/** | |||||
* Creates a keyboard shortcut for focusing the given {@link Focusable}. | |||||
* | |||||
* @param focusable | |||||
* to focused when the shortcut is invoked | |||||
* @param keyCode | |||||
* keycode that invokes the shortcut | |||||
*/ | |||||
public FocusShortcut(Focusable focusable, int keyCode) { | |||||
this(focusable, keyCode, null); | |||||
} | |||||
@Override | |||||
public void handleAction(Object sender, Object target) { | |||||
focusable.focus(); | |||||
} | |||||
} |
package com.vaadin.tests.components; | |||||
import com.vaadin.event.FocusShortcut; | |||||
import com.vaadin.event.ShortcutAction.KeyCode; | |||||
import com.vaadin.event.ShortcutAction.ModifierKey; | |||||
import com.vaadin.server.VaadinRequest; | |||||
import com.vaadin.ui.TextField; | |||||
public class FocusShortcuts extends AbstractTestUIWithLog { | |||||
@Override | |||||
protected void setup(VaadinRequest request) { | |||||
TextField name = new TextField("Name (Alt+N)"); | |||||
name.addShortcutListener( | |||||
new FocusShortcut(name, KeyCode.N, ModifierKey.ALT)); | |||||
name.addFocusListener(event -> log("Alt+N")); | |||||
TextField address = new TextField("Address (Alt+A)"); | |||||
address.addShortcutListener(new FocusShortcut(address, "&Address")); | |||||
address.addFocusListener(event -> log("Alt+A")); | |||||
TextField name2 = new TextField("Name (Ctrl+Shift+D)"); | |||||
name2.addShortcutListener(new FocusShortcut(name2, KeyCode.D, | |||||
ModifierKey.CTRL, ModifierKey.SHIFT)); | |||||
name2.addFocusListener(event -> log("Ctrl+Shift+D")); | |||||
addComponents(name, address, name2); | |||||
} | |||||
} |
package com.vaadin.tests.components; | |||||
import org.junit.Assert; | |||||
import org.junit.Test; | |||||
import org.openqa.selenium.By; | |||||
import org.openqa.selenium.Keys; | |||||
import org.openqa.selenium.WebElement; | |||||
import org.openqa.selenium.interactions.Actions; | |||||
import com.vaadin.testbench.elements.TextFieldElement; | |||||
import com.vaadin.tests.tb3.SingleBrowserTest; | |||||
public class FocusShortcutsTest extends SingleBrowserTest { | |||||
@Test | |||||
public void triggerShortCuts() { | |||||
openTestURL(); | |||||
WebElement body = findElement(By.xpath("//body")); | |||||
Actions actions = new Actions(getDriver()); | |||||
actions.keyDown(body, Keys.LEFT_ALT).sendKeys("a").keyUp(Keys.LEFT_ALT) | |||||
.build().perform(); | |||||
Assert.assertEquals("1. Alt+A", getLogRow(0)); | |||||
body.click(); | |||||
actions = new Actions(getDriver()); | |||||
actions.keyDown(body, Keys.LEFT_ALT).sendKeys("n").keyUp(Keys.LEFT_ALT) | |||||
.build().perform(); | |||||
Assert.assertEquals("2. Alt+N", getLogRow(0)); | |||||
body.click(); | |||||
actions = new Actions(getDriver()); | |||||
actions.keyDown(body, Keys.LEFT_CONTROL).keyDown(body, Keys.LEFT_SHIFT) | |||||
.sendKeys("d").keyUp(Keys.LEFT_CONTROL).keyUp(Keys.LEFT_SHIFT).build().perform(); | |||||
Assert.assertEquals("3. Ctrl+Shift+D", getLogRow(0)); | |||||
} | |||||
} |