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.

VaadinTutorialForSwingDevelopers.asciidoc 43KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958
  1. ---
  2. title: Vaadin Tutorial For Swing Developers
  3. order: 8
  4. layout: page
  5. ---
  6. [[a-hitchhikers-guide-to-convert-aswing-appto-modern-web-app]]
  7. A hitchhiker's guide to convert a Swing app to modern web app
  8. -------------------------------------------------------------
  9. [[intro]]
  10. Intro
  11. ~~~~~
  12. As expressed by Pete Hunt (Facebook, React JS) in JavaOne 2014 Web
  13. Framework Smackdown, if you would be creating a UI toolkit, from a
  14. scratch, it would look nothing like a
  15. https://en.wikipedia.org/wiki/Document_Object_Model[DOM]. Web
  16. technologies indeed are not designed for application development, but
  17. rich text presentation. Markup based presentation has proven to be
  18. superior for more static content like web sites, but _applications_ are
  19. a bit different story. In the early stages of graphical UIs on
  20. computers, UI frameworks didn’t by accident form into “component based”
  21. libraries. Those UI libraries have developed during the decades, but the
  22. the basic concept of component based UI framework is still the most
  23. powerful way to create _applications_.
  24. But Swing, SWT, Qt and similar desktop UI frameworks have one major
  25. problem compared to web apps: they require you to install special
  26. software on your client machine. As we have learned during the internet
  27. era, this can be big problem. Users have lots of different kinds of
  28. applications that they use nowadays and installing all of them and
  29. especially maintaining those will become a burden for your IT
  30. department.
  31. Browser plugins like Java’s Applet/Java WebStart support (and there
  32. Swing or JavaFX) and Flash are the traditional workarounds to avoid
  33. installing software locally for workstations. But famous security holes
  34. in those, especially with outdated software, may become a huge problem
  35. and your IT department is nowadays most likely against installing any
  36. kind of third party browser plugins. For them it is much easier to just
  37. maintain one browser application. This is one of the fundamental reasons
  38. why pure web apps are conquering even most complex application domains
  39. nowadays. 
  40. [[welcome_to_the_8220wonderful8221_world_of_web_apps]]
  41. Welcome to the “wonderful” world of web apps
  42. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  43. image:img/howvaadinworks2.png[How Vaadin works] Even
  44. for experienced desktop developers it may be a huge jump from the
  45. desktop world to the web development. Developing web applications is
  46. much trickier than developing basic desktop apps. There are lots of
  47. things that makes things complicated, such as client-server
  48. communication, the markup language and CSS used for display, new
  49. programming language for the client side and client-server communication
  50. in many different forms (basic http, ajax style requests, long polling,
  51. web sockets etc.). The fact is that, even with the most modern web app
  52. frameworks, web development is not as easy as building desktop apps.
  53. Vaadin Framework is an open source Java framework and is the closest
  54. thing to the component based Swing UI development in the mainstream web
  55. app world. Vaadin is a component based UI framework that tries to make
  56. web development as easy as traditional desktop development, maximizing
  57. developers’ productivity and the quality of the produced end user
  58. experience. In a Vaadin application the actual UI logic, written by you,
  59. lives in the server’s JVM. Instead of browser plugins, Vaadin has a
  60. built-in “thin client” that renders the UI efficiently in browsers. The
  61. highly optimized communication channel sends only the stuff that is
  62. really visible on user’s screen to thin client. Once the initial
  63. rendering has been done, only deltas, in both way, are transferred
  64. between the client and the server.
  65. The architecture of Vaadin Framework provides you an abstraction for the
  66. web development challenges, and most of the time you can forget that
  67. your are building a web application. Vaadin takes care of handling all
  68. the communication, html markup, css and browser differences - you can
  69. concentrate all your energy on your domain problems with clean Java
  70. approach and take advantage of your experience from the desktop
  71. applications.
  72. Vaadin uses GWT to implement its “thin client” running in the browser.
  73. GWT is another bit similar tool for web development, and its heart is
  74. its Java to JavaScript “compiler”. GWT also has a Swing like UI
  75. component library, but in GWT the Java code is compiled into JavaScript
  76. and executed in the browser. The compiler supports only a subset of Java
  77. and the fact that it is not running in JVM causes some other
  78. limitations, but the concepts are the same in it as well. Running your
  79. code in the browser as a white box also has some security implications.
  80. [[architectural_differences_you_should_notice]]
  81. Architectural differences you should notice
  82. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  83. Every architectural decision has its pros and consequences and so does
  84. switching from Swing to Vaadin in your UI layer.
  85. [[one_application_instance_many_users]]
  86. One application instance, many users
  87. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  88. The first thing you’ll notice is that you are now developing your UI
  89. right next to your data. Pretty much all modern business apps, both web
  90. and desktop apps, save their data somehow to a central server. Often the
  91. data is “shielded” with middleware layer, with e.g. EJBs. Now that you
  92. move to Vaadin UI, the EJB, or whatever the technology you use in your
  93. “backend”, is “closer”. It can often be run in the very same application
  94. server as your Vaadin UI, making some hard problems trivial. Using a
  95. local EJB is both efficient and secure.
  96. Even if you’d still use a separate application server for your EJBs,
  97. they are most probably connected to UI servers using a fast network that
  98. can handle chatty connection between UI and business layers more
  99. efficiently than typical client server communication - the network
  100. requirements by the Vaadin thin client are in many cases less demanding,
  101. so your application can be used over e.g. mobile networks.
  102. Another thing developers arriving from desktop Java to Vaadin will soon
  103. notice that fields with “static” keyword are quite different in the
  104. server world. Many desktop applications use static fields as “user
  105. global” variables. In Java apps running in server, they are “application
  106. global”, which is a big difference. Application servers generally use a
  107. class loader per web application (.war file), not class loader per user
  108. session. For “user global” variables, use fields in your UI class,
  109. https://vaadin.com/api/com/vaadin/server/VaadinSession.html[VaadinSession],
  110. http://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpSession.html[HttpSession]
  111. or e.g.
  112. http://docs.oracle.com/javaee/7/api/javax/enterprise/context/SessionScoped.html[@SessionScoped]
  113. CDI bean.
  114. Web applications in general will be much cheaper for IT departments to
  115. maintain. They have been traditionally run in company’s internal
  116. servers, but the trend of the era is hosting them in PaaS services, in
  117. the “cloud”. Instead of maintaining the application in each users’
  118. workstation, updates and changes only need to be applied to the server.
  119. Also all data, not just the shared parts, is saved on the server whose
  120. backups are much easier to handle. When your user’s workstation breaks,
  121. you can just give him/her a replacement and the work can continue.
  122. [[memory_and_cpu_usage_is_centralized_to_server]]
  123. Memory and CPU usage is centralized to server
  124. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  125. On the negative side is the fact that some of the computing previously
  126. done by your users workstation is now moved to the server. The CPU hit
  127. is typically negligible, but you might face some memory constraints
  128. without taking this fact into account. On the other hand, the fact that
  129. the application memory and processing happens now mostly on the server,
  130. might be a good thing. The server side approach makes it possible to
  131. handle really complex computing tasks, even with really modest handheld
  132. devices. This is naturally possible with Swing and central server as
  133. well, but with Vaadin approach this comes a free bonus feature.
  134. A typical Vaadin business app consumes 50-500kB of server memory per
  135. user, depending on your application characteristics. If you have a very
  136. small application you can do with smaller number and if you reference a
  137. lot of data from your UI, which usually makes things both faster and
  138. simpler, you might need even more memory per user.
  139. The per user memory usage is in line with e.g. Java EE standard JSF. If
  140. you do some basic math you can understand this isn’t an issue for most
  141. typical applications and modern application servers. But, in case you
  142. create an accidental memory leak in application code or a carelessly
  143. load the whole database table into memory, the memory consumption may
  144. become an issue earlier than with desktop applications. Accidentally
  145. referencing million basic database entities from a user session will
  146. easily consume 100-200MB of memory per session. This might still be
  147. tolerable in desktop applications, but if you have several concurrent
  148. users, you’ll soon be in trouble.
  149. The memory issues can usually be rather easily solved by using paging or
  150. by lazy loading the data from the backend to UI. Server capacity is also
  151. really cheap nowadays, so buying a more efficient server or clustering
  152. your application to multiple application servers is most likely much
  153. cheaper than by making compromises in your architectural design. But in
  154. case each of your application users need to do some heavy analysis with
  155. huge in-memory data sets, web applications are still not the way to go
  156. for your use case.
  157. If your applications memory usage is much more important than its
  158. development cost (read: you are trying to write next GMail), Vaadin
  159. framework might not be the right tool for your. If you still want to go
  160. to web applications, in this scenario you should strive for completely
  161. (server) stateless application and keep your UI logic in browsers.
  162. http://www.gwtproject.org[GWT] is a great library for this kind of
  163. applications.
  164. [[basic_component_usage]]
  165. Basic component usage
  166. ~~~~~~~~~~~~~~~~~~~~~
  167. Basic component usage is something where you’ll really find yourself
  168. comfortable from the day one. APIs are not exactly the same, but they
  169. share the principle. Lets look at a very basic example, lets create a
  170. textfield and a button and just throw the textfield value on button
  171. click to sysout for debugging.
  172. [source,java]
  173. ....
  174. final JTextField textField = new JTextField();
  175. JButton button = new JButton();
  176. button.addActionListener(new ActionListener() {
  177. @Override
  178. public void actionPerformed(ActionEvent e) {
  179. System.out.println("You typed: " + textField.getText());
  180. }
  181. });
  182. add(textField);
  183. add(button);
  184. ....
  185. 
 and the very same thing in Vaadin application looks like this:
  186. [source,java]
  187. ....
  188. final TextField textField = new TextField();
  189. Button button = new Button();
  190. button.addClickListener(new Button.ClickListener() {
  191. @Override
  192. public void buttonClick(Button.ClickEvent event) {
  193. System.out.println("You typed: " + textField.getValue());
  194. }
  195. });
  196. addComponent(textField);
  197. addComponent(button);
  198. ....
  199. No need to explain what happens in either of the cases ;-) Typically
  200. when Swing developers start using Vaadin, in basic component usage they
  201. find the methods they are looking for quickly with the help of their
  202. favorite IDE.
  203. Vaadin http://demo.vaadin.com/sampler/[Sampler] is a demo application
  204. that contains examples of the core components with source code usage
  205. example and references to JavaDocs. It is the favorite reference for
  206. many Vaadin developers. Naturally you can also refer to plain JavaDocs
  207. and our Book of Vaadin, the complete reference manual for Vaadin.
  208. [[event_handling_and_event_dispatching_thread]]
  209. Event handling and Event dispatching thread
  210. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  211. Like most typical desktop GUI libraries, Swing serializes all access to
  212. UI via so called event dispatching thread. It fires event listeners you
  213. hook to components and if you wish to modify the UI from another thread,
  214. you submit your UI changing tasks to it with
  215. SwingUtilities.invokeAndWait(Runnable) or
  216. SwingUtilities.invokeLater(Runnable).
  217. In Vaadin there is no similar thread, but naturally parallel UI access
  218. needs to be avoided. Vaadin uses UI (~ browser tab/window) level
  219. locking. Like with Swing apps, the code executed by framework (UI init,
  220. event listeners) is “thread safe”” by default. These code blocks are
  221. usually run in Servlet containers thread that is handling an
  222. HTTP/Websocket request. In case you need to modify a UI from any other
  223. thread, you should use _UI.getCurrent().access(Runnable)_ or
  224. _UI.getCurrent().accessSynchronously(Runnable)_ to ensure there is no
  225. parallel access.
  226. [[application_bootstrap]]
  227. Application bootstrap
  228. ~~~~~~~~~~~~~~~~~~~~~
  229. A Vaadin application is basically a
  230. http://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpServlet.html[HttpServlet]
  231. behind the scenes. In portal environment its is a Portlet. Bootstrapping
  232. a Vaadin application depends a bit on the execution environment and used
  233. helper libraries.
  234. In Swing applications your execution typically starts from the iconic
  235. https://github.com/mstahv/ejb-swing-vaadin-crud/blob/master/desktop/src/main/java/org/vaadin/swingersclub/SwingApplication.java#L49-L52[main
  236. method] or from an Applet’s init method. In simple Vaadin Servlet
  237. deployment the similar entry point to your code is _UI_ class and its
  238. _init_ method. The counterpart for UI class is browser window or browser
  239. tab. If your Vaadin application is “embedded” into another page, you
  240. should consider it as the “slot” in that host page. One servlet can
  241. handle multiple UIs, mapped to different URLs, but typically you just
  242. have one per application.
  243. A code snippet below is an example of low level hello world Vaadin
  244. application bootstrap, it introduces a Vaadin servlet as a nested class
  245. using the @WebServlet annotation and a Vaadin UI mapped to it:
  246. [source,java]
  247. ....
  248. public class MyUI extends UI {
  249. @WebServlet(urlPatterns = "/*", name = "MyUIServlet")
  250. @VaadinServletConfiguration(ui = MyUI.class, productionMode = false)
  251. public static class MyUIServlet extends VaadinServlet {
  252. }
  253. @Override
  254. protected void init(VaadinRequest vaadinRequest) {
  255. setContent(new Label("Hello World!"));
  256. }
  257. }
  258. ....
  259. But, like with non trivial Swing apps, you might want to delegate some
  260. of this low level stuff to a framework that takes care of servlet, setup
  261. and UI mapping. It is highly suggested to use e.g.
  262. https://vaadin.com/javaee/[Java EE environment] with Vaadin CDI add-on
  263. or https://vaadin.com/spring/[Spring] as a basis for your application.
  264. In these cases you typically end up having different application views
  265. as class files and container specific annotations to hint how those
  266. should be served for the end users. In the example we are using
  267. cdi-helpers add-on that also gives you a basic top level navigation and
  268. application layout for free.
  269. The following class will be automatically visible in our applications
  270. menu. Not that the screenshot also shows some other views but our “about
  271. view”.
  272. [source,java]
  273. ....
  274. @CDIView("about")
  275. public class AboutView extends VerticalLayout implements View {
  276. @PostConstruct
  277. void init() {
  278. addComponent(new Label("Hello World !"));
  279. }
  280. @Override
  281. public void enter(ViewChangeListener.ViewChangeEvent viewChangeEvent) {
  282. }
  283. }
  284. ....
  285. image:img/helloworldview.png[image]
  286. _Screenshot of the hello world view_
  287. [[laying_out_components]]
  288. Laying out components
  289. ~~~~~~~~~~~~~~~~~~~~~
  290. In Swing you are using different Layout implementations that take care
  291. of positioning components in JPanel’s sub classes. You will find
  292. similarly named Layout interface in Vaadin as well, but there is a
  293. conceptual difference. In Vaadin Layout is just a normal component that
  294. whose main feature is to contain other components.
  295. [[layouts_in_vaadin]]
  296. Layouts in Vaadin
  297. ^^^^^^^^^^^^^^^^^
  298. As you probably have learned while working with Swing applications,
  299. building layouts is generally a rather complex topic. We believe we have
  300. come up with really powerful and logical API, but understanding the
  301. basic concepts about layouts is something you really want to do before
  302. building any non-trivial application. Check out at least a nice
  303. http://youtu.be/7UxEfaQq4EQ?list=PLcRrh9hGNalnmA1mbDS0NBuq6N3Mnw2u1[tutorial
  304. style webinar] we had last year and also refer to our manual.
  305. Most commonly used Layout implementations are VerticalLayout,
  306. HorizontalLayout and GridLayout. By combining and configuring them
  307. intelligently you can achieve pretty much everything. CssLayout is also
  308. commonly used, due to its simplicity in browsers DOM. If you plan to
  309. theme your application it will be the favorite of your CSS artist, but
  310. it works also without any CSS at all, pretty much like FlowLayout in
  311. Swing, although you need to use some CSS if you want the flow to be
  312. horizontal.
  313. One thing related to Layouts is that each component in Vaadin has a
  314. caption and an icon. Most often these properties are handled by the
  315. layout and different layouts handle them in different ways. For example
  316. the FormLayout places caption and icon on the left side of the component
  317. as where HorizontalLayout and VerticalLayout place captions above the
  318. component. Naturally you don’t need to use the built in captions (and
  319. icons), but you can use Label components instead, like with Swing
  320. applications, and manually place them in the desired location.
  321. To get an overview of Layout components in Vaadin, you can also take a
  322. quick overview of them via our
  323. http://demo.vaadin.com/sampler/#ui/layout[Sampler application].
  324. [[custom_layouts]]
  325. Custom layouts
  326. ^^^^^^^^^^^^^^
  327. The fact that Layout is just a component that contains other components
  328. gives us some nice flexibility. They can easily be reused to make a more
  329. domain specific classes using composition and, in case you can also
  330. master some browser development, it is easy to build completely new
  331. layouts. Even if you want to stick on the safe JVM side, the
  332. http://vaadin.com/directory[Directory] contains lots of different kind
  333. of layout implementations for custom purposes. Check e.g. BorderLayout
  334. (you can probably guess how it works ;-) ), ColumnLayout,
  335. DragAndDropLayouts, PortalLayouts and the handy layout helpers in
  336. Viritin.
  337. There is also a CustomLayout component in the core distribution, for
  338. which a better describing name would probably be “HtmlTemplateLayout”.
  339. From that you can figure out what it does. If you have a skilled
  340. “designer” in your team who masters html and css, you can use his HTML
  341. templates. Into the markup you just need to specify the “slots” where
  342. you want to place Vaadin components.
  343. [[visual_view_composition]]
  344. Visual view composition
  345. ~~~~~~~~~~~~~~~~~~~~~~~
  346. Some Swing developers swear for the name of handwritten layouts and
  347. complete control of your views. Another tribe likes to draft the UIs
  348. with visual tools and then wire it to the application logic using Java.
  349. The same thing in Vaadin world.
  350. image:https://vaadin.com/documents/10187/8663276/designersetup/c3ddcc59-0b6f-40f2-8bb2-456261b5d7a3?t=1418989464957[image]
  351. Vaadin Eclipse plugin comes with https://vaadin.com/designer[Vaadin
  352. Designer] that lets you design your UIs in “WYSIWYG” manner. You can add
  353. code manually to your visually designed classes and then later return to
  354. visual positioning if you want.
  355. The https://vaadin.com/designer[latest version] changed the “master
  356. data” of the layout to be based on HTML5 style markup. This may sound
  357. like a weird decision for some experienced Java developers, but the idea
  358. is that your layout designs and visual appearance can also be edited by
  359. less technical graphical artists, who don’t know anything about Java
  360. programming, but can do amazing tricks with graphics, html, css and
  361. typography. Named components will be naturally available via
  362. auto-generated classes, so customization and wiring to other parts of
  363. your application will still be plain old Java development that you
  364. already master. It is just the auto-generated Java parts that we changed
  365. into markup like format.
  366. [[binding_data_to_components]]
  367. Binding data to components
  368. ~~~~~~~~~~~~~~~~~~~~~~~~~~
  369. https://vaadin.com/book/-/page/datamodel.html#datamodel[Binding data]
  370. means the task of moving data between your UI components and your
  371. backend/domain objects, in both directions. Some Swing users are using
  372. advanced data binding libraries like BeansBinding. BeansBinding concepts
  373. could be adapted to Vaadin applications as well, but there are also
  374. really handy built-in helpers into Vaadin.
  375. There are interfaces called
  376. https://vaadin.com/api/com/vaadin/data/Item.html[Item] and
  377. https://vaadin.com/api/com/vaadin/data/Property.html[Property] (and utility
  378. implementations for those), used by all Vaadin
  379. http://vaadin.com/api/com/vaadin/data/Field.html[Field] components. You
  380. can use those, but most often you’ll use the built in BeanItem
  381. implementation, and typically via BeanFieldGroup helper. BeanFieldGroup
  382. can automatically bind your entities/DTOs to the corresponding
  383. https://vaadin.com/api/com/vaadin/ui/Field.html[Field] components.
  384. Similarly to BeansBinding in Swing development, this saves you from
  385. writing a huge amount of boilerplate code that basically just moves
  386. values from UI to your domain objects and vice versa.
  387. The BeanFieldGroup in Vaadin also supports by default
  388. http://beanvalidation.org[Bean Validation] annotations you might have
  389. already defined into your domain objects. The same rules can then be
  390. used on the UI layer to automatically perform validation before throwing
  391. your domain objects back to business layer.
  392. If you have ever used JTable component you are probably familiar with
  393. Swing’s interface called TableModel that is used to provide a way for
  394. JTable to list the actual data into it. In Vaadin the similar task is
  395. delegated to
  396. https://vaadin.com/api/com/vaadin/data/Container.html[Container]
  397. interface that contains Item instances. There are built in container
  398. implementations in the framework, of which BeanItemContainer will most
  399. probably become very familiar to you. It is a simple and efficient way
  400. to list your entities in Vaadin Table and in various select components.
  401. [[lazy_loading_large_data_sets]]
  402. Lazy loading large data sets
  403. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  404. In your Swing apps, if you have listed big data sets into your UI, you
  405. probably know you need to be careful what you load into your
  406. applications memory. Also, as your data is probably shared on the server
  407. in business applications, the network usage between your server and
  408. client may easily become the bottleneck. Typically this is solved by
  409. showing just the top most results of your DB query or using some sort of
  410. “paging” when listing lots of data.
  411. As we discussed earlier, Vaadin applications UI code has a huge aid from
  412. being executed right next to your data. The data is often already in
  413. your application servers memory or in a DB server that is either in the
  414. same physical server or most likely at least connected with strong
  415. network connection to your application server. This make data accessing
  416. both efficient and simple.
  417. At the same time the well optimized UI components in Vaadin only send
  418. the essential data through the wire from server to the client. For
  419. example in Table and ComboBox, only the visible parts of the data is
  420. sent to the client side and this ways network usage stays low, even when
  421. (virtually) displaying huge amounts of data.
  422. In case you can’t (due to scalability, memory usage) load all your data
  423. into servers memory, you’ll have to do similar tricks in Vaadin as well
  424. or you might run out of memory with lots of concurrent users. Limiting
  425. the result set and using paging at UI level is naturally in basic tools
  426. for Vaadin developers as well.
  427. But as UI components already do lazy loading between your server and
  428. client, you can also extend the lazy loading chain all the way to the
  429. database using “lazy loading” implementations of the
  430. https://vaadin.com/api/com/vaadin/data/Container.html[Container API].
  431. You can pretty easily write a totally custom version for your specific
  432. use case, but the strongly suggested method is to use helpers like
  433. https://vaadin.com/web/matti/blog/-/blogs/connecting-large-amounts-of-data-to-ui[LazyList]
  434. or https://vaadin.com/addon/lazy-query-container[LazyQueryContainer]
  435. instead. In most lazy loading cases, those are the tools that you really
  436. should use, but in some architectures you can also consider using
  437. https://vaadin.com/api/com/vaadin/data/util/sqlcontainer/SQLContainer.html[SqlContainer]
  438. or https://vaadin.com/addon/vaadin-jpacontainer[JPAContainer] which do
  439. rather optimized lazy loading automatically as well.
  440. [[structuring_your_ui_code]]
  441. Structuring your UI code
  442. ~~~~~~~~~~~~~~~~~~~~~~~~
  443. If you have maintained a large Swing application, you probably know it
  444. is possible to write messy code, event with Java and its static typing
  445. and great IDEs. For large desktop applications, especially with large
  446. teams and long maintained projects, you have probably applied some sort
  447. of design patterns like MVC or MVP to structure your UI code.
  448. The very same applies to Vaadin code as well. In large applications you
  449. most likely want to use some sort of strict rules to structure your
  450. code. In smaller applications it is fine to just separate logical parts
  451. of your UI to different, possibly reusable, classes.
  452. Thanks to similarities with Vaadin and Swing, you can apply your
  453. existing experience on this topic directly to Vaadin. Implementing a
  454. clean MVP pattern is a part of https://vaadin.com/training[Advanced
  455. Vaadin course], in case you want some proven experiences on the topic.
  456. Also, consider to use tools like http://cdi-spec.org[CDI] or
  457. http://projects.spring.io/spring-framework/[Spring], which may help you
  458. to implement your patterns in even more cleaner manner.
  459. [[testing]]
  460. Testing
  461. ~~~~~~~
  462. One of the largest advantages of using well structured UI code is that
  463. it often becomes easier to write tests for your UI logic. By using e.g.
  464. MVP pattern in your code you can write unit tests for your presenter
  465. classes.
  466. In addition to writing unit tests to your backend and UI logic, it is
  467. good to have full stack integration tests or automated acceptance tests.
  468. http://arquillian.org[Arquillian] is a nice tool to write tests that run
  469. in a e.g. Java EE container with a real DB.
  470. Another nice helper to implement full end-to-end testing is
  471. https://vaadin.com/add-ons/testbench[Vaadin TestBench]. It is based on
  472. the open source Selenium project and drives real browsers and simulates
  473. user interactions. This way you can test the whole application stack
  474. from browser level to the database.
  475. [[example_crud_and_its_vaadin_conversion]]
  476. Example CRUD and its Vaadin conversion
  477. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  478. Lets image you have a server that stores your customer data. The
  479. persistency and business logic is hidden behind an EJB and your Swing
  480. based rich client reads and writes data into that via a remote EJB.
  481. There are lots of this kind of applications or bit similar that use more
  482. lower level communication mechanism to the database.
  483. We will use this kind of example application and look what the different
  484. UI implementations look like. Using this example you can hopefully get a
  485. pretty realistic idea what converting a Swing based Applet or desktop
  486. application into a Vaadin based web application might require and cost.
  487. The heart of the example is the EJB that talks to the underlying RDBMS.
  488. This part is shared by both Swing and Vaadin UI. The server used in the
  489. example is pretty modern Apache TomEE. Although your application might
  490. be using older technology, the concepts are most likely very similar,
  491. even if you were using lower level RMI, CORBA or even raw DB connection.
  492. Our example is a pretty trivial CRUD, but the business logic running in
  493. the EJB is typically the most critical part of your application. Luckily
  494. you can most often recycle this part of your application, as such as in
  495. this case, or with some modernization, and just re-write the UI part.
  496. Also at the UI part the programming model will be very familiar, so the
  497. task will be really easy for you and your colleagues - even without any
  498. web development experience.
  499. In this example we will just use raw Swing and Vaadin APIs in the UI.
  500. Some vice men in the industry have prepared for big changes in
  501. technologies. In case you have done something like this into your UI
  502. code the “Vaadin upgrade” might be even easier. E.g. one of our
  503. customer, when moving from AWT to Swing, wrote a bit more generic
  504. wrappers for their UI component and split all the UI logic to separate
  505. controllers. This was to help transition to yet another UI framework in
  506. the future. Today, from desktop world, you would naturally first think
  507. JavaFX. Instead of going into JavaFX, they wanted to eliminate Java
  508. requirement from their clients totally and go with pure browsers
  509. technologies.
  510. image:img/ejbswingvaadin.png[Architecture
  511. diagram]
  512. Architectural overview how a Swing based "thin client
  513. application" backed by an EJB can be transferred to web era using
  514. Vaadin. In the example application we build a both Swing and Vaadin UIs,
  515. connecting to exactly same EJB backend.
  516. [[application_initialization]]
  517. Application initialization
  518. ^^^^^^^^^^^^^^^^^^^^^^^^^^
  519. If you have been working with some larger Swing apps, you are, instead
  520. of starting up a JFrame from your main method like in our example, most
  521. probably using some sort of application framework as a basis. The
  522. https://netbeans.org/features/platform/index.html[NetBeans Platform] is
  523. an example of such. Similarly with Vaadin, it is hardly ever a good idea
  524. to go with raw Vaadin and a servlet container.
  525. There are couple of nice choices and in this example we are using a
  526. standard Java EE basis and use Vaadin CDI as the “framework” that help
  527. us to bootstrap the UI, and also in the next step to bind it to our
  528. backend.
  529. As a bonus, when using Vaadin CDI, you need to know even less about
  530. Servlets and web specific stuff. In Vaadin CDI application, the entry
  531. point to your application is the
  532. https://vaadin.com/api/com/vaadin/ui/UI.html[UI class] that you annotate
  533. with _@CDIUI(“”)_. The empty string means the UI’s “deployment path”,
  534. the last part in your url that you use to access your application, which
  535. in our example is the actual “root” of our application. If you want, you
  536. can have multiple UI’s in your application, just map them to different
  537. urls. The Vaadin CDI add-on will “magically” introduce the low level
  538. Servlet and configure your UIs to be displayed via it.
  539. If you look at
  540. https://github.com/mstahv/ejb-swing-vaadin-crud/blob/master/server/src/main/java/org/vaadin/vaadinui/AppUI.java[the
  541. actual UI class] in the example application, you’ll see it is
  542. practically empty. This is because we are using a yet another extension
  543. (our class extends ViewMenuUI from a
  544. https://vaadin.com/addon/cdi-helpers[cdi-helpers library]) to Vaadin CDI
  545. that creates you a basic top level application layout and view
  546. navigation automatically. This may be just what you need, but in many
  547. complex applications you might want to write a more domain specific
  548. version for this this part.
  549. The actual meat of the user interface code is written into views,
  550. annotated with CDIView. If you introduce a following class to your
  551. application, it will automatically automatically mapped to
  552. http://yourapp.com/contextpaht/#!about and the cdi-helpers will
  553. automatically register it to your applications main menu.
  554. [source,java]
  555. ....
  556. @CDIView("about")
  557. public class AboutView extends VerticalLayout implements View {
  558. @PostConstruct
  559. void init() {
  560. addComponent(new Label("Hello Vaadin World!"));
  561. }
  562. @Override
  563. public void enter(ViewChangeListener.ViewChangeEvent viewChangeEvent) {
  564. }
  565. }
  566. ....
  567. If you are not familiar with CDI or managed beans in general, you might
  568. think why I’m doing the addComponent call in the @PostConstruct
  569. annotated init method instead of creating a basic constructor. In this
  570. particular case there wouldn’t be a difference, but in the next step we
  571. will be using dependency injection to connect to our EJB. As
  572. dependencies are not resolved yet during constructor call, it is often
  573. simpler to do all view initialization in @PostConstruct annotated init
  574. method instead.
  575. The enter method is called by Vaadin each time user enters the view. It
  576. is handy to refresh some some often changing data in it, but most often
  577. you don’t need to do anything in it.
  578. [[ejb_lookup]]
  579. EJB lookup
  580. ^^^^^^^^^^
  581. In our desktop Swing example we have an ejb-client available on our
  582. classpath, and when the application first time needs access to the
  583. (remote) EJB,
  584. https://github.com/mstahv/ejb-swing-vaadin-crud/blob/master/desktop/src/main/java/org/vaadin/swingersclub/SwingApplication.java#L145-L166[it
  585. gets resolved] using a JNDI lookup with proper parameters. This is
  586. pretty handy actually, especially as we don’t have any proper security
  587. control in our example.
  588. In a real world application, if you are not using a remote EJB, client
  589. server communication might be bit trickier, but you most likely have
  590. some sort of remote interface you’ll somehow detect.
  591. In Vaadin application we could use exactly the same way, but as we chose
  592. a proper Java EE + Vaadin CDI basis for our example application, the
  593. very same procedure can be done in much cleaner and more maintainable
  594. manner. As our UI objects are CDI managed beans, we can simply use @EJB
  595. or @Inject annotation to get the reference to the very same
  596. CustomerFacade. The example below uses simple field injection, but
  597. stricter architects might want you to use constructor or method
  598. injection.
  599. [source,java]
  600. ....
  601. @Inject
  602. CustomerService service;
  603. ....
  604. In the further steps we’ll notice that the actual accessing our
  605. stateless EJB is pretty much similar in both cases.
  606. [[listing_entries_from_the_backend_to_table]]
  607. Listing entries from the backend to Table
  608. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  609. In our example Swing application we are using a
  610. https://github.com/mstahv/ejb-swing-vaadin-crud/blob/master/desktop/src/main/java/org/vaadin/swingersclub/SwingApplication.java#L58[simple
  611. TableModel], based on AbstractTableModel, to bind our customer database
  612. to UI table. We simply
  613. https://github.com/mstahv/ejb-swing-vaadin-crud/blob/master/desktop/src/main/java/org/vaadin/swingersclub/SwingApplication.java#L137-L143[grab
  614. all entities] from the backend to local List instance and create a
  615. TableModel that serves data form the list. For larger table you’d
  616. probably need to implement some sort of paging or just rudely limit the
  617. amount of listed entities. The code snippet from our Swing example is
  618. listed below. The CustomerTableModel is then passed to JTable instance.
  619. [source,java]
  620. ....
  621. private List<Customer> customers;
  622. class CustomerTableModel extends AbstractTableModel {
  623. @Override
  624. public int getRowCount() {
  625. return customers.size();
  626. }
  627. @Override
  628. public int getColumnCount() {
  629. return 3;
  630. }
  631. @Override
  632. public Object getValueAt(int rowIndex, int columnIndex) {
  633. if (customers == null) {
  634. customers = getCustomerFacade().findAll();
  635. }
  636. Customer c = customers.get(rowIndex);
  637. switch (columnIndex) {
  638. case 0:
  639. return c.getFirstName();
  640. case 1:
  641. return c.getLastName();
  642. case 2:
  643. return c.getEmail();
  644. }
  645. throw new UnsupportedOperationException("Not supported yet.");
  646. }
  647. @Override
  648. public String getColumnName(int column) {
  649. return columnNames[column];
  650. }
  651. }
  652. ....
  653. In our Vaadin application we are using technically a pretty similar
  654. in-memory table view for the database. The example actually uses a
  655. commonly used helper class from an add-on called Viritin, that just
  656. accepts the list of pojos, but you gain similar result with
  657. BeanItemContainer and raw Table component as well. Creating a basic
  658. BeanItemContainer containing all our customers would look like this:
  659. [source,java]
  660. ....
  661. BeanItemContainer<Customer> bic
  662. = new BeanItemContainer<>(Customer.class, facade.findAll());
  663. ....
  664. The BeanItemContainer makes bean introspection to detect the available
  665. properties and you can then limit the available columns by configuring
  666. your https://vaadin.com/api/com/vaadin/ui/Table.html[Table] instance.
  667. You can also get to the low level with Vaadin, like with the Swing
  668. example, and implement a custom
  669. https://vaadin.com/api/com/vaadin/data/Container.html[Container]
  670. implementation that you can pass to the Table. Most often the utility
  671. containers are what you want.
  672. Listing the whole (database) table in a Vaadin user interface this way
  673. is already far more efficient because the most of the data is still only
  674. in your server. The
  675. [Table]https://vaadin.com/api/com/vaadin/ui/Table.html) component only
  676. sends the visible viewport the Vaadin’s “thin client” and when user
  677. scrolls down more rows are fetched from the servers memory. You’ll save
  678. a lots of bandwidth compared to the desktop version.
  679. However, if we still want to make our Vaadin version better, we could
  680. use lazy loading of data also on the server side. The MTable from the
  681. https://vaadin.com/addon/viritin[Viritin add-on] in the following
  682. example only needs strategies to fetch the total number of entities and
  683. fetching entities in page manner. With Java 8 style constructs a lazy
  684. loading “binding” to our CustomerFacade could look like this:
  685. [source,java]
  686. ....
  687. MTable<Customer> table = new MTable(
  688. firstRow -> facade.findRange(firstRow, maxResults),
  689. facade.count(),
  690. maxResults
  691. );
  692. ....
  693. That scales really well both in client and in server, and uses only a
  694. tiny bit of memory on the server side. There are lots of various lazy
  695. loading container implementations available in the
  696. https://vaadin.com/directory/[Vaadin Directory] and you can naturally
  697. write one yourself as well.
  698. [[binding_entity_to_a_form_for_editing]]
  699. Binding entity to a form for editing
  700. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  701. In our Swing example, we are creating an editor for our domain object in
  702. class called CustomerForm. In it we prepare some JTextField for the
  703. essential properties of the domain model, whose values we copy to domain
  704. object when users clicks the save button.
  705. [source,java]
  706. ....
  707. JTextField firstName = new JTextField();
  708. JTextField lastName = new JTextField();
  709. JTextField email = new JTextField("yourname@yourdomain.com");
  710. JButton create = new JButton("Create");
  711. JButton update = new JButton("Update");
  712. @Override
  713. public void actionPerformed(ActionEvent e) {
  714. Customer c = editedCustomer;
  715. if (e.getSource() == create) {
  716. c = new Customer();
  717. }
  718. c.setFirstName(firstName.getText());
  719. c.setLastName(lastName.getText());
  720. c.setEmail(email.getText());
  721. if (e.getSource() == create) {
  722. application.getCustomerFacade().create(c);
  723. } else {
  724. application.getCustomerFacade().edit(c);
  725. }
  726. }
  727. ....
  728. When an existing entity is set for editing, we set the existing values
  729. for the fields.
  730. [source,java]
  731. ....
  732. void editCustomer(Customer c) {
  733. this.editedCustomer = c;
  734. firstName.setText(c.getFirstName());
  735. lastName.setText(c.getLastName());
  736. email.setText(c.getEmail());
  737. updateButtonStates();
  738. }
  739. ....
  740. Using this kind of low level approach is pretty similar in Vaadin as
  741. well. Instead of JTextField you are just using TextField class from
  742. Vaadin core and instead of getText() method you use getValue() to grab
  743. the value from the field.
  744. In a real life, in both Vaadin and Swing apps, you probably want to use
  745. your life for something better than writing lots of boilerplate code for
  746. this kind of basic forms. Vaadin comes with a really powerful tool
  747. called BeanFieldGroup to free yourself from writing the “glue code”
  748. between your UI fields and domain object properties. You can use either
  749. use naming convention or a @PropertyId annotation to hint BeanFieldGroup
  750. to do the “two way mapping” automatically. The getter-setter parts of
  751. the above can be written using BeanFieldGroup as follows:
  752. [source,java]
  753. ....
  754. TextField firstName = new TextField("First name");
  755. TextField lastName = new TextField("Last name");
  756. TextField email = new TextField("Email");
  757. public void setCustomer(Customer customer) {
  758. this.customer = customer;
  759. BeanFieldGroup<Customer> bfg
  760. = BeanFieldGroup.bindFieldsUnbuffered(customer, this);
  761. }
  762. ....
  763. The BeanFieldGroup can also attach automatically constructed validators
  764. to your fields, based on the standard http://beanvalidation.org[Bean
  765. Validation] annotations, that you already might have on your domain
  766. objects. Naturally, you can manually configure validators at UI layer as
  767. well. BeanFieldGroup also provides “UI level buffering”, that might be
  768. handy in case you happen to be using “live objects”. In typical business
  769. apps, the backend is the right level that does the “buffering” for you.
  770. In our Vaadin example, we are using BeanFieldGroup via an
  771. https://github.com/mstahv/ejb-swing-vaadin-crud/blob/master/server/src/main/java/org/vaadin/vaadinui/CustomerForm.java[AbstractForm
  772. based class]. In addition to bean binding, it provides us with basic
  773. save, reset and delete buttons. In your own application you have the
  774. liberty to go with low level manual binding, automatic binding using
  775. BeanFieldGroup or with a handy helpers like the AbstractForm or your
  776. application specific version of it. The first option has the most
  777. control, the last has the cleanest code and is probably what you want in
  778. most cases.
  779. [[possible_conversion_strategy_wrappers_for_your_own_ui_framework]]
  780. Possible conversion strategy: wrappers for your own UI framework
  781. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  782. Some Swing developers have created a domain specific wrappers to hide
  783. the actual Swing API from their application code. One of our clients did
  784. this when moving their application from AWT to Swing and then wanting to
  785. prepare for a yet another UI library change in the future. They just
  786. needed to make some changes to their wrappers and then create an
  787. “adapter” for Vaadin UI.
  788. Whether this kind of wrapper strategy really pays off probably depends
  789. on the characteristics of the application itself. In our recent customer
  790. case it was estimated that even though their application was huge, going
  791. with pure Vaadin solution would have had smaller expenses. Also by
  792. creating your own UI abstraction layer, you will lose some flexibility
  793. and make additional development more expensive. However, the solution
  794. has also other advantages. With this approach it is cheap to maintain
  795. and support both modern Vaadin web client and the legacy Swing app and
  796. still implement fixes and enhancements to only one code base.
  797. The concept is by no means unique in the industry and SibVisions JVx
  798. framework is based on a similar approach. UI can be implemented just
  799. once can be deployed to both Swing and Vaadin based client applications.
  800. [[possible-conversion-strategy-gradually-move-to-web-ui]]
  801. Possible conversion strategy: gradually move to web UI
  802. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  803. Instead of rewriting the UI layer in a one big project it might be a
  804. good idea to start moving to web era gradually. You should consider this
  805. kind of approach especially if you have a well designed "backend" layer
  806. and a large application. You could start with screens that are most
  807. often needed on devices without managed software installations, like
  808. tablets, or home computers. Then proceed the conversion on more rarely
  809. used screens. On office computers you could keep using the existing
  810. software, with the full feature set, during the transition period.
  811. [[example-app-sources]]
  812. Example app sources
  813. ^^^^^^^^^^^^^^^^^^^
  814. The full sources for the
  815. https://github.com/mstahv/ejb-swing-vaadin-crud[EJB CRUD example with
  816. both Swing and Vaadin UIs] is available via GitHub.