You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CreatingAComponentExtension.asciidoc 3.2KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. ---
  2. title: Creating A Component Extension
  3. order: 72
  4. layout: page
  5. ---
  6. [[creating-a-component-extension]]
  7. = Creating a component extension
  8. In this tutorial we create a simple extension that can be attached to a
  9. `PasswordField`, displaying a floating notification if the user's Caps
  10. Lock seems to be enabled. We assume the reader is already familiar with
  11. the <<CreatingAUIExtension#, Creating a UI extension>>
  12. tutorial.
  13. This extension has almost no server-side functionality; the whole Extension
  14. class is as follows:
  15. [source,java]
  16. ....
  17. public class CapsLockWarning extends AbstractExtension {
  18. protected CapsLockWarning(PasswordField field) {
  19. // Non-public constructor to discourage direct instantiation
  20. extend(field);
  21. }
  22. public static CapsLockWarning warnFor(PasswordField field) {
  23. return new CapsLockWarning(field);
  24. }
  25. }
  26. ....
  27. When there's nothing to configure for the extension, users just want to
  28. enable it for some component and be done with it. By defining a static
  29. factory method, the user only needs to do something like
  30. `CapsLockWarning.warnFor(myPasswordField);` to make `myPasswordField`
  31. get the new functionality.
  32. The client side is not overly complicated, either. We override the
  33. `extend` method, called by the framework when the client-side extension
  34. connector is attached to its target the client-side counterpart of the
  35. connector to which the server-side extension instance is attached in
  36. this case, `PasswordFieldConnector`.
  37. We add a key press handler to the password widget, checking if the input
  38. looks like Caps Lock might be enabled. The Caps Lock state cannot be
  39. directly queried in GWT/JavaScript, so we use a trick: check if either
  40. * the shift key was not held but the entered character was uppercase, or
  41. * the shift key _was_ held but the entered character was lowercase.
  42. If this is the case, we show a warning in the form of a floating widget
  43. (`VOverlay`). This demonstrates how an extension may make use of UI
  44. elements even though it is not a part of the layout hierarchy. A
  45. frequent use case for extensions is showing different types of floating
  46. overlay elements that are temporary in character.
  47. [source,java]
  48. ....
  49. @Connect(CapsLockWarning.class)
  50. public class CapsLockWarningConnector extends AbstractExtensionConnector {
  51. @Override
  52. protected void extend(ServerConnector target) {
  53. final Widget passwordWidget = ((ComponentConnector) target).getWidget();
  54. final VOverlay warning = new VOverlay();
  55. warning.setOwner(passwordWidget);
  56. warning.add(new HTML("Caps Lock is enabled!"));
  57. passwordWidget.addDomHandler(new KeyPressHandler() {
  58. @Override
  59. public void onKeyPress(KeyPressEvent event) {
  60. if (isEnabled() && isCapsLockOn(event)) {
  61. warning.showRelativeTo(passwordWidget);
  62. } else {
  63. warning.hide();
  64. }
  65. }
  66. }, KeyPressEvent.getType());
  67. }
  68. private boolean isCapsLockOn(KeyPressEvent e) {
  69. return e.isShiftKeyDown() ^ Character.isUpperCase(e.getCharCode());
  70. }
  71. }
  72. ....
  73. To use the Caps Lock warning, compile your widgetset and extend a
  74. PasswordField with something like this
  75. [source,java]
  76. ....
  77. PasswordField field = new PasswordField("Enter your password");
  78. CapsLockWarning.warnFor(field);
  79. addComponent(field);
  80. ....