Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

Window.java 37KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209
  1. /*
  2. * Copyright 2000-2014 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.Connector;
  34. import com.vaadin.shared.MouseEventDetails;
  35. import com.vaadin.shared.ui.window.WindowMode;
  36. import com.vaadin.shared.ui.window.WindowRole;
  37. import com.vaadin.shared.ui.window.WindowServerRpc;
  38. import com.vaadin.shared.ui.window.WindowState;
  39. import com.vaadin.util.ReflectTools;
  40. /**
  41. * A component that represents a floating popup window that can be added to a
  42. * {@link UI}. A window is added to a {@code UI} using
  43. * {@link UI#addWindow(Window)}. </p>
  44. * <p>
  45. * The contents of a window is set using {@link #setContent(Component)} or by
  46. * using the {@link #Window(String, Component)} constructor.
  47. * </p>
  48. * <p>
  49. * A window can be positioned on the screen using absolute coordinates (pixels)
  50. * or set to be centered using {@link #center()}
  51. * </p>
  52. * <p>
  53. * The caption is displayed in the window header.
  54. * </p>
  55. * <p>
  56. * In Vaadin versions prior to 7.0.0, Window was also used as application level
  57. * windows. This function is now covered by the {@link UI} class.
  58. * </p>
  59. *
  60. * @author Vaadin Ltd.
  61. * @since 3.0
  62. */
  63. @SuppressWarnings("serial")
  64. public class Window extends Panel implements FocusNotifier, BlurNotifier,
  65. LegacyComponent {
  66. private WindowServerRpc rpc = new WindowServerRpc() {
  67. @Override
  68. public void click(MouseEventDetails mouseDetails) {
  69. fireEvent(new ClickEvent(Window.this, mouseDetails));
  70. }
  71. @Override
  72. public void windowModeChanged(WindowMode newState) {
  73. setWindowMode(newState);
  74. }
  75. @Override
  76. public void windowMoved(int x, int y) {
  77. if (x != getState(false).positionX) {
  78. setPositionX(x);
  79. }
  80. if (y != getState(false).positionY) {
  81. setPositionY(y);
  82. }
  83. }
  84. };
  85. /**
  86. * Creates a new, empty window
  87. */
  88. public Window() {
  89. this("", null);
  90. }
  91. /**
  92. * Creates a new, empty window with a given title.
  93. *
  94. * @param caption
  95. * the title of the window.
  96. */
  97. public Window(String caption) {
  98. this(caption, null);
  99. }
  100. /**
  101. * Creates a new, empty window with the given content and title.
  102. *
  103. * @param caption
  104. * the title of the window.
  105. * @param content
  106. * the contents of the window
  107. */
  108. public Window(String caption, Component content) {
  109. super(caption, content);
  110. registerRpc(rpc);
  111. setSizeUndefined();
  112. }
  113. /* ********************************************************************* */
  114. /*
  115. * (non-Javadoc)
  116. *
  117. * @see com.vaadin.ui.Panel#paintContent(com.vaadin.server.PaintTarget)
  118. */
  119. @Override
  120. public synchronized void paintContent(PaintTarget target)
  121. throws PaintException {
  122. if (bringToFront != null) {
  123. target.addAttribute("bringToFront", bringToFront.intValue());
  124. bringToFront = null;
  125. }
  126. // Contents of the window panel is painted
  127. super.paintContent(target);
  128. }
  129. /*
  130. * (non-Javadoc)
  131. *
  132. * @see
  133. * com.vaadin.ui.AbstractComponent#setParent(com.vaadin.server.ClientConnector
  134. * )
  135. */
  136. @Override
  137. public void setParent(HasComponents parent) {
  138. if (parent == null || parent instanceof UI) {
  139. super.setParent(parent);
  140. } else {
  141. throw new IllegalArgumentException(
  142. "A Window can only be added to a UI using UI.addWindow(Window window)");
  143. }
  144. }
  145. /*
  146. * (non-Javadoc)
  147. *
  148. * @see com.vaadin.ui.Panel#changeVariables(java.lang.Object, java.util.Map)
  149. */
  150. @Override
  151. public void changeVariables(Object source, Map<String, Object> variables) {
  152. // TODO Are these for top level windows or sub windows?
  153. boolean sizeHasChanged = false;
  154. // size is handled in super class, but resize events only in windows ->
  155. // so detect if size change occurs before super.changeVariables()
  156. if (variables.containsKey("height")
  157. && (getHeightUnits() != Unit.PIXELS || (Integer) variables
  158. .get("height") != getHeight())) {
  159. sizeHasChanged = true;
  160. }
  161. if (variables.containsKey("width")
  162. && (getWidthUnits() != Unit.PIXELS || (Integer) variables
  163. .get("width") != getWidth())) {
  164. sizeHasChanged = true;
  165. }
  166. super.changeVariables(source, variables);
  167. // Positioning
  168. final Integer positionx = (Integer) variables.get("positionx");
  169. if (positionx != null) {
  170. final int x = positionx.intValue();
  171. // This is information from the client so it is already using the
  172. // position. No need to repaint.
  173. setPositionX(x < 0 ? -1 : x);
  174. }
  175. final Integer positiony = (Integer) variables.get("positiony");
  176. if (positiony != null) {
  177. final int y = positiony.intValue();
  178. // This is information from the client so it is already using the
  179. // position. No need to repaint.
  180. setPositionY(y < 0 ? -1 : y);
  181. }
  182. if (isClosable()) {
  183. // Closing
  184. final Boolean close = (Boolean) variables.get("close");
  185. if (close != null && close.booleanValue()) {
  186. close();
  187. }
  188. }
  189. // fire event if size has really changed
  190. if (sizeHasChanged) {
  191. fireResize();
  192. }
  193. if (variables.containsKey(FocusEvent.EVENT_ID)) {
  194. fireEvent(new FocusEvent(this));
  195. } else if (variables.containsKey(BlurEvent.EVENT_ID)) {
  196. fireEvent(new BlurEvent(this));
  197. }
  198. }
  199. /**
  200. * Method that handles window closing (from UI).
  201. *
  202. * <p>
  203. * By default, windows are removed from their respective UIs and thus
  204. * visually closed on browser-side.
  205. * </p>
  206. *
  207. * <p>
  208. * To react to a window being closed (after it is closed), register a
  209. * {@link CloseListener}.
  210. * </p>
  211. */
  212. public void close() {
  213. UI uI = getUI();
  214. // Don't do anything if not attached to a UI
  215. if (uI != null) {
  216. // window is removed from the UI
  217. uI.removeWindow(this);
  218. }
  219. }
  220. /**
  221. * Gets the distance of Window left border in pixels from left border of the
  222. * containing (main window) when the window is in {@link WindowMode#NORMAL}.
  223. *
  224. * @return the Distance of Window left border in pixels from left border of
  225. * the containing (main window).or -1 if unspecified
  226. * @since 4.0.0
  227. */
  228. public int getPositionX() {
  229. return getState(false).positionX;
  230. }
  231. /**
  232. * Sets the distance of Window left border in pixels from left border of the
  233. * containing (main window). Has effect only if in {@link WindowMode#NORMAL}
  234. * mode.
  235. *
  236. * @param positionX
  237. * the Distance of Window left border in pixels from left border
  238. * of the containing (main window). or -1 if unspecified.
  239. * @since 4.0.0
  240. */
  241. public void setPositionX(int positionX) {
  242. getState().positionX = positionX;
  243. getState().centered = false;
  244. }
  245. /**
  246. * Gets the distance of Window top border in pixels from top border of the
  247. * containing (main window) when the window is in {@link WindowMode#NORMAL}
  248. * state, or when next set to that state.
  249. *
  250. * @return Distance of Window top border in pixels from top border of the
  251. * containing (main window). or -1 if unspecified
  252. *
  253. * @since 4.0.0
  254. */
  255. public int getPositionY() {
  256. return getState(false).positionY;
  257. }
  258. /**
  259. * Sets the distance of Window top border in pixels from top border of the
  260. * containing (main window). Has effect only if in {@link WindowMode#NORMAL}
  261. * mode.
  262. *
  263. * @param positionY
  264. * the Distance of Window top border in pixels from top border of
  265. * the containing (main window). or -1 if unspecified
  266. *
  267. * @since 4.0.0
  268. */
  269. public void setPositionY(int positionY) {
  270. getState().positionY = positionY;
  271. getState().centered = false;
  272. }
  273. private static final Method WINDOW_CLOSE_METHOD;
  274. static {
  275. try {
  276. WINDOW_CLOSE_METHOD = CloseListener.class.getDeclaredMethod(
  277. "windowClose", new Class[] { CloseEvent.class });
  278. } catch (final java.lang.NoSuchMethodException e) {
  279. // This should never happen
  280. throw new java.lang.RuntimeException(
  281. "Internal error, window close method not found");
  282. }
  283. }
  284. public static class CloseEvent extends Component.Event {
  285. /**
  286. *
  287. * @param source
  288. */
  289. public CloseEvent(Component source) {
  290. super(source);
  291. }
  292. /**
  293. * Gets the Window.
  294. *
  295. * @return the window.
  296. */
  297. public Window getWindow() {
  298. return (Window) getSource();
  299. }
  300. }
  301. /**
  302. * An interface used for listening to Window close events. Add the
  303. * CloseListener to a window and
  304. * {@link CloseListener#windowClose(CloseEvent)} will be called whenever the
  305. * user closes the window.
  306. *
  307. * <p>
  308. * Since Vaadin 6.5, removing a window using {@link #removeWindow(Window)}
  309. * fires the CloseListener.
  310. * </p>
  311. */
  312. public interface CloseListener extends Serializable {
  313. /**
  314. * Called when the user closes a window. Use
  315. * {@link CloseEvent#getWindow()} to get a reference to the
  316. * {@link Window} that was closed.
  317. *
  318. * @param e
  319. * Event containing
  320. */
  321. public void windowClose(CloseEvent e);
  322. }
  323. /**
  324. * Adds a CloseListener to the window.
  325. *
  326. * For a window the CloseListener is fired when the user closes it (clicks
  327. * on the close button).
  328. *
  329. * For a browser level window the CloseListener is fired when the browser
  330. * level window is closed. Note that closing a browser level window does not
  331. * mean it will be destroyed. Also note that Opera does not send events like
  332. * all other browsers and therefore the close listener might not be called
  333. * if Opera is used.
  334. *
  335. * <p>
  336. * Since Vaadin 6.5, removing windows using {@link #removeWindow(Window)}
  337. * does fire the CloseListener.
  338. * </p>
  339. *
  340. * @param listener
  341. * the CloseListener to add.
  342. */
  343. public void addCloseListener(CloseListener listener) {
  344. addListener(CloseEvent.class, listener, WINDOW_CLOSE_METHOD);
  345. }
  346. /**
  347. * @deprecated As of 7.0, replaced by
  348. * {@link #addCloseListener(CloseListener)}
  349. **/
  350. @Deprecated
  351. public void addListener(CloseListener listener) {
  352. addCloseListener(listener);
  353. }
  354. /**
  355. * Removes the CloseListener from the window.
  356. *
  357. * <p>
  358. * For more information on CloseListeners see {@link CloseListener}.
  359. * </p>
  360. *
  361. * @param listener
  362. * the CloseListener to remove.
  363. */
  364. public void removeCloseListener(CloseListener listener) {
  365. removeListener(CloseEvent.class, listener, WINDOW_CLOSE_METHOD);
  366. }
  367. /**
  368. * @deprecated As of 7.0, replaced by
  369. * {@link #removeCloseListener(CloseListener)}
  370. **/
  371. @Deprecated
  372. public void removeListener(CloseListener listener) {
  373. removeCloseListener(listener);
  374. }
  375. protected void fireClose() {
  376. fireEvent(new Window.CloseEvent(this));
  377. }
  378. /**
  379. * Event which is fired when the mode of the Window changes.
  380. *
  381. * @author Vaadin Ltd
  382. * @since 7.1
  383. *
  384. */
  385. public static class WindowModeChangeEvent extends Component.Event {
  386. private final WindowMode windowMode;
  387. /**
  388. *
  389. * @param source
  390. */
  391. public WindowModeChangeEvent(Component source, WindowMode windowMode) {
  392. super(source);
  393. this.windowMode = windowMode;
  394. }
  395. /**
  396. * Gets the Window.
  397. *
  398. * @return the window
  399. */
  400. public Window getWindow() {
  401. return (Window) getSource();
  402. }
  403. /**
  404. * Gets the new window mode.
  405. *
  406. * @return the new mode
  407. */
  408. public WindowMode getWindowMode() {
  409. return windowMode;
  410. }
  411. }
  412. /**
  413. * An interface used for listening to Window maximize / restore events. Add
  414. * the WindowModeChangeListener to a window and
  415. * {@link WindowModeChangeListener#windowModeChanged(WindowModeChangeEvent)}
  416. * will be called whenever the window is maximized (
  417. * {@link WindowMode#MAXIMIZED}) or restored ({@link WindowMode#NORMAL} ).
  418. */
  419. public interface WindowModeChangeListener extends Serializable {
  420. public static final Method windowModeChangeMethod = ReflectTools
  421. .findMethod(WindowModeChangeListener.class,
  422. "windowModeChanged", WindowModeChangeEvent.class);
  423. /**
  424. * Called when the user maximizes / restores a window. Use
  425. * {@link WindowModeChangeEvent#getWindow()} to get a reference to the
  426. * {@link Window} that was maximized / restored. Use
  427. * {@link WindowModeChangeEvent#getWindowMode()} to get a reference to
  428. * the new state.
  429. *
  430. * @param event
  431. */
  432. public void windowModeChanged(WindowModeChangeEvent event);
  433. }
  434. /**
  435. * Adds a WindowModeChangeListener to the window.
  436. *
  437. * The WindowModeChangeEvent is fired when the user changed the display
  438. * state by clicking the maximize/restore button or by double clicking on
  439. * the window header. The event is also fired if the state is changed using
  440. * {@link #setWindowMode(WindowMode)}.
  441. *
  442. * @param listener
  443. * the WindowModeChangeListener to add.
  444. */
  445. public void addWindowModeChangeListener(WindowModeChangeListener listener) {
  446. addListener(WindowModeChangeEvent.class, listener,
  447. WindowModeChangeListener.windowModeChangeMethod);
  448. }
  449. /**
  450. * Removes the WindowModeChangeListener from the window.
  451. *
  452. * @param listener
  453. * the WindowModeChangeListener to remove.
  454. */
  455. public void removeWindowModeChangeListener(WindowModeChangeListener listener) {
  456. removeListener(WindowModeChangeEvent.class, listener,
  457. WindowModeChangeListener.windowModeChangeMethod);
  458. }
  459. protected void fireWindowWindowModeChange() {
  460. fireEvent(new Window.WindowModeChangeEvent(this, getState().windowMode));
  461. }
  462. /**
  463. * Method for the resize event.
  464. */
  465. private static final Method WINDOW_RESIZE_METHOD;
  466. static {
  467. try {
  468. WINDOW_RESIZE_METHOD = ResizeListener.class.getDeclaredMethod(
  469. "windowResized", new Class[] { ResizeEvent.class });
  470. } catch (final java.lang.NoSuchMethodException e) {
  471. // This should never happen
  472. throw new java.lang.RuntimeException(
  473. "Internal error, window resized method not found");
  474. }
  475. }
  476. /**
  477. * Resize events are fired whenever the client-side fires a resize-event
  478. * (e.g. the browser window is resized). The frequency may vary across
  479. * browsers.
  480. */
  481. public static class ResizeEvent extends Component.Event {
  482. /**
  483. *
  484. * @param source
  485. */
  486. public ResizeEvent(Component source) {
  487. super(source);
  488. }
  489. /**
  490. * Get the window form which this event originated
  491. *
  492. * @return the window
  493. */
  494. public Window getWindow() {
  495. return (Window) getSource();
  496. }
  497. }
  498. /**
  499. * Listener for window resize events.
  500. *
  501. * @see com.vaadin.ui.Window.ResizeEvent
  502. */
  503. public interface ResizeListener extends Serializable {
  504. public void windowResized(ResizeEvent e);
  505. }
  506. /**
  507. * Add a resize listener.
  508. *
  509. * @param listener
  510. */
  511. public void addResizeListener(ResizeListener listener) {
  512. addListener(ResizeEvent.class, listener, WINDOW_RESIZE_METHOD);
  513. }
  514. /**
  515. * @deprecated As of 7.0, replaced by
  516. * {@link #addResizeListener(ResizeListener)}
  517. **/
  518. @Deprecated
  519. public void addListener(ResizeListener listener) {
  520. addResizeListener(listener);
  521. }
  522. /**
  523. * Remove a resize listener.
  524. *
  525. * @param listener
  526. */
  527. public void removeResizeListener(ResizeListener listener) {
  528. removeListener(ResizeEvent.class, listener);
  529. }
  530. /**
  531. * @deprecated As of 7.0, replaced by
  532. * {@link #removeResizeListener(ResizeListener)}
  533. **/
  534. @Deprecated
  535. public void removeListener(ResizeListener listener) {
  536. removeResizeListener(listener);
  537. }
  538. /**
  539. * Fire the resize event.
  540. */
  541. protected void fireResize() {
  542. fireEvent(new ResizeEvent(this));
  543. }
  544. /**
  545. * Used to keep the right order of windows if multiple windows are brought
  546. * to front in a single changeset. If this is not used, the order is quite
  547. * random (depends on the order getting to dirty list. e.g. which window got
  548. * variable changes).
  549. */
  550. private Integer bringToFront = null;
  551. /**
  552. * If there are currently several windows visible, calling this method makes
  553. * this window topmost.
  554. * <p>
  555. * This method can only be called if this window connected a UI. Else an
  556. * illegal state exception is thrown. Also if there are modal windows and
  557. * this window is not modal, and illegal state exception is thrown.
  558. * <p>
  559. */
  560. public void bringToFront() {
  561. UI uI = getUI();
  562. if (uI == null) {
  563. throw new IllegalStateException(
  564. "Window must be attached to parent before calling bringToFront method.");
  565. }
  566. int maxBringToFront = -1;
  567. for (Window w : uI.getWindows()) {
  568. if (!isModal() && w.isModal()) {
  569. throw new IllegalStateException(
  570. "The UI contains modal windows, non-modal window cannot be brought to front.");
  571. }
  572. if (w.bringToFront != null) {
  573. maxBringToFront = Math.max(maxBringToFront,
  574. w.bringToFront.intValue());
  575. }
  576. }
  577. bringToFront = Integer.valueOf(maxBringToFront + 1);
  578. markAsDirty();
  579. }
  580. /**
  581. * Sets window modality. When a modal window is open, components outside
  582. * that window cannot be accessed.
  583. * <p>
  584. * Keyboard navigation is restricted by blocking the tab key at the top and
  585. * bottom of the window by activating the tab stop function internally.
  586. *
  587. * @param modal
  588. * true if modality is to be turned on
  589. */
  590. public void setModal(boolean modal) {
  591. getState().modal = modal;
  592. center();
  593. }
  594. /**
  595. * @return true if this window is modal.
  596. */
  597. public boolean isModal() {
  598. return getState(false).modal;
  599. }
  600. /**
  601. * Sets window resizable.
  602. *
  603. * @param resizable
  604. * true if resizability is to be turned on
  605. */
  606. public void setResizable(boolean resizable) {
  607. getState().resizable = resizable;
  608. }
  609. /**
  610. *
  611. * @return true if window is resizable by the end-user, otherwise false.
  612. */
  613. public boolean isResizable() {
  614. return getState(false).resizable;
  615. }
  616. /**
  617. *
  618. * @return true if a delay is used before recalculating sizes, false if
  619. * sizes are recalculated immediately.
  620. */
  621. public boolean isResizeLazy() {
  622. return getState(false).resizeLazy;
  623. }
  624. /**
  625. * Should resize operations be lazy, i.e. should there be a delay before
  626. * layout sizes are recalculated. Speeds up resize operations in slow UIs
  627. * with the penalty of slightly decreased usability.
  628. *
  629. * Note, some browser send false resize events for the browser window and
  630. * are therefore always lazy.
  631. *
  632. * @param resizeLazy
  633. * true to use a delay before recalculating sizes, false to
  634. * calculate immediately.
  635. */
  636. public void setResizeLazy(boolean resizeLazy) {
  637. getState().resizeLazy = resizeLazy;
  638. }
  639. /**
  640. * Sets this window to be centered relative to its parent window. Affects
  641. * windows only. If the window is resized as a result of the size of its
  642. * content changing, it will keep itself centered as long as its position is
  643. * not explicitly changed programmatically or by the user.
  644. * <p>
  645. * <b>NOTE:</b> This method has several issues as currently implemented.
  646. * Please refer to http://dev.vaadin.com/ticket/8971 for details.
  647. */
  648. public void center() {
  649. getState().centered = true;
  650. }
  651. /**
  652. * Returns the closable status of the window. If a window is closable, it
  653. * typically shows an X in the upper right corner. Clicking on the X sends a
  654. * close event to the server. Setting closable to false will remove the X
  655. * from the window and prevent the user from closing the window.
  656. *
  657. * Note! For historical reasons readonly controls the closability of the
  658. * window and therefore readonly and closable affect each other. Setting
  659. * readonly to true will set closable to false and vice versa.
  660. * <p/>
  661. *
  662. * @return true if the window can be closed by the user.
  663. */
  664. public boolean isClosable() {
  665. return !isReadOnly();
  666. }
  667. /**
  668. * Sets the closable status for the window. If a window is closable it
  669. * typically shows an X in the upper right corner. Clicking on the X sends a
  670. * close event to the server. Setting closable to false will remove the X
  671. * from the window and prevent the user from closing the window.
  672. *
  673. * Note! For historical reasons readonly controls the closability of the
  674. * window and therefore readonly and closable affect each other. Setting
  675. * readonly to true will set closable to false and vice versa.
  676. * <p/>
  677. *
  678. * @param closable
  679. * determines if the window can be closed by the user.
  680. */
  681. public void setClosable(boolean closable) {
  682. setReadOnly(!closable);
  683. }
  684. /**
  685. * Indicates whether a window can be dragged or not. By default a window is
  686. * draggable.
  687. * <p/>
  688. *
  689. * @param draggable
  690. * true if the window can be dragged by the user
  691. */
  692. public boolean isDraggable() {
  693. return getState(false).draggable;
  694. }
  695. /**
  696. * Enables or disables that a window can be dragged (moved) by the user. By
  697. * default a window is draggable.
  698. * <p/>
  699. *
  700. * @param draggable
  701. * true if the window can be dragged by the user
  702. */
  703. public void setDraggable(boolean draggable) {
  704. getState().draggable = draggable;
  705. }
  706. /**
  707. * Gets the current mode of the window.
  708. *
  709. * @see WindowMode
  710. * @return the mode of the window.
  711. */
  712. public WindowMode getWindowMode() {
  713. return getState(false).windowMode;
  714. }
  715. /**
  716. * Sets the mode for the window
  717. *
  718. * @see WindowMode
  719. * @param windowMode
  720. * The new mode
  721. */
  722. public void setWindowMode(WindowMode windowMode) {
  723. if (windowMode != getWindowMode()) {
  724. getState().windowMode = windowMode;
  725. fireWindowWindowModeChange();
  726. }
  727. }
  728. /*
  729. * Actions
  730. */
  731. protected CloseShortcut closeShortcut;
  732. /**
  733. * Makes is possible to close the window by pressing the given
  734. * {@link KeyCode} and (optional) {@link ModifierKey}s.<br/>
  735. * Note that this shortcut only reacts while the window has focus, closing
  736. * itself - if you want to close a window from a UI, use
  737. * {@link UI#addAction(com.vaadin.event.Action)} of the UI instead.
  738. *
  739. * @param keyCode
  740. * the keycode for invoking the shortcut
  741. * @param modifiers
  742. * the (optional) modifiers for invoking the shortcut, null for
  743. * none
  744. */
  745. public void setCloseShortcut(int keyCode, int... modifiers) {
  746. if (closeShortcut != null) {
  747. removeAction(closeShortcut);
  748. }
  749. closeShortcut = new CloseShortcut(this, keyCode, modifiers);
  750. addAction(closeShortcut);
  751. }
  752. /**
  753. * Removes the keyboard shortcut previously set with
  754. * {@link #setCloseShortcut(int, int...)}.
  755. */
  756. public void removeCloseShortcut() {
  757. if (closeShortcut != null) {
  758. removeAction(closeShortcut);
  759. closeShortcut = null;
  760. }
  761. }
  762. /**
  763. * A {@link ShortcutListener} specifically made to define a keyboard
  764. * shortcut that closes the window.
  765. *
  766. * <pre>
  767. * <code>
  768. * // within the window using helper
  769. * window.setCloseShortcut(KeyCode.ESCAPE, null);
  770. *
  771. * // or globally
  772. * getUI().addAction(new Window.CloseShortcut(window, KeyCode.ESCAPE));
  773. * </code>
  774. * </pre>
  775. *
  776. */
  777. public static class CloseShortcut extends ShortcutListener {
  778. protected Window window;
  779. /**
  780. * Creates a keyboard shortcut for closing the given window using the
  781. * shorthand notation defined in {@link ShortcutAction}.
  782. *
  783. * @param window
  784. * to be closed when the shortcut is invoked
  785. * @param shorthandCaption
  786. * the caption with shortcut keycode and modifiers indicated
  787. */
  788. public CloseShortcut(Window window, String shorthandCaption) {
  789. super(shorthandCaption);
  790. this.window = window;
  791. }
  792. /**
  793. * Creates a keyboard shortcut for closing the given window using the
  794. * given {@link KeyCode} and {@link ModifierKey}s.
  795. *
  796. * @param window
  797. * to be closed when the shortcut is invoked
  798. * @param keyCode
  799. * KeyCode to react to
  800. * @param modifiers
  801. * optional modifiers for shortcut
  802. */
  803. public CloseShortcut(Window window, int keyCode, int... modifiers) {
  804. super(null, keyCode, modifiers);
  805. this.window = window;
  806. }
  807. /**
  808. * Creates a keyboard shortcut for closing the given window using the
  809. * given {@link KeyCode}.
  810. *
  811. * @param window
  812. * to be closed when the shortcut is invoked
  813. * @param keyCode
  814. * KeyCode to react to
  815. */
  816. public CloseShortcut(Window window, int keyCode) {
  817. this(window, keyCode, null);
  818. }
  819. @Override
  820. public void handleAction(Object sender, Object target) {
  821. window.close();
  822. }
  823. }
  824. /*
  825. * (non-Javadoc)
  826. *
  827. * @see
  828. * com.vaadin.event.FieldEvents.FocusNotifier#addFocusListener(com.vaadin
  829. * .event.FieldEvents.FocusListener)
  830. */
  831. @Override
  832. public void addFocusListener(FocusListener listener) {
  833. addListener(FocusEvent.EVENT_ID, FocusEvent.class, listener,
  834. FocusListener.focusMethod);
  835. }
  836. /**
  837. * @deprecated As of 7.0, replaced by
  838. * {@link #addFocusListener(FocusListener)}
  839. **/
  840. @Override
  841. @Deprecated
  842. public void addListener(FocusListener listener) {
  843. addFocusListener(listener);
  844. }
  845. @Override
  846. public void removeFocusListener(FocusListener listener) {
  847. removeListener(FocusEvent.EVENT_ID, FocusEvent.class, listener);
  848. }
  849. /**
  850. * @deprecated As of 7.0, replaced by
  851. * {@link #removeFocusListener(FocusListener)}
  852. **/
  853. @Override
  854. @Deprecated
  855. public void removeListener(FocusListener listener) {
  856. removeFocusListener(listener);
  857. }
  858. /*
  859. * (non-Javadoc)
  860. *
  861. * @see
  862. * com.vaadin.event.FieldEvents.BlurNotifier#addBlurListener(com.vaadin.
  863. * event.FieldEvents.BlurListener)
  864. */
  865. @Override
  866. public void addBlurListener(BlurListener listener) {
  867. addListener(BlurEvent.EVENT_ID, BlurEvent.class, listener,
  868. BlurListener.blurMethod);
  869. }
  870. /**
  871. * @deprecated As of 7.0, replaced by {@link #addBlurListener(BlurListener)}
  872. **/
  873. @Override
  874. @Deprecated
  875. public void addListener(BlurListener listener) {
  876. addBlurListener(listener);
  877. }
  878. @Override
  879. public void removeBlurListener(BlurListener listener) {
  880. removeListener(BlurEvent.EVENT_ID, BlurEvent.class, listener);
  881. }
  882. /**
  883. * @deprecated As of 7.0, replaced by
  884. * {@link #removeBlurListener(BlurListener)}
  885. **/
  886. @Override
  887. @Deprecated
  888. public void removeListener(BlurListener listener) {
  889. removeBlurListener(listener);
  890. }
  891. /**
  892. * {@inheritDoc}
  893. *
  894. * Cause the window to be brought on top of other windows and gain keyboard
  895. * focus.
  896. */
  897. @Override
  898. public void focus() {
  899. /*
  900. * When focusing a window it basically means it should be brought to the
  901. * front. Instead of just moving the keyboard focus we focus the window
  902. * and bring it top-most.
  903. */
  904. super.focus();
  905. bringToFront();
  906. }
  907. @Override
  908. protected WindowState getState() {
  909. return (WindowState) super.getState();
  910. }
  911. @Override
  912. protected WindowState getState(boolean markAsDirty) {
  913. return (WindowState) super.getState(markAsDirty);
  914. }
  915. /**
  916. * Allows to specify which components contain the description for the
  917. * window. Text contained in these components will be read by assistive
  918. * devices when it is opened.
  919. *
  920. * @param components
  921. * the components to use as description
  922. */
  923. public void setAssistiveDescription(Component... components) {
  924. if (components == null) {
  925. throw new IllegalArgumentException(
  926. "Parameter connectors must be non-null");
  927. } else {
  928. getState().contentDescription = components;
  929. }
  930. }
  931. /**
  932. * Gets the components that are used as assistive description. Text
  933. * contained in these components will be read by assistive devices when the
  934. * window is opened.
  935. *
  936. * @return array of previously set components
  937. */
  938. public Component[] getAssistiveDescription() {
  939. Connector[] contentDescription = getState().contentDescription;
  940. if (contentDescription == null) {
  941. return null;
  942. }
  943. Component[] target = new Component[contentDescription.length];
  944. System.arraycopy(contentDescription, 0, target, 0,
  945. contentDescription.length);
  946. return target;
  947. }
  948. /**
  949. * Sets the accessibility prefix for the window caption.
  950. *
  951. * This prefix is read to assistive device users before the window caption,
  952. * but not visible on the page.
  953. *
  954. * @param prefix
  955. * String that is placed before the window caption
  956. */
  957. public void setAssistivePrefix(String prefix) {
  958. getState().assistivePrefix = prefix;
  959. }
  960. /**
  961. * Gets the accessibility prefix for the window caption.
  962. *
  963. * This prefix is read to assistive device users before the window caption,
  964. * but not visible on the page.
  965. *
  966. * @return The accessibility prefix
  967. */
  968. public String getAssistivePrefix() {
  969. return getState(false).assistivePrefix;
  970. }
  971. /**
  972. * Sets the accessibility postfix for the window caption.
  973. *
  974. * This postfix is read to assistive device users after the window caption,
  975. * but not visible on the page.
  976. *
  977. * @param prefix
  978. * String that is placed after the window caption
  979. */
  980. public void setAssistivePostfix(String assistivePostfix) {
  981. getState().assistivePostfix = assistivePostfix;
  982. }
  983. /**
  984. * Gets the accessibility postfix for the window caption.
  985. *
  986. * This postfix is read to assistive device users after the window caption,
  987. * but not visible on the page.
  988. *
  989. * @return The accessibility postfix
  990. */
  991. public String getAssistivePostfix() {
  992. return getState(false).assistivePostfix;
  993. }
  994. /**
  995. * Sets the WAI-ARIA role the window.
  996. *
  997. * This role defines how an assistive device handles a window. Available
  998. * roles are alertdialog and dialog (@see <a
  999. * href="http://www.w3.org/TR/2011/CR-wai-aria-20110118/roles">Roles
  1000. * Model</a>).
  1001. *
  1002. * The default role is dialog.
  1003. *
  1004. * @param role
  1005. * WAI-ARIA role to set for the window
  1006. */
  1007. public void setAssistiveRole(WindowRole role) {
  1008. getState().role = role;
  1009. }
  1010. /**
  1011. * Gets the WAI-ARIA role the window.
  1012. *
  1013. * This role defines how an assistive device handles a window. Available
  1014. * roles are alertdialog and dialog (@see <a
  1015. * href="http://www.w3.org/TR/2011/CR-wai-aria-20110118/roles">Roles
  1016. * Model</a>).
  1017. *
  1018. * @return WAI-ARIA role set for the window
  1019. */
  1020. public WindowRole getAssistiveRole() {
  1021. return getState(false).role;
  1022. }
  1023. /**
  1024. * Set if it should be prevented to set the focus to a component outside a
  1025. * non-modal window with the tab key.
  1026. * <p>
  1027. * This is meant to help users of assistive devices to not leaving the
  1028. * window unintentionally.
  1029. * <p>
  1030. * For modal windows, this function is activated automatically, while
  1031. * preserving the stored value of tabStop.
  1032. *
  1033. * @param tabStop
  1034. * true to keep the focus inside the window when reaching the top
  1035. * or bottom, false (default) to allow leaving the window
  1036. */
  1037. public void setTabStopEnabled(boolean tabStop) {
  1038. getState().assistiveTabStop = tabStop;
  1039. }
  1040. /**
  1041. * Get if it is prevented to leave a window with the tab key.
  1042. *
  1043. * @return true when the focus is limited to inside the window, false when
  1044. * focus can leave the window
  1045. */
  1046. public boolean isTabStopEnabled() {
  1047. return getState(false).assistiveTabStop;
  1048. }
  1049. /**
  1050. * Sets the message that is provided to users of assistive devices when the
  1051. * user reaches the top of the window when leaving a window with the tab key
  1052. * is prevented.
  1053. * <p>
  1054. * This message is not visible on the screen.
  1055. *
  1056. * @param topMessage
  1057. * String provided when the user navigates with Shift-Tab keys to
  1058. * the top of the window
  1059. */
  1060. public void setTabStopTopAssistiveText(String topMessage) {
  1061. getState().assistiveTabStopTopText = topMessage;
  1062. }
  1063. /**
  1064. * Sets the message that is provided to users of assistive devices when the
  1065. * user reaches the bottom of the window when leaving a window with the tab
  1066. * key is prevented.
  1067. * <p>
  1068. * This message is not visible on the screen.
  1069. *
  1070. * @param bottomMessage
  1071. * String provided when the user navigates with the Tab key to
  1072. * the bottom of the window
  1073. */
  1074. public void setTabStopBottomAssistiveText(String bottomMessage) {
  1075. getState().assistiveTabStopBottomText = bottomMessage;
  1076. }
  1077. /**
  1078. * Gets the message that is provided to users of assistive devices when the
  1079. * user reaches the top of the window when leaving a window with the tab key
  1080. * is prevented.
  1081. *
  1082. * @return the top message
  1083. */
  1084. public String getTabStopTopAssistiveText() {
  1085. return getState(false).assistiveTabStopTopText;
  1086. }
  1087. /**
  1088. * Gets the message that is provided to users of assistive devices when the
  1089. * user reaches the bottom of the window when leaving a window with the tab
  1090. * key is prevented.
  1091. *
  1092. * @return the bottom message
  1093. */
  1094. public String getTabStopBottomAssistiveText() {
  1095. return getState(false).assistiveTabStopBottomText;
  1096. }
  1097. }