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.

Window.java 26KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858
  1. /*
  2. * Copyright 2011 Vaadin Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.vaadin.ui;
  17. import java.io.Serializable;
  18. import java.lang.reflect.Method;
  19. import java.util.Map;
  20. import com.vaadin.event.FieldEvents.BlurEvent;
  21. import com.vaadin.event.FieldEvents.BlurListener;
  22. import com.vaadin.event.FieldEvents.BlurNotifier;
  23. import com.vaadin.event.FieldEvents.FocusEvent;
  24. import com.vaadin.event.FieldEvents.FocusListener;
  25. import com.vaadin.event.FieldEvents.FocusNotifier;
  26. import com.vaadin.event.MouseEvents.ClickEvent;
  27. import com.vaadin.event.ShortcutAction;
  28. import com.vaadin.event.ShortcutAction.KeyCode;
  29. import com.vaadin.event.ShortcutAction.ModifierKey;
  30. import com.vaadin.event.ShortcutListener;
  31. import com.vaadin.server.PaintException;
  32. import com.vaadin.server.PaintTarget;
  33. import com.vaadin.shared.MouseEventDetails;
  34. import com.vaadin.shared.ui.window.WindowServerRpc;
  35. import com.vaadin.shared.ui.window.WindowState;
  36. /**
  37. * A component that represents a floating popup window that can be added to a
  38. * {@link UI}. A window is added to a {@code UI} using
  39. * {@link UI#addWindow(Window)}. </p>
  40. * <p>
  41. * The contents of a window is set using {@link #setContent(Component)} or by
  42. * using the {@link #Window(String, Component)} constructor.
  43. * </p>
  44. * <p>
  45. * A window can be positioned on the screen using absolute coordinates (pixels)
  46. * or set to be centered using {@link #center()}
  47. * </p>
  48. * <p>
  49. * The caption is displayed in the window header.
  50. * </p>
  51. * <p>
  52. * In Vaadin versions prior to 7.0.0, Window was also used as application level
  53. * windows. This function is now covered by the {@link UI} class.
  54. * </p>
  55. *
  56. * @author Vaadin Ltd.
  57. * @since 3.0
  58. */
  59. @SuppressWarnings("serial")
  60. public class Window extends Panel implements FocusNotifier, BlurNotifier,
  61. LegacyComponent {
  62. private WindowServerRpc rpc = new WindowServerRpc() {
  63. @Override
  64. public void click(MouseEventDetails mouseDetails) {
  65. fireEvent(new ClickEvent(Window.this, mouseDetails));
  66. }
  67. };
  68. /**
  69. * Creates a new, empty sub window
  70. */
  71. public Window() {
  72. this("", null);
  73. }
  74. /**
  75. * Creates a new, empty sub window with a given title.
  76. *
  77. * @param caption
  78. * the title of the window.
  79. */
  80. public Window(String caption) {
  81. this(caption, null);
  82. }
  83. /**
  84. * Creates a new, empty sub window with the given content and title.
  85. *
  86. * @param caption
  87. * the title of the window.
  88. * @param content
  89. * the contents of the window
  90. */
  91. public Window(String caption, Component content) {
  92. super(caption, content);
  93. registerRpc(rpc);
  94. setSizeUndefined();
  95. }
  96. /* ********************************************************************* */
  97. /*
  98. * (non-Javadoc)
  99. *
  100. * @see com.vaadin.ui.Panel#paintContent(com.vaadin.server.PaintTarget)
  101. */
  102. @Override
  103. public synchronized void paintContent(PaintTarget target)
  104. throws PaintException {
  105. if (bringToFront != null) {
  106. target.addAttribute("bringToFront", bringToFront.intValue());
  107. bringToFront = null;
  108. }
  109. // Contents of the window panel is painted
  110. super.paintContent(target);
  111. }
  112. /*
  113. * (non-Javadoc)
  114. *
  115. * @see com.vaadin.ui.Panel#changeVariables(java.lang.Object, java.util.Map)
  116. */
  117. @Override
  118. public void changeVariables(Object source, Map<String, Object> variables) {
  119. // TODO Are these for top level windows or sub windows?
  120. boolean sizeHasChanged = false;
  121. // size is handled in super class, but resize events only in windows ->
  122. // so detect if size change occurs before super.changeVariables()
  123. if (variables.containsKey("height")
  124. && (getHeightUnits() != Unit.PIXELS || (Integer) variables
  125. .get("height") != getHeight())) {
  126. sizeHasChanged = true;
  127. }
  128. if (variables.containsKey("width")
  129. && (getWidthUnits() != Unit.PIXELS || (Integer) variables
  130. .get("width") != getWidth())) {
  131. sizeHasChanged = true;
  132. }
  133. super.changeVariables(source, variables);
  134. // Positioning
  135. final Integer positionx = (Integer) variables.get("positionx");
  136. if (positionx != null) {
  137. final int x = positionx.intValue();
  138. // This is information from the client so it is already using the
  139. // position. No need to repaint.
  140. setPositionX(x < 0 ? -1 : x);
  141. }
  142. final Integer positiony = (Integer) variables.get("positiony");
  143. if (positiony != null) {
  144. final int y = positiony.intValue();
  145. // This is information from the client so it is already using the
  146. // position. No need to repaint.
  147. setPositionY(y < 0 ? -1 : y);
  148. }
  149. if (isClosable()) {
  150. // Closing
  151. final Boolean close = (Boolean) variables.get("close");
  152. if (close != null && close.booleanValue()) {
  153. close();
  154. }
  155. }
  156. // fire event if size has really changed
  157. if (sizeHasChanged) {
  158. fireResize();
  159. }
  160. if (variables.containsKey(FocusEvent.EVENT_ID)) {
  161. fireEvent(new FocusEvent(this));
  162. } else if (variables.containsKey(BlurEvent.EVENT_ID)) {
  163. fireEvent(new BlurEvent(this));
  164. }
  165. }
  166. /**
  167. * Method that handles window closing (from UI).
  168. *
  169. * <p>
  170. * By default, sub-windows are removed from their respective parent windows
  171. * and thus visually closed on browser-side. Browser-level windows also
  172. * closed on the client-side, but they are not implicitly removed from the
  173. * application.
  174. * </p>
  175. *
  176. * <p>
  177. * To explicitly close a sub-window, use {@link #removeWindow(Window)}. To
  178. * react to a window being closed (after it is closed), register a
  179. * {@link CloseListener}.
  180. * </p>
  181. */
  182. public void close() {
  183. UI uI = getUI();
  184. // Don't do anything if not attached to a UI
  185. if (uI != null) {
  186. // focus is restored to the parent window
  187. uI.focus();
  188. // subwindow is removed from the UI
  189. uI.removeWindow(this);
  190. }
  191. }
  192. /**
  193. * Gets the distance of Window left border in pixels from left border of the
  194. * containing (main window).
  195. *
  196. * @return the Distance of Window left border in pixels from left border of
  197. * the containing (main window). or -1 if unspecified.
  198. * @since 4.0.0
  199. */
  200. public int getPositionX() {
  201. return getState().positionX;
  202. }
  203. /**
  204. * Sets the distance of Window left border in pixels from left border of the
  205. * containing (main window).
  206. *
  207. * @param positionX
  208. * the Distance of Window left border in pixels from left border
  209. * of the containing (main window). or -1 if unspecified.
  210. * @since 4.0.0
  211. */
  212. public void setPositionX(int positionX) {
  213. getState().positionX = positionX;
  214. getState().centered = false;
  215. }
  216. /**
  217. * Gets the distance of Window top border in pixels from top border of the
  218. * containing (main window).
  219. *
  220. * @return Distance of Window top border in pixels from top border of the
  221. * containing (main window). or -1 if unspecified .
  222. *
  223. * @since 4.0.0
  224. */
  225. public int getPositionY() {
  226. return getState().positionY;
  227. }
  228. /**
  229. * Sets the distance of Window top border in pixels from top border of the
  230. * containing (main window).
  231. *
  232. * @param positionY
  233. * the Distance of Window top border in pixels from top border of
  234. * the containing (main window). or -1 if unspecified
  235. *
  236. * @since 4.0.0
  237. */
  238. public void setPositionY(int positionY) {
  239. getState().positionY = positionY;
  240. getState().centered = false;
  241. }
  242. private static final Method WINDOW_CLOSE_METHOD;
  243. static {
  244. try {
  245. WINDOW_CLOSE_METHOD = CloseListener.class.getDeclaredMethod(
  246. "windowClose", new Class[] { CloseEvent.class });
  247. } catch (final java.lang.NoSuchMethodException e) {
  248. // This should never happen
  249. throw new java.lang.RuntimeException(
  250. "Internal error, window close method not found");
  251. }
  252. }
  253. public static class CloseEvent extends Component.Event {
  254. /**
  255. *
  256. * @param source
  257. */
  258. public CloseEvent(Component source) {
  259. super(source);
  260. }
  261. /**
  262. * Gets the Window.
  263. *
  264. * @return the window.
  265. */
  266. public Window getWindow() {
  267. return (Window) getSource();
  268. }
  269. }
  270. /**
  271. * An interface used for listening to Window close events. Add the
  272. * CloseListener to a browser level window or a sub window and
  273. * {@link CloseListener#windowClose(CloseEvent)} will be called whenever the
  274. * user closes the window.
  275. *
  276. * <p>
  277. * Since Vaadin 6.5, removing a window using {@link #removeWindow(Window)}
  278. * fires the CloseListener.
  279. * </p>
  280. */
  281. public interface CloseListener extends Serializable {
  282. /**
  283. * Called when the user closes a window. Use
  284. * {@link CloseEvent#getWindow()} to get a reference to the
  285. * {@link Window} that was closed.
  286. *
  287. * @param e
  288. * Event containing
  289. */
  290. public void windowClose(CloseEvent e);
  291. }
  292. /**
  293. * Adds a CloseListener to the window.
  294. *
  295. * For a sub window the CloseListener is fired when the user closes it
  296. * (clicks on the close button).
  297. *
  298. * For a browser level window the CloseListener is fired when the browser
  299. * level window is closed. Note that closing a browser level window does not
  300. * mean it will be destroyed. Also note that Opera does not send events like
  301. * all other browsers and therefore the close listener might not be called
  302. * if Opera is used.
  303. *
  304. * <p>
  305. * Since Vaadin 6.5, removing windows using {@link #removeWindow(Window)}
  306. * does fire the CloseListener.
  307. * </p>
  308. *
  309. * @param listener
  310. * the CloseListener to add.
  311. */
  312. public void addCloseListener(CloseListener listener) {
  313. addListener(CloseEvent.class, listener, WINDOW_CLOSE_METHOD);
  314. }
  315. /**
  316. * @deprecated As of 7.0, replaced by
  317. * {@link #addCloseListener(CloseListener)}
  318. **/
  319. @Deprecated
  320. public void addListener(CloseListener listener) {
  321. addCloseListener(listener);
  322. }
  323. /**
  324. * Removes the CloseListener from the window.
  325. *
  326. * <p>
  327. * For more information on CloseListeners see {@link CloseListener}.
  328. * </p>
  329. *
  330. * @param listener
  331. * the CloseListener to remove.
  332. */
  333. public void removeCloseListener(CloseListener listener) {
  334. removeListener(CloseEvent.class, listener, WINDOW_CLOSE_METHOD);
  335. }
  336. /**
  337. * @deprecated As of 7.0, replaced by
  338. * {@link #removeCloseListener(CloseListener)}
  339. **/
  340. @Deprecated
  341. public void removeListener(CloseListener listener) {
  342. removeCloseListener(listener);
  343. }
  344. protected void fireClose() {
  345. fireEvent(new Window.CloseEvent(this));
  346. }
  347. /**
  348. * Method for the resize event.
  349. */
  350. private static final Method WINDOW_RESIZE_METHOD;
  351. static {
  352. try {
  353. WINDOW_RESIZE_METHOD = ResizeListener.class.getDeclaredMethod(
  354. "windowResized", new Class[] { ResizeEvent.class });
  355. } catch (final java.lang.NoSuchMethodException e) {
  356. // This should never happen
  357. throw new java.lang.RuntimeException(
  358. "Internal error, window resized method not found");
  359. }
  360. }
  361. /**
  362. * Resize events are fired whenever the client-side fires a resize-event
  363. * (e.g. the browser window is resized). The frequency may vary across
  364. * browsers.
  365. */
  366. public static class ResizeEvent extends Component.Event {
  367. /**
  368. *
  369. * @param source
  370. */
  371. public ResizeEvent(Component source) {
  372. super(source);
  373. }
  374. /**
  375. * Get the window form which this event originated
  376. *
  377. * @return the window
  378. */
  379. public Window getWindow() {
  380. return (Window) getSource();
  381. }
  382. }
  383. /**
  384. * Listener for window resize events.
  385. *
  386. * @see com.vaadin.ui.Window.ResizeEvent
  387. */
  388. public interface ResizeListener extends Serializable {
  389. public void windowResized(ResizeEvent e);
  390. }
  391. /**
  392. * Add a resize listener.
  393. *
  394. * @param listener
  395. */
  396. public void addResizeListener(ResizeListener listener) {
  397. addListener(ResizeEvent.class, listener, WINDOW_RESIZE_METHOD);
  398. }
  399. /**
  400. * @deprecated As of 7.0, replaced by
  401. * {@link #addResizeListener(ResizeListener)}
  402. **/
  403. @Deprecated
  404. public void addListener(ResizeListener listener) {
  405. addResizeListener(listener);
  406. }
  407. /**
  408. * Remove a resize listener.
  409. *
  410. * @param listener
  411. */
  412. public void removeResizeListener(ResizeListener listener) {
  413. removeListener(ResizeEvent.class, listener);
  414. }
  415. /**
  416. * @deprecated As of 7.0, replaced by
  417. * {@link #removeResizeListener(ResizeListener)}
  418. **/
  419. @Deprecated
  420. public void removeListener(ResizeListener listener) {
  421. removeResizeListener(listener);
  422. }
  423. /**
  424. * Fire the resize event.
  425. */
  426. protected void fireResize() {
  427. fireEvent(new ResizeEvent(this));
  428. }
  429. /**
  430. * Used to keep the right order of windows if multiple windows are brought
  431. * to front in a single changeset. If this is not used, the order is quite
  432. * random (depends on the order getting to dirty list. e.g. which window got
  433. * variable changes).
  434. */
  435. private Integer bringToFront = null;
  436. /**
  437. * If there are currently several windows visible, calling this method makes
  438. * this window topmost.
  439. * <p>
  440. * This method can only be called if this window connected a UI. Else an
  441. * illegal state exception is thrown. Also if there are modal windows and
  442. * this window is not modal, and illegal state exception is thrown.
  443. * <p>
  444. */
  445. public void bringToFront() {
  446. UI uI = getUI();
  447. if (uI == null) {
  448. throw new IllegalStateException(
  449. "Window must be attached to parent before calling bringToFront method.");
  450. }
  451. int maxBringToFront = -1;
  452. for (Window w : uI.getWindows()) {
  453. if (!isModal() && w.isModal()) {
  454. throw new IllegalStateException(
  455. "The UI contains modal windows, non-modal window cannot be brought to front.");
  456. }
  457. if (w.bringToFront != null) {
  458. maxBringToFront = Math.max(maxBringToFront,
  459. w.bringToFront.intValue());
  460. }
  461. }
  462. bringToFront = Integer.valueOf(maxBringToFront + 1);
  463. markAsDirty();
  464. }
  465. /**
  466. * Sets sub-window modal, so that widgets behind it cannot be accessed.
  467. * <b>Note:</b> affects sub-windows only.
  468. *
  469. * @param modal
  470. * true if modality is to be turned on
  471. */
  472. public void setModal(boolean modal) {
  473. getState().modal = modal;
  474. center();
  475. }
  476. /**
  477. * @return true if this window is modal.
  478. */
  479. public boolean isModal() {
  480. return getState().modal;
  481. }
  482. /**
  483. * Sets sub-window resizable. <b>Note:</b> affects sub-windows only.
  484. *
  485. * @param resizable
  486. * true if resizability is to be turned on
  487. */
  488. public void setResizable(boolean resizable) {
  489. getState().resizable = resizable;
  490. }
  491. /**
  492. *
  493. * @return true if window is resizable by the end-user, otherwise false.
  494. */
  495. public boolean isResizable() {
  496. return getState().resizable;
  497. }
  498. /**
  499. *
  500. * @return true if a delay is used before recalculating sizes, false if
  501. * sizes are recalculated immediately.
  502. */
  503. public boolean isResizeLazy() {
  504. return getState().resizeLazy;
  505. }
  506. /**
  507. * Should resize operations be lazy, i.e. should there be a delay before
  508. * layout sizes are recalculated. Speeds up resize operations in slow UIs
  509. * with the penalty of slightly decreased usability.
  510. *
  511. * Note, some browser send false resize events for the browser window and
  512. * are therefore always lazy.
  513. *
  514. * @param resizeLazy
  515. * true to use a delay before recalculating sizes, false to
  516. * calculate immediately.
  517. */
  518. public void setResizeLazy(boolean resizeLazy) {
  519. getState().resizeLazy = resizeLazy;
  520. }
  521. /**
  522. * Sets this window to be centered relative to its parent window. Affects
  523. * sub-windows only. If the window is resized as a result of the size of its
  524. * content changing, it will keep itself centered as long as its position is
  525. * not explicitly changed programmatically or by the user.
  526. * <p>
  527. * <b>NOTE:</b> This method has several issues as currently implemented.
  528. * Please refer to http://dev.vaadin.com/ticket/8971 for details.
  529. */
  530. public void center() {
  531. getState().centered = true;
  532. }
  533. /**
  534. * Returns the closable status of the sub window. If a sub window is
  535. * closable it typically shows an X in the upper right corner. Clicking on
  536. * the X sends a close event to the server. Setting closable to false will
  537. * remove the X from the sub window and prevent the user from closing the
  538. * window.
  539. *
  540. * Note! For historical reasons readonly controls the closability of the sub
  541. * window and therefore readonly and closable affect each other. Setting
  542. * readonly to true will set closable to false and vice versa.
  543. * <p/>
  544. * Closable only applies to sub windows, not to browser level windows.
  545. *
  546. * @return true if the sub window can be closed by the user.
  547. */
  548. public boolean isClosable() {
  549. return !isReadOnly();
  550. }
  551. /**
  552. * Sets the closable status for the sub window. If a sub window is closable
  553. * it typically shows an X in the upper right corner. Clicking on the X
  554. * sends a close event to the server. Setting closable to false will remove
  555. * the X from the sub window and prevent the user from closing the window.
  556. *
  557. * Note! For historical reasons readonly controls the closability of the sub
  558. * window and therefore readonly and closable affect each other. Setting
  559. * readonly to true will set closable to false and vice versa.
  560. * <p/>
  561. * Closable only applies to sub windows, not to browser level windows.
  562. *
  563. * @param closable
  564. * determines if the sub window can be closed by the user.
  565. */
  566. public void setClosable(boolean closable) {
  567. setReadOnly(!closable);
  568. }
  569. /**
  570. * Indicates whether a sub window can be dragged or not. By default a sub
  571. * window is draggable.
  572. * <p/>
  573. * Draggable only applies to sub windows, not to browser level windows.
  574. *
  575. * @param draggable
  576. * true if the sub window can be dragged by the user
  577. */
  578. public boolean isDraggable() {
  579. return getState().draggable;
  580. }
  581. /**
  582. * Enables or disables that a sub window can be dragged (moved) by the user.
  583. * By default a sub window is draggable.
  584. * <p/>
  585. * Draggable only applies to sub windows, not to browser level windows.
  586. *
  587. * @param draggable
  588. * true if the sub window can be dragged by the user
  589. */
  590. public void setDraggable(boolean draggable) {
  591. getState().draggable = draggable;
  592. }
  593. /*
  594. * Actions
  595. */
  596. protected CloseShortcut closeShortcut;
  597. /**
  598. * Makes is possible to close the window by pressing the given
  599. * {@link KeyCode} and (optional) {@link ModifierKey}s.<br/>
  600. * Note that this shortcut only reacts while the window has focus, closing
  601. * itself - if you want to close a subwindow from a parent window, use
  602. * {@link #addAction(com.vaadin.event.Action)} of the parent window instead.
  603. *
  604. * @param keyCode
  605. * the keycode for invoking the shortcut
  606. * @param modifiers
  607. * the (optional) modifiers for invoking the shortcut, null for
  608. * none
  609. */
  610. public void setCloseShortcut(int keyCode, int... modifiers) {
  611. if (closeShortcut != null) {
  612. removeAction(closeShortcut);
  613. }
  614. closeShortcut = new CloseShortcut(this, keyCode, modifiers);
  615. addAction(closeShortcut);
  616. }
  617. /**
  618. * Removes the keyboard shortcut previously set with
  619. * {@link #setCloseShortcut(int, int...)}.
  620. */
  621. public void removeCloseShortcut() {
  622. if (closeShortcut != null) {
  623. removeAction(closeShortcut);
  624. closeShortcut = null;
  625. }
  626. }
  627. /**
  628. * A {@link ShortcutListener} specifically made to define a keyboard
  629. * shortcut that closes the window.
  630. *
  631. * <pre>
  632. * <code>
  633. * // within the window using helper
  634. * subWindow.setCloseShortcut(KeyCode.ESCAPE, null);
  635. *
  636. * // or globally
  637. * getWindow().addAction(new Window.CloseShortcut(subWindow, KeyCode.ESCAPE));
  638. * </code>
  639. * </pre>
  640. *
  641. */
  642. public static class CloseShortcut extends ShortcutListener {
  643. protected Window window;
  644. /**
  645. * Creates a keyboard shortcut for closing the given window using the
  646. * shorthand notation defined in {@link ShortcutAction}.
  647. *
  648. * @param window
  649. * to be closed when the shortcut is invoked
  650. * @param shorthandCaption
  651. * the caption with shortcut keycode and modifiers indicated
  652. */
  653. public CloseShortcut(Window window, String shorthandCaption) {
  654. super(shorthandCaption);
  655. this.window = window;
  656. }
  657. /**
  658. * Creates a keyboard shortcut for closing the given window using the
  659. * given {@link KeyCode} and {@link ModifierKey}s.
  660. *
  661. * @param window
  662. * to be closed when the shortcut is invoked
  663. * @param keyCode
  664. * KeyCode to react to
  665. * @param modifiers
  666. * optional modifiers for shortcut
  667. */
  668. public CloseShortcut(Window window, int keyCode, int... modifiers) {
  669. super(null, keyCode, modifiers);
  670. this.window = window;
  671. }
  672. /**
  673. * Creates a keyboard shortcut for closing the given window using the
  674. * given {@link KeyCode}.
  675. *
  676. * @param window
  677. * to be closed when the shortcut is invoked
  678. * @param keyCode
  679. * KeyCode to react to
  680. */
  681. public CloseShortcut(Window window, int keyCode) {
  682. this(window, keyCode, null);
  683. }
  684. @Override
  685. public void handleAction(Object sender, Object target) {
  686. window.close();
  687. }
  688. }
  689. /**
  690. * Note, that focus/blur listeners in Window class are only supported by sub
  691. * windows. Also note that Window is not considered focused if its contained
  692. * component currently has focus.
  693. *
  694. * @see com.vaadin.event.FieldEvents.FocusNotifier#addListener(com.vaadin.event.FieldEvents.FocusListener)
  695. */
  696. @Override
  697. public void addFocusListener(FocusListener listener) {
  698. addListener(FocusEvent.EVENT_ID, FocusEvent.class, listener,
  699. FocusListener.focusMethod);
  700. }
  701. /**
  702. * @deprecated As of 7.0, replaced by
  703. * {@link #addFocusListener(FocusListener)}
  704. **/
  705. @Override
  706. @Deprecated
  707. public void addListener(FocusListener listener) {
  708. addFocusListener(listener);
  709. }
  710. @Override
  711. public void removeFocusListener(FocusListener listener) {
  712. removeListener(FocusEvent.EVENT_ID, FocusEvent.class, listener);
  713. }
  714. /**
  715. * @deprecated As of 7.0, replaced by
  716. * {@link #removeFocusListener(FocusListener)}
  717. **/
  718. @Override
  719. @Deprecated
  720. public void removeListener(FocusListener listener) {
  721. removeFocusListener(listener);
  722. }
  723. /**
  724. * Note, that focus/blur listeners in Window class are only supported by sub
  725. * windows. Also note that Window is not considered focused if its contained
  726. * component currently has focus.
  727. *
  728. * @see com.vaadin.event.FieldEvents.BlurNotifier#addListener(com.vaadin.event.FieldEvents.BlurListener)
  729. */
  730. @Override
  731. public void addBlurListener(BlurListener listener) {
  732. addListener(BlurEvent.EVENT_ID, BlurEvent.class, listener,
  733. BlurListener.blurMethod);
  734. }
  735. /**
  736. * @deprecated As of 7.0, replaced by {@link #addBlurListener(BlurListener)}
  737. **/
  738. @Override
  739. @Deprecated
  740. public void addListener(BlurListener listener) {
  741. addBlurListener(listener);
  742. }
  743. @Override
  744. public void removeBlurListener(BlurListener listener) {
  745. removeListener(BlurEvent.EVENT_ID, BlurEvent.class, listener);
  746. }
  747. /**
  748. * @deprecated As of 7.0, replaced by
  749. * {@link #removeBlurListener(BlurListener)}
  750. **/
  751. @Override
  752. @Deprecated
  753. public void removeListener(BlurListener listener) {
  754. removeBlurListener(listener);
  755. }
  756. /**
  757. * {@inheritDoc}
  758. *
  759. * If the window is a sub-window focusing will cause the sub-window to be
  760. * brought on top of other sub-windows on gain keyboard focus.
  761. */
  762. @Override
  763. public void focus() {
  764. /*
  765. * When focusing a sub-window it basically means it should be brought to
  766. * the front. Instead of just moving the keyboard focus we focus the
  767. * window and bring it top-most.
  768. */
  769. super.focus();
  770. bringToFront();
  771. }
  772. @Override
  773. protected WindowState getState() {
  774. return (WindowState) super.getState();
  775. }
  776. }