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.

Page.java 27KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836
  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.server;
  17. import java.io.Serializable;
  18. import java.lang.reflect.Method;
  19. import java.net.URI;
  20. import java.net.URISyntaxException;
  21. import java.util.EventObject;
  22. import java.util.Iterator;
  23. import java.util.LinkedList;
  24. import java.util.List;
  25. import com.vaadin.event.EventRouter;
  26. import com.vaadin.shared.ui.BorderStyle;
  27. import com.vaadin.shared.ui.ui.PageClientRpc;
  28. import com.vaadin.shared.ui.ui.UIConstants;
  29. import com.vaadin.ui.JavaScript;
  30. import com.vaadin.ui.LegacyWindow;
  31. import com.vaadin.ui.Link;
  32. import com.vaadin.ui.Notification;
  33. import com.vaadin.ui.UI;
  34. import com.vaadin.util.ReflectTools;
  35. public class Page implements Serializable {
  36. /**
  37. * Listener that gets notified when the size of the browser window
  38. * containing the uI has changed.
  39. *
  40. * @see UI#addListener(BrowserWindowResizeListener)
  41. */
  42. public interface BrowserWindowResizeListener extends Serializable {
  43. /**
  44. * Invoked when the browser window containing a UI has been resized.
  45. *
  46. * @param event
  47. * a browser window resize event
  48. */
  49. public void browserWindowResized(BrowserWindowResizeEvent event);
  50. }
  51. /**
  52. * Event that is fired when a browser window containing a uI is resized.
  53. */
  54. public static class BrowserWindowResizeEvent extends EventObject {
  55. private final int width;
  56. private final int height;
  57. /**
  58. * Creates a new event
  59. *
  60. * @param source
  61. * the uI for which the browser window has been resized
  62. * @param width
  63. * the new width of the browser window
  64. * @param height
  65. * the new height of the browser window
  66. */
  67. public BrowserWindowResizeEvent(Page source, int width, int height) {
  68. super(source);
  69. this.width = width;
  70. this.height = height;
  71. }
  72. @Override
  73. public Page getSource() {
  74. return (Page) super.getSource();
  75. }
  76. /**
  77. * Gets the new browser window height
  78. *
  79. * @return an integer with the new pixel height of the browser window
  80. */
  81. public int getHeight() {
  82. return height;
  83. }
  84. /**
  85. * Gets the new browser window width
  86. *
  87. * @return an integer with the new pixel width of the browser window
  88. */
  89. public int getWidth() {
  90. return width;
  91. }
  92. }
  93. /**
  94. * Private class for storing properties related to opening resources.
  95. */
  96. private class OpenResource implements Serializable {
  97. /**
  98. * The resource to open
  99. */
  100. private final Resource resource;
  101. /**
  102. * The name of the target window
  103. */
  104. private final String name;
  105. /**
  106. * The width of the target window
  107. */
  108. private final int width;
  109. /**
  110. * The height of the target window
  111. */
  112. private final int height;
  113. /**
  114. * The border style of the target window
  115. */
  116. private final BorderStyle border;
  117. /**
  118. * Creates a new open resource.
  119. *
  120. * @param url
  121. * The URL to open
  122. * @param name
  123. * The name of the target window
  124. * @param width
  125. * The width of the target window
  126. * @param height
  127. * The height of the target window
  128. * @param border
  129. * The border style of the target window
  130. */
  131. private OpenResource(String url, String name, int width, int height,
  132. BorderStyle border) {
  133. this(new ExternalResource(url), name, width, height, border);
  134. }
  135. /**
  136. * Creates a new open resource.
  137. *
  138. * @param resource
  139. * The resource to open
  140. * @param name
  141. * The name of the target window
  142. * @param width
  143. * The width of the target window
  144. * @param height
  145. * The height of the target window
  146. * @param border
  147. * The border style of the target window
  148. */
  149. private OpenResource(Resource resource, String name, int width,
  150. int height, BorderStyle border) {
  151. this.resource = resource;
  152. this.name = name;
  153. this.width = width;
  154. this.height = height;
  155. this.border = border;
  156. }
  157. /**
  158. * Paints the open request. Should be painted inside the window.
  159. *
  160. * @param target
  161. * the paint target
  162. * @throws PaintException
  163. * if the paint operation fails
  164. */
  165. private void paintContent(PaintTarget target) throws PaintException {
  166. target.startTag("open");
  167. target.addAttribute("src", resource);
  168. if (name != null && name.length() > 0) {
  169. target.addAttribute("name", name);
  170. }
  171. if (width >= 0) {
  172. target.addAttribute("width", width);
  173. }
  174. if (height >= 0) {
  175. target.addAttribute("height", height);
  176. }
  177. switch (border) {
  178. case MINIMAL:
  179. target.addAttribute("border", "minimal");
  180. break;
  181. case NONE:
  182. target.addAttribute("border", "none");
  183. break;
  184. }
  185. target.endTag("open");
  186. }
  187. }
  188. private static final Method BROWSWER_RESIZE_METHOD = ReflectTools
  189. .findMethod(BrowserWindowResizeListener.class,
  190. "browserWindowResized", BrowserWindowResizeEvent.class);
  191. /**
  192. * @deprecated As of 7.0, use {@link BorderStyle#NONE} instead.
  193. */
  194. @Deprecated
  195. public static final BorderStyle BORDER_NONE = BorderStyle.NONE;
  196. /**
  197. * @deprecated As of 7.0, use {@link BorderStyle#MINIMAL} instead.
  198. */
  199. @Deprecated
  200. public static final BorderStyle BORDER_MINIMAL = BorderStyle.MINIMAL;
  201. /**
  202. * @deprecated As of 7.0, use {@link BorderStyle#DEFAULT} instead.
  203. */
  204. @Deprecated
  205. public static final BorderStyle BORDER_DEFAULT = BorderStyle.DEFAULT;
  206. /**
  207. * Listener that listens to changes in URI fragment.
  208. */
  209. public interface UriFragmentChangedListener extends Serializable {
  210. public void uriFragmentChanged(UriFragmentChangedEvent event);
  211. }
  212. private static final Method URI_FRAGMENT_CHANGED_METHOD = ReflectTools
  213. .findMethod(Page.UriFragmentChangedListener.class,
  214. "uriFragmentChanged", UriFragmentChangedEvent.class);
  215. /**
  216. * Resources to be opened automatically on next repaint. The list is
  217. * automatically cleared when it has been sent to the client.
  218. */
  219. private final LinkedList<OpenResource> openList = new LinkedList<OpenResource>();
  220. /**
  221. * A list of notifications that are waiting to be sent to the client.
  222. * Cleared (set to null) when the notifications have been sent.
  223. */
  224. private List<Notification> notifications;
  225. /**
  226. * Event fired when uri fragment changes.
  227. */
  228. public static class UriFragmentChangedEvent extends EventObject {
  229. /**
  230. * The new uri fragment
  231. */
  232. private final String uriFragment;
  233. /**
  234. * Creates a new instance of UriFragmentReader change event.
  235. *
  236. * @param source
  237. * the Source of the event.
  238. */
  239. public UriFragmentChangedEvent(Page source, String uriFragment) {
  240. super(source);
  241. this.uriFragment = uriFragment;
  242. }
  243. /**
  244. * Gets the uI in which the fragment has changed.
  245. *
  246. * @return the uI in which the fragment has changed
  247. */
  248. public Page getPage() {
  249. return (Page) getSource();
  250. }
  251. /**
  252. * Get the new fragment
  253. *
  254. * @return the new fragment
  255. */
  256. public String getUriFragment() {
  257. return uriFragment;
  258. }
  259. }
  260. private EventRouter eventRouter;
  261. private final UI uI;
  262. private int browserWindowWidth = -1;
  263. private int browserWindowHeight = -1;
  264. private JavaScript javaScript;
  265. /**
  266. * The current browser location.
  267. */
  268. private URI location;
  269. public Page(UI uI) {
  270. this.uI = uI;
  271. }
  272. private void addListener(Class<?> eventType, Object target, Method method) {
  273. if (eventRouter == null) {
  274. eventRouter = new EventRouter();
  275. }
  276. eventRouter.addListener(eventType, target, method);
  277. }
  278. private void removeListener(Class<?> eventType, Object target, Method method) {
  279. if (eventRouter != null) {
  280. eventRouter.removeListener(eventType, target, method);
  281. }
  282. }
  283. public void addUriFragmentChangedListener(
  284. Page.UriFragmentChangedListener listener) {
  285. addListener(UriFragmentChangedEvent.class, listener,
  286. URI_FRAGMENT_CHANGED_METHOD);
  287. }
  288. /**
  289. * @deprecated As of 7.0, replaced by
  290. * {@link #addUriFragmentChangedListener(UriFragmentChangedListener)}
  291. **/
  292. @Deprecated
  293. public void addListener(Page.UriFragmentChangedListener listener) {
  294. addUriFragmentChangedListener(listener);
  295. }
  296. public void removeUriFragmentChangedListener(
  297. Page.UriFragmentChangedListener listener) {
  298. removeListener(UriFragmentChangedEvent.class, listener,
  299. URI_FRAGMENT_CHANGED_METHOD);
  300. }
  301. /**
  302. * @deprecated As of 7.0, replaced by
  303. * {@link #removeUriFragmentChangedListener(UriFragmentChangedListener)}
  304. **/
  305. @Deprecated
  306. public void removeListener(Page.UriFragmentChangedListener listener) {
  307. removeUriFragmentChangedListener(listener);
  308. }
  309. /**
  310. * Sets the fragment part in the current location URI. Optionally fires a
  311. * {@link UriFragmentChangedEvent}.
  312. * <p>
  313. * The fragment is the optional last component of a URI, prefixed with a
  314. * hash sign ("#").
  315. * <p>
  316. * Passing <code>null</code> as <code>newFragment</code> clears the fragment
  317. * (no "#" in the URI); passing an empty string sets an empty fragment (a
  318. * trailing "#" in the URI.) This is consistent with the semantics of
  319. * {@link java.net.URI}.
  320. *
  321. * @param newUriFragment
  322. * The new fragment.
  323. * @param fireEvent
  324. * true to fire event
  325. *
  326. * @see #getUriFragment()
  327. * @see #setLocation(URI)
  328. * @see UriFragmentChangedEvent
  329. * @see Page.UriFragmentChangedListener
  330. *
  331. */
  332. public void setUriFragment(String newUriFragment, boolean fireEvents) {
  333. String oldUriFragment = location.getFragment();
  334. if (newUriFragment == oldUriFragment
  335. || (newUriFragment != null && newUriFragment
  336. .equals(oldUriFragment))) {
  337. return;
  338. }
  339. try {
  340. location = new URI(location.getScheme(),
  341. location.getSchemeSpecificPart(), newUriFragment);
  342. } catch (URISyntaxException e) {
  343. // This should not actually happen as the fragment syntax is not
  344. // constrained
  345. throw new RuntimeException(e);
  346. }
  347. if (fireEvents) {
  348. fireEvent(new UriFragmentChangedEvent(this, newUriFragment));
  349. }
  350. uI.markAsDirty();
  351. }
  352. private void fireEvent(EventObject event) {
  353. if (eventRouter != null) {
  354. eventRouter.fireEvent(event);
  355. }
  356. }
  357. /**
  358. * Sets URI fragment. This method fires a {@link UriFragmentChangedEvent}
  359. *
  360. * @param newUriFragment
  361. * id of the new fragment
  362. * @see UriFragmentChangedEvent
  363. * @see Page.UriFragmentChangedListener
  364. */
  365. public void setUriFragment(String newUriFragment) {
  366. setUriFragment(newUriFragment, true);
  367. }
  368. /**
  369. * Gets the currently set URI fragment.
  370. * <p>
  371. * Returns <code>null</code> if there is no fragment and an empty string if
  372. * there is an empty fragment.
  373. * <p>
  374. * To listen to changes in fragment, hook a
  375. * {@link Page.UriFragmentChangedListener}.
  376. *
  377. * @return the current fragment in browser location URI.
  378. *
  379. * @see #getLocation()
  380. * @see #setUriFragment(String)
  381. * @see #addUriFragmentChangedListener(UriFragmentChangedListener)
  382. */
  383. public String getUriFragment() {
  384. return location.getFragment();
  385. }
  386. public void init(VaadinRequest request) {
  387. // Extract special parameter sent by vaadinBootstrap.js
  388. String location = request.getParameter("loc");
  389. String clientWidth = request.getParameter("cw");
  390. String clientHeight = request.getParameter("ch");
  391. if (location != null) {
  392. try {
  393. this.location = new URI(location);
  394. } catch (URISyntaxException e) {
  395. throw new RuntimeException(
  396. "Invalid location URI received from client", e);
  397. }
  398. }
  399. if (clientWidth != null && clientHeight != null) {
  400. try {
  401. browserWindowWidth = Integer.parseInt(clientWidth);
  402. browserWindowHeight = Integer.parseInt(clientHeight);
  403. } catch (NumberFormatException e) {
  404. throw new RuntimeException(
  405. "Invalid window size received from client", e);
  406. }
  407. }
  408. }
  409. public WebBrowser getWebBrowser() {
  410. return uI.getSession().getBrowser();
  411. }
  412. /**
  413. * Updates the internal state with the given values. Does not resize the
  414. * Page or browser window.
  415. *
  416. * @param width
  417. * The new width
  418. * @param height
  419. * The new height
  420. */
  421. public void updateBrowserWindowSize(int width, int height) {
  422. boolean fireEvent = false;
  423. if (width != browserWindowWidth) {
  424. browserWindowWidth = width;
  425. fireEvent = true;
  426. }
  427. if (height != browserWindowHeight) {
  428. browserWindowHeight = height;
  429. fireEvent = true;
  430. }
  431. if (fireEvent) {
  432. fireEvent(new BrowserWindowResizeEvent(this, browserWindowWidth,
  433. browserWindowHeight));
  434. }
  435. }
  436. /**
  437. * Adds a new {@link BrowserWindowResizeListener} to this uI. The listener
  438. * will be notified whenever the browser window within which this uI resides
  439. * is resized.
  440. *
  441. * @param resizeListener
  442. * the listener to add
  443. *
  444. * @see BrowserWindowResizeListener#browserWindowResized(BrowserWindowResizeEvent)
  445. * @see #setResizeLazy(boolean)
  446. */
  447. public void addBrowserWindowResizeListener(
  448. BrowserWindowResizeListener resizeListener) {
  449. addListener(BrowserWindowResizeEvent.class, resizeListener,
  450. BROWSWER_RESIZE_METHOD);
  451. }
  452. /**
  453. * @deprecated As of 7.0, replaced by
  454. * {@link #addBrowserWindowResizeListener(BrowserWindowResizeListener)}
  455. **/
  456. @Deprecated
  457. public void addListener(BrowserWindowResizeListener resizeListener) {
  458. addBrowserWindowResizeListener(resizeListener);
  459. }
  460. /**
  461. * Removes a {@link BrowserWindowResizeListener} from this UI. The listener
  462. * will no longer be notified when the browser window is resized.
  463. *
  464. * @param resizeListener
  465. * the listener to remove
  466. */
  467. public void removeBrowserWindowResizeListener(
  468. BrowserWindowResizeListener resizeListener) {
  469. removeListener(BrowserWindowResizeEvent.class, resizeListener,
  470. BROWSWER_RESIZE_METHOD);
  471. }
  472. /**
  473. * @deprecated As of 7.0, replaced by
  474. * {@link #removeBrowserWindowResizeListener(BrowserWindowResizeListener)}
  475. **/
  476. @Deprecated
  477. public void removeListener(BrowserWindowResizeListener resizeListener) {
  478. removeBrowserWindowResizeListener(resizeListener);
  479. }
  480. /**
  481. * Gets the last known height of the browser window in which this UI
  482. * resides.
  483. *
  484. * @return the browser window height in pixels
  485. */
  486. public int getBrowserWindowHeight() {
  487. return browserWindowHeight;
  488. }
  489. /**
  490. * Gets the last known width of the browser window in which this uI resides.
  491. *
  492. * @return the browser window width in pixels
  493. */
  494. public int getBrowserWindowWidth() {
  495. return browserWindowWidth;
  496. }
  497. public JavaScript getJavaScript() {
  498. if (javaScript == null) {
  499. // Create and attach on first use
  500. javaScript = new JavaScript();
  501. javaScript.extend(uI);
  502. }
  503. return javaScript;
  504. }
  505. public void paintContent(PaintTarget target) throws PaintException {
  506. if (!openList.isEmpty()) {
  507. for (final Iterator<OpenResource> i = openList.iterator(); i
  508. .hasNext();) {
  509. (i.next()).paintContent(target);
  510. }
  511. openList.clear();
  512. }
  513. // Paint notifications
  514. if (notifications != null) {
  515. target.startTag("notifications");
  516. for (final Iterator<Notification> it = notifications.iterator(); it
  517. .hasNext();) {
  518. final Notification n = it.next();
  519. target.startTag("notification");
  520. if (n.getCaption() != null) {
  521. target.addAttribute(
  522. UIConstants.ATTRIBUTE_NOTIFICATION_CAPTION,
  523. n.getCaption());
  524. }
  525. if (n.getDescription() != null) {
  526. target.addAttribute(
  527. UIConstants.ATTRIBUTE_NOTIFICATION_MESSAGE,
  528. n.getDescription());
  529. }
  530. if (n.getIcon() != null) {
  531. target.addAttribute(
  532. UIConstants.ATTRIBUTE_NOTIFICATION_ICON,
  533. n.getIcon());
  534. }
  535. if (!n.isHtmlContentAllowed()) {
  536. target.addAttribute(
  537. UIConstants.NOTIFICATION_HTML_CONTENT_NOT_ALLOWED,
  538. true);
  539. }
  540. target.addAttribute(
  541. UIConstants.ATTRIBUTE_NOTIFICATION_POSITION, n
  542. .getPosition().ordinal());
  543. target.addAttribute(UIConstants.ATTRIBUTE_NOTIFICATION_DELAY,
  544. n.getDelayMsec());
  545. if (n.getStyleName() != null) {
  546. target.addAttribute(
  547. UIConstants.ATTRIBUTE_NOTIFICATION_STYLE,
  548. n.getStyleName());
  549. }
  550. target.endTag("notification");
  551. }
  552. target.endTag("notifications");
  553. notifications = null;
  554. }
  555. if (location != null) {
  556. target.addAttribute(UIConstants.LOCATION_VARIABLE,
  557. location.toString());
  558. }
  559. }
  560. /**
  561. * Navigates this page to the given URI. The contents of this page in the
  562. * browser is replaced with whatever is returned for the given URI.
  563. *
  564. * @param uri
  565. * the URI to show
  566. */
  567. public void setLocation(String uri) {
  568. openList.add(new OpenResource(uri, null, -1, -1, BORDER_DEFAULT));
  569. uI.markAsDirty();
  570. }
  571. /**
  572. * Navigates this page to the given URI. The contents of this page in the
  573. * browser is replaced with whatever is returned for the given URI.
  574. *
  575. * @param uri
  576. * the URI to show
  577. */
  578. public void setLocation(URI uri) {
  579. setLocation(uri.toString());
  580. }
  581. /**
  582. * Returns the location URI of this page, as reported by the browser. Note
  583. * that this may not be consistent with the server URI the application is
  584. * deployed in due to potential proxies, redirections and similar.
  585. *
  586. * @return The browser location URI.
  587. */
  588. public URI getLocation() {
  589. return location;
  590. }
  591. /**
  592. * For internal use only. Used to update the server-side location when the
  593. * client-side location changes.
  594. */
  595. public void updateLocation(String location) {
  596. try {
  597. String oldUriFragment = this.location.getFragment();
  598. this.location = new URI(location);
  599. String newUriFragment = this.location.getFragment();
  600. if (newUriFragment == null ? oldUriFragment != null
  601. : !newUriFragment.equals(oldUriFragment)) {
  602. fireEvent(new UriFragmentChangedEvent(this, newUriFragment));
  603. }
  604. } catch (URISyntaxException e) {
  605. throw new RuntimeException(e);
  606. }
  607. }
  608. /**
  609. * Opens the given URL in a window with the given name.
  610. * <p>
  611. * The supplied {@code windowName} is used as the target name in a
  612. * window.open call in the client. This means that special values such as
  613. * "_blank", "_self", "_top", "_parent" have special meaning. An empty or
  614. * <code>null</code> window name is also a special case.
  615. * </p>
  616. * <p>
  617. * "", null and "_self" as {@code windowName} all causes the URL to be
  618. * opened in the current window, replacing any old contents. For
  619. * downloadable content you should avoid "_self" as "_self" causes the
  620. * client to skip rendering of any other changes as it considers them
  621. * irrelevant (the page will be replaced by the response from the URL). This
  622. * can speed up the opening of a URL, but it might also put the client side
  623. * into an inconsistent state if the window content is not completely
  624. * replaced e.g., if the URL is downloaded instead of displayed in the
  625. * browser.
  626. * </p>
  627. * <p>
  628. * "_blank" as {@code windowName} causes the URL to always be opened in a
  629. * new window or tab (depends on the browser and browser settings).
  630. * </p>
  631. * <p>
  632. * "_top" and "_parent" as {@code windowName} works as specified by the HTML
  633. * standard.
  634. * </p>
  635. * <p>
  636. * Any other {@code windowName} will open the URL in a window with that
  637. * name, either by opening a new window/tab in the browser or by replacing
  638. * the contents of an existing window with that name.
  639. * </p>
  640. * <p>
  641. * Please note that opening a popup window in this way may be blocked by the
  642. * browser's popup-blocker because the new browser window is opened when
  643. * processing a response from the server. To avoid this, you should instead
  644. * use {@link Link} for opening the window because browsers are more
  645. * forgiving then the window is opened directly from a client-side click
  646. * event.
  647. * </p>
  648. *
  649. * @param url
  650. * the URL to open.
  651. * @param windowName
  652. * the name of the window.
  653. */
  654. public void open(String url, String windowName) {
  655. openList.add(new OpenResource(url, windowName, -1, -1, BORDER_DEFAULT));
  656. uI.markAsDirty();
  657. }
  658. /**
  659. * Opens the given URL in a window with the given size, border and name. For
  660. * more information on the meaning of {@code windowName}, see
  661. * {@link #open(String, String)}.
  662. * <p>
  663. * Please note that opening a popup window in this way may be blocked by the
  664. * browser's popup-blocker because the new browser window is opened when
  665. * processing a response from the server. To avoid this, you should instead
  666. * use {@link Link} for opening the window because browsers are more
  667. * forgiving then the window is opened directly from a client-side click
  668. * event.
  669. * </p>
  670. *
  671. * @param url
  672. * the URL to open.
  673. * @param windowName
  674. * the name of the window.
  675. * @param width
  676. * the width of the window in pixels
  677. * @param height
  678. * the height of the window in pixels
  679. * @param border
  680. * the border style of the window.
  681. */
  682. public void open(String url, String windowName, int width, int height,
  683. BorderStyle border) {
  684. openList.add(new OpenResource(url, windowName, width, height, border));
  685. uI.markAsDirty();
  686. }
  687. /**
  688. * @deprecated As of 7.0, only retained to maintain compatibility with
  689. * LegacyWindow.open methods. See documentation for
  690. * {@link LegacyWindow#open(Resource, String, int, int, BorderStyle)}
  691. * for discussion about replacing API.
  692. */
  693. @Deprecated
  694. public void open(Resource resource, String windowName, int width,
  695. int height, BorderStyle border) {
  696. openList.add(new OpenResource(resource, windowName, width, height,
  697. border));
  698. uI.markAsDirty();
  699. }
  700. /**
  701. * Internal helper method to actually add a notification.
  702. *
  703. * @param notification
  704. * the notification to add
  705. */
  706. private void addNotification(Notification notification) {
  707. if (notifications == null) {
  708. notifications = new LinkedList<Notification>();
  709. }
  710. notifications.add(notification);
  711. uI.markAsDirty();
  712. }
  713. /**
  714. * Shows a notification message.
  715. *
  716. * @see Notification
  717. *
  718. * @param notification
  719. * The notification message to show
  720. *
  721. * @deprecated As of 7.0, use Notification.show(Page) instead.
  722. */
  723. @Deprecated
  724. public void showNotification(Notification notification) {
  725. addNotification(notification);
  726. }
  727. /**
  728. * Gets the Page to which the current uI belongs. This is automatically
  729. * defined when processing requests to the server. In other cases, (e.g.
  730. * from background threads), the current uI is not automatically defined.
  731. *
  732. * @see UI#getCurrent()
  733. *
  734. * @return the current page instance if available, otherwise
  735. * <code>null</code>
  736. */
  737. public static Page getCurrent() {
  738. UI currentUI = UI.getCurrent();
  739. if (currentUI == null) {
  740. return null;
  741. }
  742. return currentUI.getPage();
  743. }
  744. /**
  745. * Sets the page title. The page title is displayed by the browser e.g. as
  746. * the title of the browser window or as the title of the tab.
  747. *
  748. * @param title
  749. * the new page title to set
  750. */
  751. public void setTitle(String title) {
  752. uI.getRpcProxy(PageClientRpc.class).setTitle(title);
  753. }
  754. }