<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Blog @ SIB Visions &#187; rzenz</title>
	<atom:link href="http://blog.sibvisions.com/author/rzenz/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.sibvisions.com</link>
	<description>Blog @ SIB Visions</description>
	<lastBuildDate>Fri, 24 Apr 2026 07:44:44 +0000</lastBuildDate>
		<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Four years SIB Visions, a look back and ahead</title>
		<link>https://blog.sibvisions.com/2018/05/07/four-years-sib-visions-rzenz/</link>
		<comments>https://blog.sibvisions.com/2018/05/07/four-years-sib-visions-rzenz/#comments</comments>
		<pubDate>Mon, 07 May 2018 07:02:37 +0000</pubDate>
		<dc:creator>rzenz</dc:creator>
				<category><![CDATA[Information]]></category>

		<guid isPermaLink="false">https://blog.sibvisions.com/?p=7845</guid>
		<description><![CDATA[My fourth year at SIB Visions has ended, once more it is time to take a deep breath, sit down and have a look at everything that has happened so far.
Demos
As mentioned in my last years post, there are several new demo applications available in the VisionX application store. These range from member portals to [...]]]></description>
			<content:encoded><![CDATA[<p><a href="https://blog.sibvisions.com/2017/04/14/three-years-sib-visions-rzenz/">My fourth year at SIB Visions has ended</a>, once more it is time to take a deep breath, sit down and have a look at everything that has happened so far.</p>
<h3 style="padding-top: 10px">Demos</h3>
<p>As mentioned in <a href="https://blog.sibvisions.com/2017/04/14/three-years-sib-visions-rzenz/">my last years post</a>, there are several <a href="https://blog.sibvisions.com/2017/05/22/visionx-demo-application/">new demo applications</a> available in the <a href="https://visionx.sibvisions.com/">VisionX</a> application store. These range from member portals to ERP applications and demonstrate not only the capabilities of <a href="https://www.sibvisions.com/jvx">JVx</a> but also those of <a href="https://visionx.sibvisions.com/">VisionX</a>.</p>
<p style="text-align: center"><a href="https://blog.sibvisions.com/wp-content/uploads/2017/04/demo-biels.png" rel="lightbox[7845]"><img src="https://blog.sibvisions.com/wp-content/uploads/2017/04/demo-biels.png" alt="The layout of a simple screen with a table and a few editors." width="480" height="240" style="border: 1px solid #cccccc" /></a></p>
<p>The <a href="https://blog.sibvisions.com/2017/05/22/visionx-demo-application/">blog posting</a> already outlines quite well what the demo applications encompass, so there is no need here to reiterate that. However, working in these was quite interesting because it is such a vast spectrum of applications, they have quite different requirements and as I've said before (at some point), one should always use the product one does create.</p>
<h3 style="padding-top: 10px">JVx Reference series</h3>
<p>The <a href="https://blog.sibvisions.com/tag/jvx-reference/">JVx Reference series</a>, a collection of blog posts which is supposed to give an overview over the most important aspects of the <a href="https://www.sibvisions.com/jvx">JVx Application Framework</a>, has also grown considerably:</p>
<ul>
<li><a href="https://blog.sibvisions.com/2017/04/24/jvx-reference-application-basics/">Application Basics</a>, an overview over how a <a href="https://www.sibvisions.com/jvx">JVx</a> application works.</li>
<li><a href="https://blog.sibvisions.com/2017/05/01/jvx-reference-databooks/">DataBooks</a>, a simple introduction to DataBooks.</li>
<li><a href="https://blog.sibvisions.com/2017/07/03/jvx-reference-resource-and-uiresource/">Resource and UIResource</a>, an explanation of the GUI abstraction concepts.</li>
<li><a href="https://blog.sibvisions.com/2017/09/28/jvx-reference-launchers-and-applications/">Launchers and Applications</a>, an overview over the two concepts of Launchers and Applications in <a href="https://www.sibvisions.com/jvx">JVx</a>.</li>
<li><a href="https://blog.sibvisions.com/2017/11/15/jvx-reference-the-formlayout/">The FormLayout</a>, a tutorial showing how to use the FormLayout.</li>
<li><a href="https://blog.sibvisions.com/2018/01/05/jvx-reference-celleditors/">CellEditors</a>, an explanation on what CellEditors are.</li>
</ul>
<p>The series now covers all of the most important topics of the <a href="https://www.sibvisions.com/jvx">JVx</a> framework. The new articles are outlining the remaining core concepts of <a href="https://www.sibvisions.com/jvx">JVx</a> and give a good overview over these. If you feel like something is still missing and should be added to this list, feel free to drop us a message so that we can include it. We're also considering pressing these into an easier to digest format, to make the entrance of newcomers to <a href="https://www.sibvisions.com/jvx">JVx</a> as easy as possible.</p>
<h3 style="padding-top: 10px">Kitchensink</h3>
<p>After having it around for so many years, I've finally managed to <a href="https://blog.sibvisions.com/2017/09/07/jvx-kitchensink-a-simple-jvx-showcase-application/">properly introduce the JVx Kitchensink</a> last year. It is a simple demo application which is supposed to give a good overview over all the components and controls of <a href="https://www.sibvisions.com/jvx">JVx</a>.</p>
<p style="text-align: center"><a href="https://blog.sibvisions.com/wp-content/uploads/2017/09/databinding.png" rel="lightbox[7845]"><img src="https://blog.sibvisions.com/wp-content/uploads/2017/09/databinding.png" alt="JVx Kitchensink - Databinding" width="500" style="border: 1px solid #cccccc" /></a></p>
<p>It is also my go-to application when it comes to debugging problems with JVx or testing the same functionality in different implementations. With this introduction it also received a much needed upgrade in aesthetics and functionality, for example it is now easy to see the source of each sample.</p>
<h3 style="padding-top: 10px">JVx and Lua</h3>
<p>I'm quite a fan of <a href="https://www.luaj.org/luaj/3.0/README.html">LuaJ</a>, a <a href="https://en.wikipedia.org/wiki/Lua_%28programming_language%29Lua">Lua</a> JITC for Java. It allows you to quickly and easily deploy a complete Lua integration and adding scripting support to your application. I've worked with LuaJ on a private project of mine and have been very fascinated with how easy it is to create a scripting interface with it, so of course I could not withstand the temptation to create <a href="https://github.com/sibvisions/jvx.lua">a proof-of-concept JVx bindings library</a> with it.</p>
<p>These bindings give you access to the complete GUI layer of JVx, directly from Lua scripts. There is also a <a>demo application for these bindings</a> available.</p>
<p style="text-align: center"><a href="https://blog.sibvisions.com/wp-content/uploads/2018/04/demo1.png" rel="lightbox[7845]"><img src="https://blog.sibvisions.com/wp-content/uploads/2018/04/demo1.png" alt="JVx Lua Demo Application" width="500" style="border: 1px solid #cccccc" /></a></p>
<p>Additionally, these bindings are used in the <a href="https://github.com/sibvisions/jvx.formlayout-visualization">JVx FormLayout Visualization application</a>, which makes it easy to inspect certain configurations of the FormLayout and see how it behaves with each change.</p>
<p style="text-align: center"><a href="https://blog.sibvisions.com/wp-content/uploads/2018/04/formlayout-visualization.png" rel="lightbox[7845]"><img src="https://blog.sibvisions.com/wp-content/uploads/2018/04/formlayout-visualization.png" alt="JVx FormLayout Visualization Application" width="500" style="border: 1px solid #cccccc" /></a></p>
<h3 style="padding-top: 10px">Vaadin 8</h3>
<p>In the late summer of 2017 we've started working on migrating from Vaadin 7 to Vaadin 8. That was not a small task, but was eased by the availability of the Vaadin 7 compatibility layer, which allowed us to gradually and deliberately upgrade parts and single components to the new version. All in all, the migration went rather smooth even though it was quite time consuming. On a similar note, we took the opportunity and enabled <a href="https://oss.sibvisions.com/index.php?do=details&amp;task_id=1602&amp;project=7">the new client-side layouts</a> by default. These new layouts provide a much more sophisticated layouting mechanism and allow the applications to utilize layouts as it was previously only possible in desktop applications.</p>
<p>I already wrote <a>briefly about these new layouts in my last years posting</a>, and I will do so again. The main motivation behind these new layouts is to be able to use sophisticated layouts on the client side which are driven dynamically by the size of each component. There is no such support in Vaadin by default, so we had to create our own layouts for this. The main idea behind these layouts is to have the layouting mechanism completely on the client side and that it only operates with hints (constraints) given by the server side, if they are required at all. What is happening on the client side is that each component which is added to the panel is measured and then absolutely positioned inside the panel according to the layout. So technically it works exactly the same as the layouts in the <a href="https://en.wikipedia.org/wiki/Swing_%28Java%29">Swing</a> or <a href="https://en.wikipedia.org/wiki/JavaFX">JavaFX</a> implementation, with the sole difference that the a layer of indirection is between the component management and the layout itself (namely the client/server connection).</p>
<p>While further work was done on these layouts, the need to actually being able to measure the time spent in each panels layout method was also required. Unfortunately, there wasn't a ready made solution at hand so I dug around the Vaadin internals and found that it has a profiler built-in. Nice, or so I thought, as it turned out, <a href="https://blog.sibvisions.com/2017/09/11/vaadin-hack-the-profiler/">getting it to spit out the needed information was a little bit more work</a> than anticipated, however, in the end I was able to gather quite valuable information from it.</p>
<p>The remaining time was filled with making sure that Vaadin 8 worked the same way as Vaadin 7 did, and replacing all the deprecated Vaadin 7 components wherever possible.</p>
<h3 style="padding-top: 10px">Documentation pipeline</h3>
<p>As part of our efforts to unify our documentation and provide a better documentation experience (for us, our users and our customers) we've built a custom documentation pipeline. This pipeline allows us to feed it <a href="https://daringfireball.net/projects/markdown/">Markdown</a> documents and spits out HTML, PDF and DokuWiki files. The main component which enables us to do that is <a href="https://pandoc.org/">Pandoc</a>, the swiss-army knife when it comes to converting documents, and <a href="https://wkhtmltopdf.org/">wkhtmltopdf</a>, which allows to convert HTML documents into PDFs.</p>
<p>The requirements for this pipeline were simple enough:</p>
<ol>
<li>Documentation must be easy to write.</li>
<li>Documentation must have a unified look, always.</li>
<li>Conversion into multiple formats are required (HTML, PDF and DokuWiki).</li>
</ol>
<p>That lead us to the decision to use Markdown with Pandoc. Markdown is easy to write and easy to read and does not dictate any sort of styling for the finished document (though it is possible with embedded HTML). Pandoc can convert the Markdown documents to HTML and DokuWiki and additionally allows us to manipulate these documents on the fly by using <a href="https://pandoc.org/lua-filters.html">Lua filters</a>. With these filters one is capable of manipulating the internal document representation and add or remove additional parts or modify already existing ones. In short, there is not much the Lua filters cannot do.</p>
<p>Conversion to PDF was a quite different matter, the logical choice was to convert the HTML to PDF, as this was already quite well laid out. wkhtmltopdf is a tool which uses the Qt Webkit engine to render a HTML document into a PDF, there are quite a few gotchas on the way, but overall it does that very well. Additionally, with the modern CSS variants, one can write rules for different <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries">devices</a>, which make it easy to change the style of a document as soon as it is send to a printer.</p>
<p>Last but not least, we needed a way to easily start this pipeline on different machines. We've opted to use <a href="https://en.wikipedia.org/wiki/Apache_Ant">Apache Ant</a> as launcher environment for the pipeline for a few simple reasons:</p>
<ul>
<li>We are already familiar with it.</li>
<li>It allows to write complex logic using the <a href="https://ant-contrib.sourceforge.net/">ant-contrib tasks</a>.</li>
<li>As it is a Java solution, we can write the script once and run it everywhere. So we don't need to duplicate logic over multiple files for different systems.</li>
</ul>
<p>So the only thing that needed to be system dependent were the launcher scripts. We've put all the necessary logic into the Apache Ant build file (which is mostly copying files and executing different programs like Pandoc) which in turn is invoked through the systems specific launchers.</p>
<p>I'm not sure in what detail I can go here, but the most work here was obviously to create the HTML template and figuring out which options make the most sense to use. I can give you two pieces of advice, though. First, when working with Pandoc and Lua filters, the native (or JSON) output format of Pandoc is your best friend when it comes to debugging the document structure. Second, when trying to create print material with wkhtmltopdf, disable the automatic scaling of content, it will save you a lot of headache.</p>
<p>We're still looking into how we can make this pipeline available to the general public, whether it will be as a product or as (partial) FLOSS has not been decided by now.</p>
<h3 style="padding-top: 10px">EPlug</h3>
<p>With the start of the new year we've found the time to squeeze some much needed bug fixes into <a href="https://www.sibvisions.com/eplug">EPlug</a> and publish <a href="https://blog.sibvisions.com/2018/01/30/eplug-1-2-7/">the 1.2.7 bug fix release</a>. It brings various bug fixes, improved performance and a better DataBookView to the table.</p>
<h3 style="padding-top: 10px">Diving into database specific behavior</h3>
<p>There were some problems surrounding our PostgreSQL JDBC implementation. As it turned out, when an exception occurs during a transaction, PostgreSQL is awaiting a user interaction on how to proceed. I've <a href="https://blog.sibvisions.com/2018/02/12/jvx-postgresql-savepoints/">outlined everything related to it in another blog post</a>, and as it turned out, PostgreSQL wasn't even the odd one during my tests.</p>
<h3 style="padding-top: 10px">The look ahead</h3>
<p>That was a quite slow year, actually. The Vaadin 8 migration took a lot of time, but a few interesting projects sneaked in none the less. I'm currently working on another quite interesting project which I hope will be finished within the next time. Stay tuned for it.</p>
<p>Thanks to everyone at SIB Visions, it's been an awesome year and I'm looking forward to another one with all of you!</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.sibvisions.com/2018/05/07/four-years-sib-visions-rzenz/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JVx and PostgreSQL, supporting Savepoints</title>
		<link>https://blog.sibvisions.com/2018/02/12/jvx-postgresql-savepoints/</link>
		<comments>https://blog.sibvisions.com/2018/02/12/jvx-postgresql-savepoints/#comments</comments>
		<pubDate>Mon, 12 Feb 2018 10:05:51 +0000</pubDate>
		<dc:creator>rzenz</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Information]]></category>
		<category><![CDATA[JDBC]]></category>
		<category><![CDATA[JVx]]></category>
		<category><![CDATA[PostgreSQL]]></category>

		<guid isPermaLink="false">https://blog.sibvisions.com/?p=7704</guid>
		<description><![CDATA[Transactions are an integral mechanism of databases, without them we could hardly ensure data consistency. Well, we could of course, but it would be a lot more work. JDBC has of course support for transactions, but it also supports so called "Savepoints", which we will have a look at today.
What are transactions?
Normally, I'd assume that [...]]]></description>
			<content:encoded><![CDATA[<p><a href="https://en.wikipedia.org/wiki/Database_transaction">Transactions</a> are an integral mechanism of databases, without them we could hardly ensure data consistency. Well, we could of course, but it would be a lot more work. <a href="https://en.wikipedia.org/wiki/Database_transaction">JDBC</a> has of course support for transactions, but it also supports so called "Savepoints", which we will have a look at today.</p>
<h3 style="padding-top: 10px">What are transactions?</h3>
<p>Normally, I'd assume that everyone of you knows what transactions are and what they are used for, but today I will quickly rehash it to make sure. Transactions enable us to define groups of statements to be executed on a database with all either succeeding or all failing. Imagine the following statements which might be executed on a database as one action:</p>
<div class="codesnip-container">
<pre style="line-height: 14px">
1: Insert record into A
2: Update record of B
3: Update another record of B
4: Insert record into C
</pre>
</div>
<p>This might happen in the background if you click a button or do something similar. This example is straightforward but if we start thinking about possible problems we will soon realize that there is a lot of potential for things going wrong. For example if statement #3 would fail we would miss records in the tables B and C. Overall, our data would be in an inconsistent state after that. To make sure that it does not happen, we can define these statements as a single transaction.</p>
<div class="codesnip-container">
<pre style="line-height: 14px">
Transaction
  |-Insert record into A
  |-Update record of B
  |-Update another record of B
  |-Insert record into C
  \-Commit
</pre>
</div>
<p>If one of these statements fail, all changes done by previous statements can be undone and the database will return to the state before we started manipulating it. That is great, because we can now guarantee that even though an error has happened, the data will remain in a consistent state.</p>
<p>We could even extend that with additional application logic, for example we insert three records and then we check if the values of all records add up to a certain threshold, if yes, we simply undo the changes. Or if we notice that a constraint has been violated (though, pretty much all databases support constraint definitions in one way or the other). Additionally, transactions are completely isolated from all other connected clients. That means that if we start a transaction and insert a record into table A, all other clients will not see this record until we commit our changes. So the data is never in an inconsistent state, not even temporarily or transiently.</p>
<h3 style="padding-top: 10px">What are Savepoints?</h3>
<p><a href="https://en.wikipedia.org/wiki/Savepoint">Savepoints</a> are sub-transactions within another transaction. It allows to undo parts of an ongoing transaction. </p>
<p>Another example:</p>
<div class="codesnip-container">
<pre style="line-height: 14px">
Transaction
  |-Insert record into A
  |-Insert child record into B
  |-Insert child record into B
  |-Insert another record into A
  |-Insert child record into B
  |-Insert child record into B
  |-Insert another record into A
  |-Insert child record into B
  |-Insert child record into B
  \-Commit
</pre>
</div>
<p>This is a little bit more fabricated and complicated, assume we want to insert three master records with two detail records each. The following conditions apply:</p>
<ul>
<li>If a master record fails to insert, nothing should be inserted.</li>
<li>If a detail record fails to insert, the corresponding master record should also not be inserted.</li>
</ul>
<p>This is hard to do with a simple transaction, but is quite easy when it comes to using savepoints:</p>
<div class="codesnip-container">
<pre style="line-height: 14px">
Transaction
  |-Savepoint 1
  |   |-Insert record into A
  |   |-Insert child record into B
  |   \-Insert child record into B
  |-Savepoint 2
  |   |-Insert another record into A
  |   |-Insert child record into B
  |   \-Insert child record into B
  |-Savepoint 3
  |   |-Insert another record into A
  |   |-Insert child record into B
  |   \-Insert child record into B
  \-Commit
</pre>
</div>
<p>We create a savepoint before the insert of the master record, if the insert of the master record fails we rollback the transaction, if the insert of a detail record fails we rollback to the savepoint we created earlier. This allows quite complicated and nested transactions, especially because there is no defined limit to how deep savepoints can be nested.</p>
<h3 style="padding-top: 10px">Error behavior</h3>
<p>Of course it can always happen that a statement fails for one reason or another, so it is important to know how the database behaves once an error occurred. We built ourselves another simple example:</p>
<div class="codesnip-container">
<pre style="line-height: 14px">
Transaction
  |-Insert record into A
  |-Insert record into B (this fails)
  |-Insert record into C
  \-Commit
</pre>
</div>
<p>We insert three records, and the second one fails to insert. How should the database behave in such a situation? Turns out that this differs between different database systems.</p>
<h4 style="padding-top: 10px">Silent/Automatic restore to a previous state</h4>
<p>Many databases perform a simple "silent/automatic restore to a previous state", all changes done (if any) of the current statement are undone and the transaction can be treated like the failing statement never happened. With the example above, and assuming that we do not cancel the transaction on an error, the records would be inserted into A and C.</p>
<p>In our tests <a href="http://www.oracle.com/technetwork/database/enterprise-edition/overview/index.html">Oracle</a>, <a href="https://www.mysql.com/">MySQL</a>/<a href="https://mariadb.org/">MariaDB</a>, <a href="http://www.h2database.com/html/main.html">H2</a> and <a href="https://www.sqlite.org/">SQLite</a> were all behaving this way.</p>
<h4 style="padding-top: 10px">Requiring manual recovery</h4>
<p><a href="https://www.postgresql.org/">PostgresSQL</a> requires to perform a "manual recovery" from a failed statement. So that once an error occurred during a transaction, the user has to revert to a (manually) set savepoint or rollback the complete transaction. We will go into details on that later.</p>
<h4 style="padding-top: 10px">Reverting everything and happily continuing</h4>
<p><a href="https://www.microsoft.com/en-us/sql-server/sql-server-2016">MS SQL</a> on the other hand has a quite different approach. When an error occurs during a transaction, all changes are (automatically) rolled back but the transaction can still be used. So in our example, only the record in C would be inserted.</p>
<h3 style="padding-top: 10px">PostgreSQL JDBC and Savepoints</h3>
<p>Back to <a href="https://www.postgresql.org/">PostgresSQL</a> and how it requires manual recovery. When a statement fails within a transaction in PostgreSQL, the transaction enters the aborted state and one can then see an error like the one below if further statements are issued:</p>
<blockquote><p>
Current transaction is aborted, commands ignored until end of transaction block.
</p></blockquote>
<p>What that means is simple that the connection/server is still waiting on input on what to do with the transaction. There are three possible ways to recover from there:</p>
<ol>
<li><a href="https://www.postgresql.org/docs/9.6/static/sql-rollback.html">Rollback</a> the complete transaction</li>
<li><a href="https://www.postgresql.org/docs/9.6/static/sql-commit.html">Commit</a>, which will be transformed into a rollback at this point</li>
<li><a href="https://www.postgresql.org/docs/9.6/static/sql-rollback-to.html">Rollback to a savepoint</a></li>
</ol>
<p>But these actions must be initiated by the user before the transaction can be further used (or not, if it is being rolled back completely). If one wants to emulate the behavior of other databases in PostgreSQL, every statement that is executed within a transaction has to be "wrapped" with a savepoint, in pseudo-code:</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">begin transaction<br />
&nbsp; &nbsp; savepoint<br />
&nbsp; &nbsp; <span class="kw1">try</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; execute statement<br />
&nbsp; &nbsp; &nbsp; &nbsp; release savepoint<br />
&nbsp; &nbsp; <span class="kw1">catch</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; rollback to savepoint<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; ...<br />
<span class="me1">commit</span></div>
</div>
<p>Even though that seems tedious, that is not the case. If you have such a requirement you already have central point through which all statements pass before being executed, so this can be implemented easily.</p>
<h3 style="padding-top: 10px">JVx and Savepoints</h3>
<p>In our case it is DBAccess, our main datasource. Because every database interaction has to pass through DBAccess (in one way or the other), we could <a href="https://oss.sibvisions.com/index.php?do=details&amp;task_id=1870&amp;project=2">easily implement such emulation at a low-level</a> and it is automatically available to all users. To be exact, DBAccess has received internal support to wrap all statements in savepoints when configured to do so. This configuration possibility is protected and is currently only used by the PostgresSQL DBAccess extension. It does exactly what it says on the tin and is only active when enabled and automatic commits have been turned off. So this change does have no effect on any other database but PostgreSQL.</p>
<p>We already <a href="https://oss.sibvisions.com/index.php?do=details&amp;task_id=1881&amp;project=2">have plans to extend this basic savepoint support</a> with a public API which allows users of JVx to utilize this new functionality. One of the ideas that we are currently discussing is to provide the ability to create named savepoints. A simple mockup of that idea:</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="co1">// Switch off auto commit to use transactions.</span></div>
</li>
<li class="li2">
<div class="de2">dbAccess.<span class="me1">setAutoCommit</span><span class="br0">&#40;</span><span class="kw2">false</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2"><span class="co1">// Insert some data.</span></div>
</li>
<li class="li2">
<div class="de2">dbStorage.<span class="me1">insert</span><span class="br0">&#40;</span>aRecord<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">dbStorage.<span class="me1">insert</span><span class="br0">&#40;</span>anotherRecord<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2"><span class="co1">// This part is optional.</span></div>
</li>
<li class="li2">
<div class="de2"><span class="kw1">try</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; dbAccess.<span class="me1">setSavepoint</span><span class="br0">&#40;</span><span class="st0">&quot;NAME&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; dbStorage.<span class="me1">insert</span><span class="br0">&#40;</span>yetAnotherRecord<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; dbStorage.<span class="me1">update</span><span class="br0">&#40;</span>someOtherRecord<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="kw1">catch</span> <span class="br0">&#40;</span>DataSourceException dse<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; log.<span class="me1">error</span><span class="br0">&#40;</span>dse<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; dbAccess.<span class="me1">rollbackTo</span><span class="br0">&#40;</span><span class="st0">&quot;NAME&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">dbAccess.<span class="me1">commit</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
</ol>
</div>
</div>
<p>As said, we are currently in the process of discussing such possibilities but definitely want to provide such an API at one point.</p>
<h3 style="padding-top: 10px">Conclusion</h3>
<p>As it turns out, the "special" behavior of PostgreSQL isn't as special as it seems to be. It is a design decision that was taken and that is understandable. Changing this behavior now, 20+ years in, is out of the question as it would require a substantial effort to make sure that this behavior is backwards compatible. The gains from such a change on the other hand would be very little, as it is a quite specialized case in which this behavior matters and  the "fix" is rather easy.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.sibvisions.com/2018/02/12/jvx-postgresql-savepoints/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>EPlug 1.2.7</title>
		<link>https://blog.sibvisions.com/2018/01/30/eplug-1-2-7/</link>
		<comments>https://blog.sibvisions.com/2018/01/30/eplug-1-2-7/#comments</comments>
		<pubDate>Tue, 30 Jan 2018 12:59:06 +0000</pubDate>
		<dc:creator>rzenz</dc:creator>
				<category><![CDATA[Release notes]]></category>
		<category><![CDATA[EPlug]]></category>

		<guid isPermaLink="false">https://blog.sibvisions.com/?p=7737</guid>
		<description><![CDATA[We're happy to announce the release of EPlug 1.2.7. This minor update comes with a big performance improvement!
Major performance improvement
The most notable and important feature of this release is the major speed improvement when checking files. We've revisited how the build pipeline works and could determine quite a few bottlenecks which did not only encumber [...]]]></description>
			<content:encoded><![CDATA[<p>We're happy to announce the release of <a href="https://eplug.sibvisions.com/">EPlug</a> <strong>1.2.7</strong>. This minor update comes with a big performance improvement!</p>
<h3 style="padding-top: 10px">Major performance improvement</h3>
<p>The most notable and important feature of this release is the major speed improvement when checking files. We've revisited how the build pipeline works and could determine quite a few bottlenecks which did not only encumber the build process, but also the live checks of databooks. After fixing these bottlenecks the databook live checks are blazing fast and one does not notice any more that these are active.</p>
<p>While reviewing the code, we also saw the possibility for a few more tweaks which we will incorporate into the next major release, to squeeze even more performance out of this.</p>
<h3 style="padding-top: 10px">Improved DataBook View</h3>
<p>The DataBook view has also received some much needed attention. There is now a toolbar button which allows to sort the columns by their name (instead of their order as returned by the datasource). Additionally the view does no longer flicker when refreshing and will also clear itself when the last editor closes.</p>
<h3 style="padding-top: 10px">Other fixes</h3>
<ol>
<li>There is no longer a sleeping EPlug job in the Progress View.</li>
<li>The EPlug preferences are now only available on Java projects.</li>
<li>If there is no screen lifecycle object, the session object is now used.</li>
<li>Removed raw HTML in tooltips.</li>
</ol>
<h3 style="padding-top: 10px">How to get it?</h3>
<p>Simply update EPlug via Eclipse!</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.sibvisions.com/2018/01/30/eplug-1-2-7/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JVx Reference, CellEditors</title>
		<link>https://blog.sibvisions.com/2018/01/05/jvx-reference-celleditors/</link>
		<comments>https://blog.sibvisions.com/2018/01/05/jvx-reference-celleditors/#comments</comments>
		<pubDate>Thu, 04 Jan 2018 23:37:56 +0000</pubDate>
		<dc:creator>rzenz</dc:creator>
				<category><![CDATA[Information]]></category>
		<category><![CDATA[JVx]]></category>
		<category><![CDATA[JVx Reference]]></category>

		<guid isPermaLink="false">https://blog.sibvisions.com/?p=7560</guid>
		<description><![CDATA[Let's talk about CellEditors, and how they are decoupled from the surrounding GUI.
What are they?
While we've already covered large parts of how the GUI layer and the model of JVx works, the CellEditors have been left completely untouched and unmentioned. One might believe that they can be easily explained together with the Editors, however, they [...]]]></description>
			<content:encoded><![CDATA[<p>Let's talk about CellEditors, and how they are decoupled from the surrounding GUI.</p>
<h3 style="padding-top: 10px">What are they?</h3>
<p>While we've already covered large parts of <a href="https://blog.sibvisions.com/2016/12/07/jvx-reference-of-technologies-and-factories/">how the GUI layer</a> and <a href="https://blog.sibvisions.com/2017/05/01/jvx-reference-databooks/">the model</a> of JVx works</a>, the CellEditors have been left completely untouched and unmentioned. One might believe that they can be easily explained together with the Editors, however, they are a topic on their own, and a complex one from time to time that is.</p>
<p>The difference between Editors (the UIEditor for the most part) and CellEditors is that the Editors only provide the high-level GUI control, while the CellEditors provide the actual functionality. Let's take a look at a quite simple screen.</p>
<p style="text-align: center"><a href="https://blog.sibvisions.com/wp-content/uploads/2017/12/celleditors.png" rel="lightbox[7560]"><img src="https://blog.sibvisions.com/wp-content/uploads/2017/12/celleditors.png" alt="The layout of a simple screen with a table and a few editors." width="500" style="border: 1px solid #cccccc" /></a></p>
<p>We see a window with a table on the left and some editors on the right, simple enough. Now these components we are seeing are UIEditors, not CellEditors. The CellEditors themselves are only added as child components to the Editors, so the Editors are basically just panels which contain the actual CellEditor.</p>
<p style="text-align: center"><a href="https://blog.sibvisions.com/wp-content/uploads/2017/12/celleditors2.png" rel="lightbox[7560]"><img src="https://blog.sibvisions.com/wp-content/uploads/2017/12/celleditors2.png" alt="The same scree but with the CellEditors differentiated from the UIEditors which contain them." width="500" style="border: 1px solid #cccccc" /></a></p>
<p>So technically every UIEditor is just another panel which gets the CellEditor added. The CellEditors themselves follow the same pattern as all GUI components in JVx, there is the base interface, an eventual extension of technology components, the implementation and finally the UI object. They are, however, rarely directly used in building the GUI, but mostly only referenced when building the model.</p>
<h3 style="padding-top: 10px">Why are they?</h3>
<p>If you want to make GUI editor components, I know of two possible ways from the top of my head to achieve that: You create dedicated editor components for the datatypes that are available, for example a NumberEditor, TextEditor and so forth. Or you create one editor component which acts as a mere container and allows to plug in any wanted behavior for the type you're editing.</p>
<p>We've opted for the second option, because it means that the GUI is actually decoupled from the datatypes (and in extension the data) of the model. If we'd have separate components for each datatype, changing the datatype of a single column would mean that you'd have to touch all editors associated with that column and change that code, maybe with rippling effects on the rest of the GUI. With the CellEditors, one can change the datatype of a column and not worry about the GUI that is associated with that column. The CellEditor is changed on the model once and that change is automatically picked up by all Editors. Which also means that one can define and change defaults very easily and globally.</p>
<p>Of course one can also set the preferred or wanted CellEditor directly on the Editor, instead of using the one defined in the model, should the need arise.</p>
<h3 style="padding-top: 10px">And the table?</h3>
<p>The same applies to the Table. Theoretically, every cell of the Table can be viewed as a single Editor, for this context at least. So a single cell behaves the same as an Editor when it comes to how the CellEditors are handled.</p>
<h3 style="padding-top: 10px">How many are there?</h3>
<p>JVx comes with a variety of CellEditors out of the box:</p>
<ul>
<li>Boolean</li>
<li>Choice</li>
<li>Date/Time</li>
<li>List</li>
<li>Number</li>
<li>Text</li>
<ul>
<li>HTML</li>
<li>Multiline</li>
<li>Password</li>
<li>Standard</li>
</ul>
</ul>
<p>With these nearly all needs can be covered. If there is need for a new one, it can be created and added like any other UI component.</p>
<h3 style="padding-top: 10px">Using CellEditors</h3>
<p>As said previously, which CellEditor is used is defined primarily with the model, for example:</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="kw1">private</span> <span class="kw4">void</span> initiliazeModel<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="kw1">throws</span> ModelException</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; dataBook <span class="sy0">=</span> <span class="kw1">new</span> MemDataBook<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; ICellEditor cellEditor <span class="sy0">=</span> <span class="kw1">new</span> UITextCellEditor<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; IDataType dataType <span class="sy0">=</span> <span class="kw1">new</span> StringDataType<span class="br0">&#40;</span>cellEditor<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; ColumnDefinition column <span class="sy0">=</span> <span class="kw1">new</span> ColumnDefinition<span class="br0">&#40;</span><span class="st0">&quot;COLUMN&quot;</span>, dataType<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; RowDefinition rowDefinition <span class="sy0">=</span> dataBook.<span class="me1">getRowDefinition</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; rowDefinition.<span class="me1">addColumnDefinition</span><span class="br0">&#40;</span>column<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; dataBook.<span class="me1">open</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2"><span class="kw1">private</span> <span class="kw4">void</span> initializeUI<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="kw1">throws</span> ModelException</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; editor <span class="sy0">=</span> <span class="kw1">new</span> UIEditor<span class="br0">&#40;</span>dataBook, <span class="st0">&quot;COLUMN&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; add<span class="br0">&#40;</span>editor<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
</div>
<p>We can see that every column has a datatype and every datatype has a CellEditor. That allows the model to provide the actual editing functionality without changing the GUI code. The Editor, when notifyRepaint() is called, will fetch the CellEditor from the datatype and use it. Additionally, there is a technology dependent default mechanism which allows this system to work even when the UI classes are not used.</p>
<p>Let's do a step by step explanation of what happens:</p>
<ol>
<li>The model is created.</li>
<li>The GUI is created.</li>
<li>The model invokes notifyRepaint() on all bound controls.</li>
<li>The Editor gets the CellEditor from the model and adds it to itself.</li>
</ol>
<h3 style="padding-top: 10px">One moment, instance sharing?</h3>
<p>If we revisit at the example code from above, we will notice that the CellEditor instance is set on the model and must then be used by the Editor. That means that a single CellEditor instance is used for all bound Editors. We all know that sharing instances in such a way can be fun, but in this case it is not a problem because CellEditors are only "factories" for the actual editing components.</p>
<p>The ICellEditor interface does actually only specify two methods, whether it is a direct cell editor, and the factory method for creating an ICellEditorHandler. The CellEditorHandler is the manager of the instance of the component that is going to be embedded into the Editor.</p>
<ol>
<li>notifyRepaint() is called on the editor.</li>
<li>The Editor gets the CellEditorHandler from the CellEditor.</li>
<li>The Editor gets the component from the CellEditorHandler and embeds it.</li>
</ol>
<p>This mechanism makes sure that no component instances end up shared between different GUI components.</p>
<h3 style="padding-top: 10px">A closer look at the CellEditorHandler</h3>
<p>If we take a good look at the CellEditorHandler interface, we see that it contains everything that is required for setting up a component to be able to edit data coming from a DataRow. One method is especially important, the getCellEditorComponent() function. It returns the actual technology component that is to be embedded into the Editor. That means that even though there are implementations for the CellEditors on the UI layer, the actual components which will provide the functionality for editing the data are implemented on the technology layer. A short refresher:</p>
<p style="text-align: center"><a href="https://blog.sibvisions.com/wp-content/uploads/2016/12/layers.png" rel="lightbox[7560]"><img src="https://blog.sibvisions.com/wp-content/uploads/2016/12/layers.png" alt="The different layers of JVx." width="500" style="border: 1px solid #cccccc" /></a></p>
<p>Revisiting our simple screen from above, we'd actually need to represent it as something like this:</p>
<p style="text-align: center"><a href="https://blog.sibvisions.com/wp-content/uploads/2018/01/celleditors3.png" rel="lightbox[7560]"><img src="https://blog.sibvisions.com/wp-content/uploads/2018/01/celleditors3.png" alt="FormLayout with one added component." width="500" style="border: 1px solid #cccccc" /></a></p>
<p>Because the embedded components in the Editor are actually on the technology layer.</p>
<h3 style="padding-top: 10px">CellRenderers</h3>
<p>There is another small topic we need to discuss, CellRenderers. They follow nearly the same schematics as CellEditors but are used to display values directly, for example values in a table cell. The Table is also the primary component which uses them to display the cell values until the editing is started. For simplicity reasons, most CellEditors implement ICellRenderer directly and provide management of the created component. That is because the reuse of components for barely displaying values is easier does not contain as much error potential.</p>
<h3 style="padding-top: 10px">Conclusion</h3>
<p>CellEditors provide an easy mechanic to allow to edit data, and more important, they are decoupled from the GUI code in which they are used in a way which allows the model to change, even dynamically. That enables programmers to create and edit screens and models quickly without the need to check if the GUI and the model fit together, they always do.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.sibvisions.com/2018/01/05/jvx-reference-celleditors/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Let&#039;s experiment, reducing code in screens and lifecycle objects.</title>
		<link>https://blog.sibvisions.com/2018/01/03/experiment-less-code/</link>
		<comments>https://blog.sibvisions.com/2018/01/03/experiment-less-code/#comments</comments>
		<pubDate>Wed, 03 Jan 2018 14:11:26 +0000</pubDate>
		<dc:creator>rzenz</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[JVx]]></category>

		<guid isPermaLink="false">https://blog.sibvisions.com/?p=7563</guid>
		<description><![CDATA[Let's do a small experiment, and see if we can reduce the code required in screens and lifecycle objects to a minimum.
But be advised, this blog post is meant as a food for thoughts and less as a practical manual on doing things. So we will explore different possibilities which might not be practical.
Starting point
We [...]]]></description>
			<content:encoded><![CDATA[<p>Let's do a small experiment, and see if we can reduce the code required in screens and lifecycle objects to a minimum.</p>
<p>But be advised, this blog post is meant as a food for thoughts and less as a practical manual on doing things. So we will explore different possibilities which might not be practical.</p>
<h3 style="padding-top: 10px">Starting point</h3>
<p>We will start with a small screen which has been automatically generated by <a href="https://visionx.sibvisions.com">VisionX</a>, but has (manually) been stripped of all comments, documentation, imports and has some formatting modifications to make it easier readable in this post.</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="kw1">public</span> <span class="kw1">class</span> PeopleWorkScreen <span class="kw1">extends</span> DataSourceWorkScreen</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIEditor editPeopleFirstName <span class="sy0">=</span> <span class="kw1">new</span> UIEditor<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIEditor editPeopleLastName <span class="sy0">=</span> <span class="kw1">new</span> UIEditor<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIEditor editPeopleDateOfBirth <span class="sy0">=</span> <span class="kw1">new</span> UIEditor<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIEditor editPeopleOccupation <span class="sy0">=</span> <span class="kw1">new</span> UIEditor<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UILabel labelFirstName <span class="sy0">=</span> <span class="kw1">new</span> UILabel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UILabel labelLastName <span class="sy0">=</span> <span class="kw1">new</span> UILabel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UILabel labelDateofBirth <span class="sy0">=</span> <span class="kw1">new</span> UILabel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UILabel labelOccupation <span class="sy0">=</span> <span class="kw1">new</span> UILabel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIFormLayout formLayout1 <span class="sy0">=</span> <span class="kw1">new</span> UIFormLayout<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIGroupPanel groupPanelPeople <span class="sy0">=</span> <span class="kw1">new</span> UIGroupPanel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> NavigationTable tablePeople <span class="sy0">=</span> <span class="kw1">new</span> NavigationTable<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIPanel splitPanelMainFirst <span class="sy0">=</span> <span class="kw1">new</span> UIPanel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIPanel splitPanelMainSecond <span class="sy0">=</span> <span class="kw1">new</span> UIPanel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UISplitPanel splitPanelMain <span class="sy0">=</span> <span class="kw1">new</span> UISplitPanel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIBorderLayout borderLayout1 <span class="sy0">=</span> <span class="kw1">new</span> UIBorderLayout<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIBorderLayout borderLayout2 <span class="sy0">=</span> <span class="kw1">new</span> UIBorderLayout<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIBorderLayout borderLayout3 <span class="sy0">=</span> <span class="kw1">new</span> UIBorderLayout<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> RemoteDataBook rdbPeople <span class="sy0">=</span> <span class="kw1">new</span> RemoteDataBook<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">public</span> PeopleWorkScreen<span class="br0">&#40;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IWorkScreenApplication pApplication,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AbstractConnection pConnection,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">Map</span> pParameter<span class="br0">&#41;</span> <span class="kw1">throws</span> <span class="kw3">Throwable</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">super</span><span class="br0">&#40;</span>pApplication, pConnection, pParameter<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; initializeModel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; initializeUI<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> <span class="kw4">void</span> initializeModel<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="kw1">throws</span> <span class="kw3">Throwable</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; rdbPeople.<span class="me1">setName</span><span class="br0">&#40;</span><span class="st0">&quot;people&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; rdbPeople.<span class="me1">setDataSource</span><span class="br0">&#40;</span>getDataSource<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; rdbPeople.<span class="me1">open</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> <span class="kw4">void</span> initializeUI<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="kw1">throws</span> <span class="kw3">Throwable</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; tablePeople.<span class="me1">setMaximumSize</span><span class="br0">&#40;</span><span class="kw1">new</span> UIDimension<span class="br0">&#40;</span>450, 350<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; tablePeople.<span class="me1">setDataBook</span><span class="br0">&#40;</span>rdbPeople<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; tablePeople.<span class="me1">setAutoResize</span><span class="br0">&#40;</span><span class="kw2">false</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; labelFirstName.<span class="me1">setText</span><span class="br0">&#40;</span><span class="st0">&quot;First Name&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; labelLastName.<span class="me1">setText</span><span class="br0">&#40;</span><span class="st0">&quot;Last Name&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; labelDateofBirth.<span class="me1">setText</span><span class="br0">&#40;</span><span class="st0">&quot;Date of Birth&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; labelOccupation.<span class="me1">setText</span><span class="br0">&#40;</span><span class="st0">&quot;Occupation&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; editPeopleFirstName.<span class="me1">setDataRow</span><span class="br0">&#40;</span>rdbPeople<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; editPeopleFirstName.<span class="me1">setColumnName</span><span class="br0">&#40;</span><span class="st0">&quot;FIRST_NAME&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; editPeopleLastName.<span class="me1">setDataRow</span><span class="br0">&#40;</span>rdbPeople<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; editPeopleLastName.<span class="me1">setColumnName</span><span class="br0">&#40;</span><span class="st0">&quot;LAST_NAME&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; editPeopleDateOfBirth.<span class="me1">setDataRow</span><span class="br0">&#40;</span>rdbPeople<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; editPeopleDateOfBirth.<span class="me1">setColumnName</span><span class="br0">&#40;</span><span class="st0">&quot;DATE_OF_BIRTH&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; editPeopleOccupation.<span class="me1">setDataRow</span><span class="br0">&#40;</span>rdbPeople<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; editPeopleOccupation.<span class="me1">setColumnName</span><span class="br0">&#40;</span><span class="st0">&quot;OCCUPATION&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; splitPanelMainFirst.<span class="me1">setLayout</span><span class="br0">&#40;</span>borderLayout2<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; splitPanelMainFirst.<span class="me1">add</span><span class="br0">&#40;</span>tablePeople, UIBorderLayout.<span class="me1">CENTER</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">setText</span><span class="br0">&#40;</span><span class="st0">&quot;People&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">setLayout</span><span class="br0">&#40;</span>formLayout1<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span>labelFirstName, formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>0, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span>editPeopleFirstName, formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>1, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span>labelLastName, formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>2, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span>editPeopleLastName, formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>3, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span>labelDateofBirth, formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>0, 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span>editPeopleDateOfBirth, formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>1, 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span>labelOccupation, formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>2, 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span>editPeopleOccupation, formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>3, 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; splitPanelMainSecond.<span class="me1">setLayout</span><span class="br0">&#40;</span>borderLayout3<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; splitPanelMainSecond.<span class="me1">add</span><span class="br0">&#40;</span>groupPanelPeople, UIBorderLayout.<span class="me1">CENTER</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; splitPanelMain.<span class="me1">add</span><span class="br0">&#40;</span>splitPanelMainFirst, UISplitPanel.<span class="me1">FIRST_COMPONENT</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; splitPanelMain.<span class="me1">add</span><span class="br0">&#40;</span>splitPanelMainSecond, UISplitPanel.<span class="me1">SECOND_COMPONENT</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; setLayout<span class="br0">&#40;</span>borderLayout1<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; add<span class="br0">&#40;</span>splitPanelMain, UIBorderLayout.<span class="me1">CENTER</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
</div>
<p>This is the <strong>PeopleWorkScreen</strong> class. It really doesn't do much except containing a Split panel, having on the left a table and on the right a few editors. That does look quite manageable, also it does look as one would expect in the GUI.</p>
<p style="text-align: center"><a href="https://blog.sibvisions.com/wp-content/uploads/2017/12/less-code-screen.png" rel="lightbox[7563]"><img src="https://blog.sibvisions.com/wp-content/uploads/2017/12/less-code-screen.png" alt="The screen we are going to use as demonstration." width="400" style="border: 1px solid #cccccc" /></a></p>
<p>But it is a very good starting point for our experiments. As an additional note, we will lose <a href="https://visionx.sibvisions.com">VisionX</a> support with all the changes we will make, unfortunately, that can't be circumvented I'm afraid.</p>
<h3 style="padding-top: 10px">Annotations for editors</h3>
<p>The first thought one has when it comes to reducing code is to use Annotations to deliver important information. We can do this here, too, to remove some setup from the editors and instead add it to a more central place. So we will create a new Annotation which is holding the required information for the editors, which are the name of the databook and the name of the column.</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2">@Retention<span class="br0">&#40;</span>RUNTIME<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">@Target<span class="br0">&#40;</span>FIELD<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="kw1">public</span> @<span class="kw1">interface</span> DataBound</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw3">String</span> dataBookName<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw3">String</span> columnName<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
</div>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="kw1">public</span> <span class="kw1">class</span> PeopleWorkScreen <span class="kw1">extends</span> DataSourceWorkScreen</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; @DataBound<span class="br0">&#40;</span>dataBookName <span class="sy0">=</span> <span class="st0">&quot;people&quot;</span>, columnName <span class="sy0">=</span> <span class="st0">&quot;FIRST_NAME&quot;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIEditor editPeopleFirstName <span class="sy0">=</span> <span class="kw1">new</span> UIEditor<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; @DataBound<span class="br0">&#40;</span>dataBookName <span class="sy0">=</span> <span class="st0">&quot;people&quot;</span>, columnName <span class="sy0">=</span> <span class="st0">&quot;LAST_NAME&quot;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIEditor editPeopleLastName <span class="sy0">=</span> <span class="kw1">new</span> UIEditor<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; @DataBound<span class="br0">&#40;</span>dataBookName <span class="sy0">=</span> <span class="st0">&quot;people&quot;</span>, columnName <span class="sy0">=</span> <span class="st0">&quot;DATE_OF_BIRTH&quot;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIEditor editPeopleDateOfBirth <span class="sy0">=</span> <span class="kw1">new</span> UIEditor<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; @DataBound<span class="br0">&#40;</span>dataBookName <span class="sy0">=</span> <span class="st0">&quot;people&quot;</span>, columnName <span class="sy0">=</span> <span class="st0">&quot;OCCUPATION&quot;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIEditor editPeopleOccupation <span class="sy0">=</span> <span class="kw1">new</span> UIEditor<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UILabel labelFirstName <span class="sy0">=</span> <span class="kw1">new</span> UILabel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UILabel labelLastName <span class="sy0">=</span> <span class="kw1">new</span> UILabel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UILabel labelDateofBirth <span class="sy0">=</span> <span class="kw1">new</span> UILabel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UILabel labelOccupation <span class="sy0">=</span> <span class="kw1">new</span> UILabel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIFormLayout formLayout1 <span class="sy0">=</span> <span class="kw1">new</span> UIFormLayout<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIGroupPanel groupPanelPeople <span class="sy0">=</span> <span class="kw1">new</span> UIGroupPanel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> NavigationTable tablePeople <span class="sy0">=</span> <span class="kw1">new</span> NavigationTable<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIPanel splitPanelMainFirst <span class="sy0">=</span> <span class="kw1">new</span> UIPanel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIPanel splitPanelMainSecond <span class="sy0">=</span> <span class="kw1">new</span> UIPanel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UISplitPanel splitPanelMain <span class="sy0">=</span> <span class="kw1">new</span> UISplitPanel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIBorderLayout borderLayout1 <span class="sy0">=</span> <span class="kw1">new</span> UIBorderLayout<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIBorderLayout borderLayout2 <span class="sy0">=</span> <span class="kw1">new</span> UIBorderLayout<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIBorderLayout borderLayout3 <span class="sy0">=</span> <span class="kw1">new</span> UIBorderLayout<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> RemoteDataBook rdbPeople <span class="sy0">=</span> <span class="kw1">new</span> RemoteDataBook<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">public</span> PeopleWorkScreen<span class="br0">&#40;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IWorkScreenApplication pApplication,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AbstractConnection pConnection,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">Map</span> pParameter<span class="br0">&#41;</span> <span class="kw1">throws</span> <span class="kw3">Throwable</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">super</span><span class="br0">&#40;</span>pApplication, pConnection, pParameter<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; initializeModel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; initializeUI<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> <span class="kw4">void</span> initializeModel<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="kw1">throws</span> <span class="kw3">Throwable</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; rdbPeople.<span class="me1">setName</span><span class="br0">&#40;</span><span class="st0">&quot;people&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; rdbPeople.<span class="me1">setDataSource</span><span class="br0">&#40;</span>getDataSource<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; rdbPeople.<span class="me1">open</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> <span class="kw4">void</span> initializeUI<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="kw1">throws</span> <span class="kw3">Throwable</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; tablePeople.<span class="me1">setMaximumSize</span><span class="br0">&#40;</span><span class="kw1">new</span> UIDimension<span class="br0">&#40;</span>450, 350<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; tablePeople.<span class="me1">setDataBook</span><span class="br0">&#40;</span>rdbPeople<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; tablePeople.<span class="me1">setAutoResize</span><span class="br0">&#40;</span><span class="kw2">false</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; labelFirstName.<span class="me1">setText</span><span class="br0">&#40;</span><span class="st0">&quot;First Name&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; labelLastName.<span class="me1">setText</span><span class="br0">&#40;</span><span class="st0">&quot;Last Name&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; labelDateofBirth.<span class="me1">setText</span><span class="br0">&#40;</span><span class="st0">&quot;Date of Birth&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; labelOccupation.<span class="me1">setText</span><span class="br0">&#40;</span><span class="st0">&quot;Occupation&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; splitPanelMainFirst.<span class="me1">setLayout</span><span class="br0">&#40;</span>borderLayout2<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; splitPanelMainFirst.<span class="me1">add</span><span class="br0">&#40;</span>tablePeople, UIBorderLayout.<span class="me1">CENTER</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">setText</span><span class="br0">&#40;</span><span class="st0">&quot;People&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">setLayout</span><span class="br0">&#40;</span>formLayout1<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span>labelFirstName, formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>0, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span>editPeopleFirstName, formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>1, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span>labelLastName, formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>2, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span>editPeopleLastName, formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>3, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span>labelDateofBirth, formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>0, 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span>editPeopleDateOfBirth, formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>1, 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span>labelOccupation, formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>2, 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span>editPeopleOccupation, formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>3, 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; splitPanelMainSecond.<span class="me1">setLayout</span><span class="br0">&#40;</span>borderLayout3<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; splitPanelMainSecond.<span class="me1">add</span><span class="br0">&#40;</span>groupPanelPeople, UIBorderLayout.<span class="me1">CENTER</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; splitPanelMain.<span class="me1">add</span><span class="br0">&#40;</span>splitPanelMainFirst, UISplitPanel.<span class="me1">FIRST_COMPONENT</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; splitPanelMain.<span class="me1">add</span><span class="br0">&#40;</span>splitPanelMainSecond, UISplitPanel.<span class="me1">SECOND_COMPONENT</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; setLayout<span class="br0">&#40;</span>borderLayout1<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; add<span class="br0">&#40;</span>splitPanelMain, UIBorderLayout.<span class="me1">CENTER</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
</div>
<p>As one can see, we've annotated the fields with our new Annotation and removed the setup lines from the initializeUI() function. Of course, that alone does nothing, we must add the processing of the annotations somewhere. The best place would be in the application when the workscreen is opened.</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="kw1">public</span> <span class="kw1">class</span> AnnotationAwareApplication <span class="kw1">extends</span> ProjX</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">public</span> AnnotationAwareApplication<span class="br0">&#40;</span>UILauncher pLauncher<span class="br0">&#41;</span> <span class="kw1">throws</span> <span class="kw3">Throwable</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">super</span><span class="br0">&#40;</span>pLauncher<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; @Override</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw1">synchronized</span> IWorkScreen openWorkScreen<span class="br0">&#40;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">String</span> pClassName,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Modality pModality,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AbstractConnection pConnection,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">Map</span> pParameters,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">boolean</span> pSingleInstance<span class="br0">&#41;</span> <span class="kw1">throws</span> <span class="kw3">Throwable</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; DataSourceWorkScreen workScreen <span class="sy0">=</span> <span class="br0">&#40;</span>DataSourceWorkScreen<span class="br0">&#41;</span><span class="kw1">super</span>.<span class="me1">openWorkScreen</span><span class="br0">&#40;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pClassName,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pModality,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pConnection,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pParameters,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pSingleInstance<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw3">Field</span> field <span class="sy0">:</span> workScreen.<span class="me1">getClass</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">getDeclaredFields</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DataBound dataBound <span class="sy0">=</span> field.<span class="me1">getAnnotation</span><span class="br0">&#40;</span>DataBound.<span class="kw1">class</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>dataBound <span class="sy0">!=</span> <span class="kw2">null</span> <span class="sy0">&amp;&amp;</span> IEditor.<span class="kw1">class</span>.<span class="me1">isAssignableFrom</span><span class="br0">&#40;</span>field.<span class="me1">getType</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IDataBook dataBook <span class="sy0">=</span> workScreen.<span class="me1">getDataSource</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="me1">getDataBook</span><span class="br0">&#40;</span>dataBound.<span class="me1">dataBookName</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">String</span> columnName <span class="sy0">=</span> dataBound.<span class="me1">columnName</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; field.<span class="me1">setAccessible</span><span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IEditor editor <span class="sy0">=</span> <span class="br0">&#40;</span>IEditor<span class="br0">&#41;</span>field.<span class="me1">get</span><span class="br0">&#40;</span>workScreen<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editor.<span class="me1">setDataRow</span><span class="br0">&#40;</span>dataBook<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editor.<span class="me1">setColumnName</span><span class="br0">&#40;</span>columnName<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> workScreen<span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
</div>
<p>Easy enough, it removes some lines from the screen and the logic added inside the application is straightforward.</p>
<p>The upside is that we now have the information of the data binding right there in the field declaration, the downside is that it doesn't save us that much. In theory the gain is only 1 line per editor. We could do better than that.</p>
<h3 style="padding-top: 10px">Automatic editors</h3>
<p>Annotations are interesting, but don't fit well here. We could do better when we extend the UIEditor itself and fit it with the necessary logic to be able to find its data binding on its own. That means that it would need to go upward at some point and find its parent workscreen to retrieve the datasource (which holds all the databooks). Walking upwards in the hierarchy is straightforward, the question is when we should do that? The best point in time would be when addNotify() is being called, because at that point the GUI is being created, so we are very, very likely inside the initializeUI() function of the workscreen or at a later point.</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="kw1">public</span> <span class="kw1">class</span> AutomaticEditor <span class="kw1">extends</span> UIEditor</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> <span class="kw3">String</span> dataBookName <span class="sy0">=</span> <span class="kw2">null</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> <span class="kw3">String</span> columnName <span class="sy0">=</span> <span class="kw2">null</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">public</span> AutomaticEditor<span class="br0">&#40;</span><span class="kw3">String</span> pDataBookName, <span class="kw3">String</span> pColumnName<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">super</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; dataBookName <span class="sy0">=</span> pDataBookName<span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; columnName <span class="sy0">=</span> pColumnName<span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; @Override</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">void</span> addNotify<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; DataSourceWorkScreen workScreen <span class="sy0">=</span> getParentWorkScreen<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">try</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setDataRow<span class="br0">&#40;</span>workScreen.<span class="me1">getDataSource</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">getDataBook</span><span class="br0">&#40;</span>dataBookName<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setColumnName<span class="br0">&#40;</span>columnName<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">catch</span> <span class="br0">&#40;</span>ModelException e<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ExceptionHandler.<span class="me1">raise</span><span class="br0">&#40;</span>e<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">super</span>.<span class="me1">addNotify</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> DataSourceWorkScreen getParentWorkScreen<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; IContainer parent <span class="sy0">=</span> getParent<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">while</span> <span class="br0">&#40;</span>parent <span class="sy0">!=</span> <span class="kw2">null</span> <span class="sy0">&amp;&amp;</span> <span class="sy0">!</span><span class="br0">&#40;</span>parent <span class="kw1">instanceof</span> DataSourceWorkScreen<span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; parent <span class="sy0">=</span> parent.<span class="me1">getParent</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="br0">&#40;</span>DataSourceWorkScreen<span class="br0">&#41;</span>parent<span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
</div>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="kw1">public</span> <span class="kw1">class</span> PeopleWorkScreen <span class="kw1">extends</span> DataSourceWorkScreen</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIEditor editPeopleFirstName<span class="sy0">=</span><span class="kw1">new</span> AutomaticEditor<span class="br0">&#40;</span><span class="st0">&quot;people&quot;</span>,<span class="st0">&quot;FIRST_NAME&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIEditor editPeopleLastName <span class="sy0">=</span> <span class="kw1">new</span> AutomaticEditor<span class="br0">&#40;</span><span class="st0">&quot;people&quot;</span>, <span class="st0">&quot;LAST_NAME&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIEditor editPeopleDoB <span class="sy0">=</span> <span class="kw1">new</span> AutomaticEditor<span class="br0">&#40;</span><span class="st0">&quot;people&quot;</span>, <span class="st0">&quot;DATE_OF_BIRTH&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIEditor editPeopleOccupation<span class="sy0">=</span><span class="kw1">new</span> AutomaticEditor<span class="br0">&#40;</span><span class="st0">&quot;people&quot;</span>,<span class="st0">&quot;OCCUPATION&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UILabel labelFirstName <span class="sy0">=</span> <span class="kw1">new</span> UILabel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UILabel labelLastName <span class="sy0">=</span> <span class="kw1">new</span> UILabel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UILabel labelDateofBirth <span class="sy0">=</span> <span class="kw1">new</span> UILabel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UILabel labelOccupation <span class="sy0">=</span> <span class="kw1">new</span> UILabel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIFormLayout formLayout1 <span class="sy0">=</span> <span class="kw1">new</span> UIFormLayout<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIGroupPanel groupPanelPeople <span class="sy0">=</span> <span class="kw1">new</span> UIGroupPanel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> NavigationTable tablePeople <span class="sy0">=</span> <span class="kw1">new</span> NavigationTable<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIPanel splitPanelMainFirst <span class="sy0">=</span> <span class="kw1">new</span> UIPanel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIPanel splitPanelMainSecond <span class="sy0">=</span> <span class="kw1">new</span> UIPanel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UISplitPanel splitPanelMain <span class="sy0">=</span> <span class="kw1">new</span> UISplitPanel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIBorderLayout borderLayout1 <span class="sy0">=</span> <span class="kw1">new</span> UIBorderLayout<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIBorderLayout borderLayout2 <span class="sy0">=</span> <span class="kw1">new</span> UIBorderLayout<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> UIBorderLayout borderLayout3 <span class="sy0">=</span> <span class="kw1">new</span> UIBorderLayout<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> RemoteDataBook rdbPeople <span class="sy0">=</span> <span class="kw1">new</span> RemoteDataBook<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">public</span> PeopleWorkScreen<span class="br0">&#40;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IWorkScreenApplication pApplication,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AbstractConnection pConnection,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">Map</span> pParameter<span class="br0">&#41;</span> <span class="kw1">throws</span> <span class="kw3">Throwable</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">super</span><span class="br0">&#40;</span>pApplication, pConnection, pParameter<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; initializeModel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; initializeUI<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> <span class="kw4">void</span> initializeModel<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="kw1">throws</span> <span class="kw3">Throwable</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; rdbPeople.<span class="me1">setName</span><span class="br0">&#40;</span><span class="st0">&quot;people&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; rdbPeople.<span class="me1">setDataSource</span><span class="br0">&#40;</span>getDataSource<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; rdbPeople.<span class="me1">open</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> <span class="kw4">void</span> initializeUI<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="kw1">throws</span> <span class="kw3">Throwable</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; tablePeople.<span class="me1">setMaximumSize</span><span class="br0">&#40;</span><span class="kw1">new</span> UIDimension<span class="br0">&#40;</span>450, 350<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; tablePeople.<span class="me1">setDataBook</span><span class="br0">&#40;</span>rdbPeople<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; tablePeople.<span class="me1">setAutoResize</span><span class="br0">&#40;</span><span class="kw2">false</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; labelFirstName.<span class="me1">setText</span><span class="br0">&#40;</span><span class="st0">&quot;First Name&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; labelLastName.<span class="me1">setText</span><span class="br0">&#40;</span><span class="st0">&quot;Last Name&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; labelDateofBirth.<span class="me1">setText</span><span class="br0">&#40;</span><span class="st0">&quot;Date of Birth&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; labelOccupation.<span class="me1">setText</span><span class="br0">&#40;</span><span class="st0">&quot;Occupation&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; splitPanelMainFirst.<span class="me1">setLayout</span><span class="br0">&#40;</span>borderLayout2<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; splitPanelMainFirst.<span class="me1">add</span><span class="br0">&#40;</span>tablePeople, UIBorderLayout.<span class="me1">CENTER</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">setText</span><span class="br0">&#40;</span><span class="st0">&quot;People&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">setLayout</span><span class="br0">&#40;</span>formLayout1<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span>labelFirstName, formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>0, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span>editPeopleFirstName, formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>1, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span>labelLastName, formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>2, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span>editPeopleLastName, formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>3, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span>labelDateofBirth, formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>0, 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span>editPeopleDoB, formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>1, 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span>labelOccupation, formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>2, 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span>editPeopleOccupation, formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>3, 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; splitPanelMainSecond.<span class="me1">setLayout</span><span class="br0">&#40;</span>borderLayout3<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; splitPanelMainSecond.<span class="me1">add</span><span class="br0">&#40;</span>groupPanelPeople, UIBorderLayout.<span class="me1">CENTER</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; splitPanelMain.<span class="me1">add</span><span class="br0">&#40;</span>splitPanelMainFirst, UISplitPanel.<span class="me1">FIRST_COMPONENT</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; splitPanelMain.<span class="me1">add</span><span class="br0">&#40;</span>splitPanelMainSecond, UISplitPanel.<span class="me1">SECOND_COMPONENT</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; setLayout<span class="br0">&#40;</span>borderLayout1<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; add<span class="br0">&#40;</span>splitPanelMain, UIBorderLayout.<span class="me1">CENTER</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
</div>
<p>That removes the complete setup of the editor from the code, with the exception of the constructor, and instead the editor itself manages its own setup, neat. So I think we can't lose any more of the editor associated code at this point, the only further possibility would be to associate a "default" databook with the workscreen so that we can scrap the databook name from the constructor. Or, we could scan the fields of the screen and build the editors based on their name, but that is a rather fragile approach.</p>
<h3 style="padding-top: 10px">Inline fields</h3>
<p>While we are at it and we will lose <a href="https://visionx.sibvisions.com">VisionX</a> support anyway, we can inline the fields directly into the initializeUI() function to shed more lines.</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="kw1">public</span> <span class="kw1">class</span> PeopleWorkScreen <span class="kw1">extends</span> DataSourceWorkScreen</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> RemoteDataBook rdbPeople <span class="sy0">=</span> <span class="kw1">new</span> RemoteDataBook<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">public</span> PeopleWorkScreen<span class="br0">&#40;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IWorkScreenApplication pApplication,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AbstractConnection pConnection,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">Map</span> pParameter<span class="br0">&#41;</span> <span class="kw1">throws</span> <span class="kw3">Throwable</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">super</span><span class="br0">&#40;</span>pApplication, pConnection, pParameter<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; initializeModel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; initializeUI<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> <span class="kw4">void</span> initializeModel<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="kw1">throws</span> <span class="kw3">Throwable</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; rdbPeople.<span class="me1">setName</span><span class="br0">&#40;</span><span class="st0">&quot;people&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; rdbPeople.<span class="me1">setDataSource</span><span class="br0">&#40;</span>getDataSource<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; rdbPeople.<span class="me1">open</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> <span class="kw4">void</span> initializeUI<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="kw1">throws</span> <span class="kw3">Throwable</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; NavigationTable tablePeople <span class="sy0">=</span> <span class="kw1">new</span> NavigationTable<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; tablePeople.<span class="me1">setMaximumSize</span><span class="br0">&#40;</span><span class="kw1">new</span> UIDimension<span class="br0">&#40;</span>450, 350<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; tablePeople.<span class="me1">setDataBook</span><span class="br0">&#40;</span>rdbPeople<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; tablePeople.<span class="me1">setAutoResize</span><span class="br0">&#40;</span><span class="kw2">false</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; UIPanel splitPanelMainFirst <span class="sy0">=</span> <span class="kw1">new</span> UIPanel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; splitPanelMainFirst.<span class="me1">setLayout</span><span class="br0">&#40;</span><span class="kw1">new</span> UIBorderLayout<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; splitPanelMainFirst.<span class="me1">add</span><span class="br0">&#40;</span>tablePeople, UIBorderLayout.<span class="me1">CENTER</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; UIFormLayout formLayout1 <span class="sy0">=</span> <span class="kw1">new</span> UIFormLayout<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; UIGroupPanel groupPanelPeople <span class="sy0">=</span> <span class="kw1">new</span> UIGroupPanel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">setText</span><span class="br0">&#40;</span><span class="st0">&quot;People&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">setLayout</span><span class="br0">&#40;</span>formLayout1<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span><span class="kw1">new</span> UILabel<span class="br0">&#40;</span><span class="st0">&quot;First Name&quot;</span><span class="br0">&#41;</span>, </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>0, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span><span class="kw1">new</span> AutomaticEditor<span class="br0">&#40;</span><span class="st0">&quot;people&quot;</span>, <span class="st0">&quot;FIRST_NAME&quot;</span><span class="br0">&#41;</span>, </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>1, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span><span class="kw1">new</span> UILabel<span class="br0">&#40;</span><span class="st0">&quot;Last Name&quot;</span><span class="br0">&#41;</span>, </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>2, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span><span class="kw1">new</span> AutomaticEditor<span class="br0">&#40;</span><span class="st0">&quot;people&quot;</span>, <span class="st0">&quot;LAST_NAME&quot;</span><span class="br0">&#41;</span>, </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>3, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span><span class="kw1">new</span> UILabel<span class="br0">&#40;</span><span class="st0">&quot;Date of Birth&quot;</span><span class="br0">&#41;</span>, </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>0, 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span><span class="kw1">new</span> AutomaticEditor<span class="br0">&#40;</span><span class="st0">&quot;people&quot;</span>, <span class="st0">&quot;DATE_OF_BIRTH&quot;</span><span class="br0">&#41;</span>, </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>1, 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span><span class="kw1">new</span> UILabel<span class="br0">&#40;</span><span class="st0">&quot;Occupation&quot;</span><span class="br0">&#41;</span>, </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>2, 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span><span class="kw1">new</span> AutomaticEditor<span class="br0">&#40;</span><span class="st0">&quot;people&quot;</span>, <span class="st0">&quot;OCCUPATION&quot;</span><span class="br0">&#41;</span>, </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>3, 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; UIPanel splitPanelMainSecond <span class="sy0">=</span> <span class="kw1">new</span> UIPanel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; splitPanelMainSecond.<span class="me1">setLayout</span><span class="br0">&#40;</span><span class="kw1">new</span> UIBorderLayout<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; splitPanelMainSecond.<span class="me1">add</span><span class="br0">&#40;</span>groupPanelPeople, UIBorderLayout.<span class="me1">CENTER</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; UISplitPanel splitPanelMain <span class="sy0">=</span> <span class="kw1">new</span> UISplitPanel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; splitPanelMain.<span class="me1">add</span><span class="br0">&#40;</span>splitPanelMainFirst, UISplitPanel.<span class="me1">FIRST_COMPONENT</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; splitPanelMain.<span class="me1">add</span><span class="br0">&#40;</span>splitPanelMainSecond, UISplitPanel.<span class="me1">SECOND_COMPONENT</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; setLayout<span class="br0">&#40;</span><span class="kw1">new</span> UIBorderLayout<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; add<span class="br0">&#40;</span>splitPanelMain, UIBorderLayout.<span class="me1">CENTER</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
</div>
<p>That makes the code harder to read but in the end it saves a lot of lines.</p>
<h3 style="padding-top: 10px">Automatic databooks</h3>
<p>Now the only part of the screen which we can now reduce is the model part. This is a little more complicated, though. First, if we create a databook on the fly it's a little bit more complicated to get it customized, so we have to assume that we can use the databooks "as they are", with all the necessary setup being done on the server side (which is ideal anyway). Second, ideally we could let the connection create the databooks as they are needed, that is a little bit more complicated and for this example we will add that logic to the screen instead. So the <strong>PeopleWorkScreen</strong> gains the method getDataBook(String) which gets or creates a databook for the given name and returns it.</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="kw1">public</span> <span class="kw1">class</span> PeopleWorkScreen <span class="kw1">extends</span> DataSourceWorkScreen</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">public</span> PeopleWorkScreen<span class="br0">&#40;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IWorkScreenApplication pApplication,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AbstractConnection pConnection,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">Map</span> pParameter<span class="br0">&#41;</span> <span class="kw1">throws</span> <span class="kw3">Throwable</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">super</span><span class="br0">&#40;</span>pApplication, pConnection, pParameter<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; initializeUI<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> <span class="kw4">void</span> initializeUI<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="kw1">throws</span> <span class="kw3">Throwable</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; NavigationTable tablePeople <span class="sy0">=</span> <span class="kw1">new</span> NavigationTable<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; tablePeople.<span class="me1">setMaximumSize</span><span class="br0">&#40;</span><span class="kw1">new</span> UIDimension<span class="br0">&#40;</span>450, 350<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; tablePeople.<span class="me1">setDataBook</span><span class="br0">&#40;</span>getDataBook<span class="br0">&#40;</span><span class="st0">&quot;people&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; tablePeople.<span class="me1">setAutoResize</span><span class="br0">&#40;</span><span class="kw2">false</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; UIPanel splitPanelMainFirst <span class="sy0">=</span> <span class="kw1">new</span> UIPanel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; splitPanelMainFirst.<span class="me1">setLayout</span><span class="br0">&#40;</span><span class="kw1">new</span> UIBorderLayout<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; splitPanelMainFirst.<span class="me1">add</span><span class="br0">&#40;</span>tablePeople, UIBorderLayout.<span class="me1">CENTER</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; UIFormLayout formLayout1 <span class="sy0">=</span> <span class="kw1">new</span> UIFormLayout<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; UIGroupPanel groupPanelPeople <span class="sy0">=</span> <span class="kw1">new</span> UIGroupPanel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">setText</span><span class="br0">&#40;</span><span class="st0">&quot;People&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">setLayout</span><span class="br0">&#40;</span>formLayout1<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span><span class="kw1">new</span> UILabel<span class="br0">&#40;</span><span class="st0">&quot;First Name&quot;</span><span class="br0">&#41;</span>, </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>0, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span><span class="kw1">new</span> AutomaticEditor<span class="br0">&#40;</span><span class="st0">&quot;people&quot;</span>, <span class="st0">&quot;FIRST_NAME&quot;</span><span class="br0">&#41;</span>, </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>1, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span><span class="kw1">new</span> UILabel<span class="br0">&#40;</span><span class="st0">&quot;Last Name&quot;</span><span class="br0">&#41;</span>, </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>2, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span><span class="kw1">new</span> AutomaticEditor<span class="br0">&#40;</span><span class="st0">&quot;people&quot;</span>, <span class="st0">&quot;LAST_NAME&quot;</span><span class="br0">&#41;</span>, </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>3, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span><span class="kw1">new</span> UILabel<span class="br0">&#40;</span><span class="st0">&quot;Date of Birth&quot;</span><span class="br0">&#41;</span>, </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>0, 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span><span class="kw1">new</span> AutomaticEditor<span class="br0">&#40;</span><span class="st0">&quot;people&quot;</span>, <span class="st0">&quot;DATE_OF_BIRTH&quot;</span><span class="br0">&#41;</span>, </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>1, 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span><span class="kw1">new</span> UILabel<span class="br0">&#40;</span><span class="st0">&quot;Occupation&quot;</span><span class="br0">&#41;</span>, </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>2, 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; groupPanelPeople.<span class="me1">add</span><span class="br0">&#40;</span><span class="kw1">new</span> AutomaticEditor<span class="br0">&#40;</span><span class="st0">&quot;people&quot;</span>, <span class="st0">&quot;OCCUPATION&quot;</span><span class="br0">&#41;</span>, </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;formLayout1.<span class="me1">getConstraints</span><span class="br0">&#40;</span>3, 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; UIPanel splitPanelMainSecond <span class="sy0">=</span> <span class="kw1">new</span> UIPanel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; splitPanelMainSecond.<span class="me1">setLayout</span><span class="br0">&#40;</span><span class="kw1">new</span> UIBorderLayout<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; splitPanelMainSecond.<span class="me1">add</span><span class="br0">&#40;</span>groupPanelPeople, UIBorderLayout.<span class="me1">CENTER</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; UISplitPanel splitPanelMain <span class="sy0">=</span> <span class="kw1">new</span> UISplitPanel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; splitPanelMain.<span class="me1">add</span><span class="br0">&#40;</span>splitPanelMainFirst, UISplitPanel.<span class="me1">FIRST_COMPONENT</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; splitPanelMain.<span class="me1">add</span><span class="br0">&#40;</span>splitPanelMainSecond, UISplitPanel.<span class="me1">SECOND_COMPONENT</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; setLayout<span class="br0">&#40;</span><span class="kw1">new</span> UIBorderLayout<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; add<span class="br0">&#40;</span>splitPanelMain, UIBorderLayout.<span class="me1">CENTER</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">public</span> IDataBook getDataBook<span class="br0">&#40;</span><span class="kw3">String</span> pDataBookName<span class="br0">&#41;</span> <span class="kw1">throws</span> ModelException</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; IDataBook dataBook <span class="sy0">=</span> getDataSource<span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">getDataBook</span><span class="br0">&#40;</span>pDataBookName<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>dataBook <span class="sy0">==</span> <span class="kw2">null</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dataBook <span class="sy0">=</span> <span class="kw1">new</span> RemoteDataBook<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dataBook.<span class="me1">setName</span><span class="br0">&#40;</span>pDataBookName<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dataBook.<span class="me1">setDataSource</span><span class="br0">&#40;</span>getDataSource<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dataBook.<span class="me1">open</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> dataBook<span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
</div>
<p>and the changed editor</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="kw1">public</span> <span class="kw1">class</span> AutomaticEditor <span class="kw1">extends</span> UIEditor</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> <span class="kw3">String</span> dataBookName <span class="sy0">=</span> <span class="kw2">null</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> <span class="kw3">String</span> columnName <span class="sy0">=</span> <span class="kw2">null</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">public</span> AutomaticEditor<span class="br0">&#40;</span><span class="kw3">String</span> pDataBookName, <span class="kw3">String</span> pColumnName<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">super</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; dataBookName <span class="sy0">=</span> pDataBookName<span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; columnName <span class="sy0">=</span> pColumnName<span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; @Override</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">void</span> addNotify<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; PeopleWorkScreen workScreen <span class="sy0">=</span> getParentWorkScreen<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">try</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setDataRow<span class="br0">&#40;</span>workScreen.<span class="me1">getDataBook</span><span class="br0">&#40;</span>dataBookName<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setColumnName<span class="br0">&#40;</span>columnName<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">catch</span> <span class="br0">&#40;</span>ModelException e<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ExceptionHandler.<span class="me1">raise</span><span class="br0">&#40;</span>e<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">super</span>.<span class="me1">addNotify</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> PeopleWorkScreen getParentWorkScreen<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; IContainer parent <span class="sy0">=</span> getParent<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">while</span> <span class="br0">&#40;</span>parent <span class="sy0">!=</span> <span class="kw2">null</span> <span class="sy0">&amp;&amp;</span> <span class="sy0">!</span><span class="br0">&#40;</span>parent <span class="kw1">instanceof</span> PeopleWorkScreen<span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; parent <span class="sy0">=</span> parent.<span class="me1">getParent</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="br0">&#40;</span>PeopleWorkScreen<span class="br0">&#41;</span>parent<span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
</div>
<p>This introduces a quite unhealthy coupling between the <strong>PeopleWorkScreen</strong> and the <strong>AutomaticEditor</strong>, we can live with that for this example, but in a real application we'd have to correctly structure these objects. For example by introducing a workscreen base class, or by actually extending the datasource to provide this functionality.</p>
<p>If we ingore the method we just introduced in the <strong>PeopleWorkScreen</strong>, we actually managed to reduce the screen class a great deal and removed code which can be automated. That means that, at least theoretically, the likelihood of errors as we write the code has been lowered and it has become easier to write error free code. We can also now see that the screen class has become quite minimal, there really isn't anything left that we could restructure or remove.</p>
<h3 style="padding-top: 10px">Lifecycle objects</h3>
<p>Now let us jump to the server and have a look at the associated lifecycle object.</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="kw1">public</span> <span class="kw1">class</span> People <span class="kw1">extends</span> Session</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">public</span> DBStorage getPeople<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="kw1">throws</span> <span class="kw3">Exception</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; DBStorage dbsPeople <span class="sy0">=</span> <span class="br0">&#40;</span>DBStorage<span class="br0">&#41;</span>get<span class="br0">&#40;</span><span class="st0">&quot;people&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>dbsPeople <span class="sy0">==</span> <span class="kw2">null</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dbsPeople <span class="sy0">=</span> <span class="kw1">new</span> DBStorage<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dbsPeople.<span class="me1">setWritebackTable</span><span class="br0">&#40;</span><span class="st0">&quot;PEOPLE&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dbsPeople.<span class="me1">setDBAccess</span><span class="br0">&#40;</span>getDBAccess<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dbsPeople.<span class="me1">open</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; put<span class="br0">&#40;</span><span class="st0">&quot;people&quot;</span>, dbsPeople<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> dbsPeople<span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span> &nbsp; </div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
</div>
<p>There isn't much here that we can do, but a few small things might make it easier to write in the future. Again, we will be losing <a href="https://visionx.sibvisions.com">VisionX</a> support if we edit this "too much", but we are far beyond that point anyway.</p>
<h3 style="padding-top: 10px">Reducing error potential</h3>
<p>What can happen easily with managing storages is that one does copy and paste code and misses to edit the key, under which the storage is stored, correctly. That can happen quickly especially if there is a complex object hierarchy in place. So what we can do is separating the storing logic from the creation logic.</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="kw1">public</span> <span class="kw1">class</span> People <span class="kw1">extends</span> Session</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">public</span> DBStorage getPeople<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="kw1">throws</span> <span class="kw3">Exception</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> getOrCreateStorage<span class="br0">&#40;</span><span class="st0">&quot;people&quot;</span>, <span class="br0">&#40;</span>storage<span class="br0">&#41;</span> <span class="sy0">-&gt;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; storage.<span class="me1">setWritebackTable</span><span class="br0">&#40;</span><span class="st0">&quot;PEOPLE&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">protected</span> DBStorage getOrCreateStorage<span class="br0">&#40;</span><span class="kw3">String</span> pName, Consumer pStorageConfigurer<span class="br0">&#41;</span> </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">throws</span> <span class="kw3">Exception</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; DBStorage storage <span class="sy0">=</span> <span class="br0">&#40;</span>DBStorage<span class="br0">&#41;</span>get<span class="br0">&#40;</span>pName<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>storage <span class="sy0">==</span> <span class="kw2">null</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; storage <span class="sy0">=</span> <span class="kw1">new</span> DBStorage<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; storage.<span class="me1">setDBAccess</span><span class="br0">&#40;</span>getDBAccess<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pStorageConfigurer.<span class="me1">accept</span><span class="br0">&#40;</span>storage<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span>storage.<span class="me1">isOpen</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; storage.<span class="me1">open</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; put<span class="br0">&#40;</span>pName, storage<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> storage<span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
</div>
<p>This has the upside that it would reduce the error potential greatly, especially with a lot of storages, and it would allow us to add additional safety checks, for example if a storage with that name is already existing and would be overridden. But it has the downside that with each access a new lambda function is created, that might or might not be important for your use case.</p>
<p>If we try to mitigate this side effect we will quickly reach certain limits, for example if we change the process to a registry based approach we will find that we've again introduced the very thing we wanted to remove. The storage configurer must be registered at the registry with a name and the storage must be received with a name, so we'd be back at square one, actually.</p>
<h3 style="padding-top: 10px">A more dynamic approach</h3>
<p>To get rid of this duplication of the name we could create a registry with the configurers and use a generic approach to retrieving it. The problem here is that that is not possible at compile time, so what we need would actually be a system that catches non-matched calls for storages in the client/server connection and redirects it to our generic method. That is unfortunately not trivial and I will only outline this approach here now.</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="kw1">public</span> <span class="kw1">class</span> People <span class="kw1">extends</span> Session</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> Map<span class="sy0">&lt;</span>String, Consumer<span class="sy0">&gt;</span> registeredStorages <span class="sy0">=</span> <span class="kw1">new</span> <span class="kw3">HashMap</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">public</span> People<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">super</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; registerStorage<span class="br0">&#40;</span><span class="st0">&quot;people&quot;</span>, <span class="br0">&#40;</span>storage<span class="br0">&#41;</span> <span class="sy0">-&gt;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; storage.<span class="me1">setWritebackTable</span><span class="br0">&#40;</span><span class="st0">&quot;PEOPLE&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">protected</span> DBStorage getOrCreateStorage<span class="br0">&#40;</span><span class="kw3">String</span> pName<span class="br0">&#41;</span> <span class="kw1">throws</span> <span class="kw3">Exception</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; DBStorage storage <span class="sy0">=</span> <span class="br0">&#40;</span>DBStorage<span class="br0">&#41;</span>get<span class="br0">&#40;</span>pName<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>storage <span class="sy0">==</span> <span class="kw2">null</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; storage <span class="sy0">=</span> <span class="kw1">new</span> DBStorage<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; storage.<span class="me1">setDBAccess</span><span class="br0">&#40;</span>getDBAccess<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; registeredStorages.<span class="me1">get</span><span class="br0">&#40;</span>pName<span class="br0">&#41;</span>.<span class="me1">accept</span><span class="br0">&#40;</span>storage<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span>storage.<span class="me1">isOpen</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; storage.<span class="me1">open</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; put<span class="br0">&#40;</span>pName, storage<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> storage<span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">protected</span> <span class="kw4">void</span> registerStorage<span class="br0">&#40;</span><span class="kw3">String</span> pName, Consumer pStorageConfigurer<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; registeredStorages.<span class="me1">put</span><span class="br0">&#40;</span>pName, pStorageConfigurer<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span> </div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
</div>
<p>Now all that is missing would be that the connection is calling our getOrCreateStorage(String) method with the name of the requested object. Of course there is also a lot of error checking missing here, but that is not relevant for our example.</p>
<p>And again, if we remove the additional code we added, because it should be contained inside a base class, we have managed to reduce the code on the server side significantly. From here going any further becomes complicated, for example, again, one might to work with Annotations but that won't save us anything here anymore.</p>
<h3 style="padding-top: 10px">Conclusion</h3>
<p>From time to time it is necessary to let the thoughts drift and think about different things, for example how to reduce the code inside of classes which are automatically generated and managed. Once I had a nice discussion with someone online on how to do things differently in their library. We had a little back and forth on what could be done and in the end we agreed that it should stay the way it was because none of the approaches we came up with had a significant advantage over the current state. In the end they said that, even though nothing came of it, it was an important discussion to have because from time to time one had to engage in such stimulated, technical and theoretical discussions, and I agree completely with that. It is important to be open to new ideas and consider different approaches even when they don't end up taken.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.sibvisions.com/2018/01/03/experiment-less-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JVx Reference, the FormLayout</title>
		<link>https://blog.sibvisions.com/2017/11/15/jvx-reference-the-formlayout/</link>
		<comments>https://blog.sibvisions.com/2017/11/15/jvx-reference-the-formlayout/#comments</comments>
		<pubDate>Wed, 15 Nov 2017 09:42:23 +0000</pubDate>
		<dc:creator>rzenz</dc:creator>
				<category><![CDATA[API]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[JVx]]></category>
		<category><![CDATA[JVx Reference]]></category>

		<guid isPermaLink="false">https://blog.sibvisions.com/?p=7334</guid>
		<description><![CDATA[Let's talk about the FormLayout, and why the anchor system makes it much more flexible than just a simple grid.
Basics
JVx comes with 5 layouts by default:

null/none/manual
BorderLayout
FlowLayout
GridLayout
FormLayout

From these five the first four are easily explained, only the FormLayout needs some more information because it might not be as easy to grasp in the first moment than [...]]]></description>
			<content:encoded><![CDATA[<p>Let's talk about the <a href="http://forum.sibvisions.com/viewtopic.php?f=11&amp;t=167&amp;p=219">FormLayout</a>, and why the anchor system makes it much more flexible than just a simple grid.</p>
<h3 style="padding-top: 10px">Basics</h3>
<p>JVx comes with 5 layouts by default:</p>
<ul>
<li>null/none/manual</li>
<li>BorderLayout</li>
<li>FlowLayout</li>
<li>GridLayout</li>
<li>FormLayout</li>
</ul>
<p>From these five the first four are easily explained, only the FormLayout needs some more information because it might not be as easy to grasp in the first moment than the others.</p>
<p>The FormLayout uses a dependent anchor system. An Anchor in this context is a position inside the layout which is calculated from parent anchors and either the size of the component or a fixed value. So we can say there are two different types of Anchors inside the FormLayout which we are concerned about:</p>
<ul>
<li><strong>AutoSize-Anchors</strong>, its position is calculated from the component assigned to it.</li>
<li><strong>Fixed-Anchors</strong>, its position is fixed.</li>
</ul>
<p>Additionally, there are three special cases of Fixed-Anchors:</p>
<ul>
<li><strong>Border-Anchors</strong>, which surround the FormLayout at its border.</li>
<li><strong>Margin-Anchors</strong>, which are inset from the border by the defined value.</li>
<li><strong>Gap-Anchors</strong>, which are added to create a gap between components.</li>
</ul>
<p>When it comes to calculating the position of an anchor, the position of the parent anchor is determined and then the value of the current anchor is added (which is either the size of a component or a fixed value). Simplified and in pseudo-code it can expressed like this:</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="kw1">public</span> <span class="kw4">int</span> getPosition<span class="br0">&#40;</span>Anchor pAnchor<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw4">int</span> parentPosition <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>pAnchor.<span class="me1">getParent</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">!=</span> <span class="kw2">null</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; parentPosition <span class="sy0">=</span> getPosition<span class="br0">&#40;</span>pAnchor.<span class="me1">getParent</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>pAnchor.<span class="me1">isAutoSize</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> parentPosition <span class="sy0">+</span> pAnchor.<span class="me1">getComponent</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">getWidth</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">else</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> parentPosition <span class="sy0">+</span> pAnchor.<span class="me1">getValue</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
</div>
<p>With this knowledge, we are nearly done with completely understanding the FormLayout.</p>
<h3 style="padding-top: 10px">Creating constraints</h3>
<p>Now, the second important part after the basics is knowing how the constraints are created. For example this:</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component, layout.<span class="me1">getConstraints</span><span class="br0">&#40;</span>0, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
</ol>
</div>
</div>
<p style="text-align: center"><a href="https://blog.sibvisions.com/wp-content/uploads/2017/11/formlayout-1.png" rel="lightbox[7334]"><img src="https://blog.sibvisions.com/wp-content/uploads/2017/11/formlayout-1.png" alt="FormLayout with one added component." width="500" style="border: 1px solid #cccccc" /></a></p>
<p>With the coordinates of 0,0, no new anchors are created but instead the component is attached to the top and left margin anchor. Two new AutoSize-Anchors (horizontally and vertically) are created and attached to the component.</p>
<p>If we now add a second component in the same row:</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component, layout.<span class="me1">getConstraints</span><span class="br0">&#40;</span>0, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component, layout.<span class="me1">getConstraints</span><span class="br0">&#40;</span>1, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
</ol>
</div>
</div>
<p style="text-align: center"><a href="https://blog.sibvisions.com/wp-content/uploads/2017/11/formlayout-2.png" rel="lightbox[7334]"><img src="https://blog.sibvisions.com/wp-content/uploads/2017/11/formlayout-2.png" alt="FormLayout with two added components." width="500" style="border: 1px solid #cccccc" /></a></p>
<p>Because we are still on row 0 the component is attached to the top margin anchor and the previous AutoSize-Anchor for this row. Then, a new Gap-Anchor will be created which is attached to the trailing AutoSize-Anchor of the previous component.</p>
<p>We can of course also add items to the right and bottom:</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component, layout.<span class="me1">getConstraints</span><span class="br0">&#40;</span>0, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component, layout.<span class="me1">getConstraints</span><span class="br0">&#40;</span>1, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component, layout.<span class="me1">getConstraints</span><span class="br0">&#40;</span><span class="sy0">-</span>1, <span class="sy0">-</span>1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
</ol>
</div>
</div>
<p style="text-align: center"><a href="https://blog.sibvisions.com/wp-content/uploads/2017/11/formlayout-3.png" rel="lightbox[7334]"><img src="https://blog.sibvisions.com/wp-content/uploads/2017/11/formlayout-3.png" alt="FormLayout with three added components, one in the bottom right corner." width="500" style="border: 1px solid #cccccc" /></a></p>
<p>What happens is the same as when adding a component at the coordinates 0,0, except that the reference is the lower right corner. The component is attached to the bottom and right margin anchors, with trialing AutoSize-Anchors.</p>
<p>Last but not least, we can add components which span between anchors:</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component, layout.<span class="me1">getConstraints</span><span class="br0">&#40;</span>0, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component, layout.<span class="me1">getConstraints</span><span class="br0">&#40;</span>1, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component, layout.<span class="me1">getConstraints</span><span class="br0">&#40;</span><span class="sy0">-</span>1, <span class="sy0">-</span>1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component, layout.<span class="me1">getConstraints</span><span class="br0">&#40;</span>2, 1, <span class="sy0">-</span>2, <span class="sy0">-</span>2<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
</ol>
</div>
</div>
<p style="text-align: center"><a href="https://blog.sibvisions.com/wp-content/uploads/2017/11/formlayout-4.png" rel="lightbox[7334]"><img src="https://blog.sibvisions.com/wp-content/uploads/2017/11/formlayout-4.png" alt="FormLayout with four added components, one stretched." width="500" style="border: 1px solid #cccccc" /></a></p>
<p>Again, the same logic applies as previously, with the notable exception that new Gap-Anchors are created for all four sides. That includes variants which span over anchors:</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component, layout.<span class="me1">getConstraints</span><span class="br0">&#40;</span>0, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component, layout.<span class="me1">getConstraints</span><span class="br0">&#40;</span>1, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component, layout.<span class="me1">getConstraints</span><span class="br0">&#40;</span>0, 1, 2, 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
</ol>
</div>
</div>
<p style="text-align: center"><a href="https://blog.sibvisions.com/wp-content/uploads/2017/11/formlayout-5.png" rel="lightbox[7334]"><img src="https://blog.sibvisions.com/wp-content/uploads/2017/11/formlayout-5.png" alt="FormLayout with three added components, one of them spans multiple anchors." width="500" style="border: 1px solid #cccccc" /></a></p>
<p>The component is horizontally attached to the left Margin-Anchor and additionally to the AutoSize-Anchor of the second column. The AutoSize- and Gap-Anchor of the first column are not ignored, they are not relevant to this case.</p>
<p>At this point it is important to note that spanning and stretched components are disregarded for the preferred size calculation of the layout. So whenever you span or stretch a component, it is not taken into account when the preferred size of the layout is calculated, which can lead to unexpected results.</p>
<h3 style="padding-top: 10px">Interactive demo</h3>
<p>Sometimes, however, it might not be obvious what anchors are created and how they are used. For this we have created a simple interactive demonstration application which allows to inspect the created anchors of a layout, the <a href="https://github.com/sibvisions/jvx.formlayout-visualization">JVx FormLayout Visualization</a>.</p>
<p style="text-align: center"><a href="https://blog.sibvisions.com/wp-content/uploads/2017/11/formlayout-visualization.png" rel="lightbox[7334]"><img src="https://blog.sibvisions.com/wp-content/uploads/2017/11/formlayout-visualization.png" alt="FormLayout Visualization Demo" width="400" style="border: 1px solid #cccccc" /></a></p>
<p>On the left is the possibility to show and hide anchors together with the information about the currently highlighted anchor. On the right is a Lua scripting area which allows you to quickly and easily rebuild and test layouts. It utilizes the <a href="https://blog.sibvisions.com/2017/09/25/jvx-lua-proof-of-concept/">JVx-Lua bridge from a previous blog post</a> and so any changes to the code are directly applied.</p>
<h3 style="padding-top: 10px">The most simple usage: Flow-like</h3>
<p>Enough of the internals, let's talk use-cases. The most simple use-case for the FormLayout can be a container which flows its contents in a line until a certain number of items is reach, at which it breaks into a new line:</p>
<div class="tab-me-wrapper"><ul class="tab-me-tabs"><li class="active first"><a href="javascript:void(0)" rel="tab1834"><span>Java</span></a></li><li><a href="javascript:void(0)" rel="tab1782"><span>Lua (Demo Application)</span></a></li></ul><!-- .tab-me-tabs --><div class="tab-me-content-wrapper"><div class="tab-me-tab-content" id="tab1834" ><div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2">layout.<span class="me1">setNewlineCount</span><span class="br0">&#40;</span>3<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
</ol>
</div>
</div>
<p></div><div class="tab-me-tab-content" id="tab1782" style="display:none"></p>
<div class="codesnip-container" >
<div class="lua codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2">layout:setNewlineCount<span class="br0">&#40;</span>3<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">panel:add<span class="br0">&#40;</span>stub<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel:add<span class="br0">&#40;</span>stub<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel:add<span class="br0">&#40;</span>stub<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel:add<span class="br0">&#40;</span>stub<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel:add<span class="br0">&#40;</span>stub<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel:add<span class="br0">&#40;</span>stub<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel:add<span class="br0">&#40;</span>stub<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
</ol>
</div>
</div>
<p></div></div></div><!-- .tabs-wrapper --></p>
<p style="text-align: center"><a href="https://blog.sibvisions.com/wp-content/uploads/2017/11/formlayout-flow.png" rel="lightbox[7334]"><img src="https://blog.sibvisions.com/wp-content/uploads/2017/11/formlayout-flow.png" alt="FormLayout with a flow layout" width="400" style="border: 1px solid #cccccc" /></a></p>
<p>It does not require any interaction from us except adding components. In this case, when three components have been added, the next one will be added to the next line and so on. This is quite useful when all you want to do is display components in a fixed horizontal grid.</p>
<h3 style="padding-top: 10px">The obvious usage: Grid-like</h3>
<p>The FormLayout can also be used to align components in a grid, and actually layout them in a grid-like fashion:</p>
<div class="tab-me-wrapper"><ul class="tab-me-tabs"><li class="active first"><a href="javascript:void(0)" rel="tab1221"><span>Java</span></a></li><li><a href="javascript:void(0)" rel="tab1498"><span>Lua (Demo Application)</span></a></li></ul><!-- .tab-me-tabs --><div class="tab-me-content-wrapper"><div class="tab-me-tab-content" id="tab1221" ><div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component, layout.<span class="me1">getConstraints</span><span class="br0">&#40;</span>0, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component, layout.<span class="me1">getConstraints</span><span class="br0">&#40;</span>1, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component, layout.<span class="me1">getConstraints</span><span class="br0">&#40;</span>2, 0, <span class="sy0">-</span>2, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component, layout.<span class="me1">getConstraints</span><span class="br0">&#40;</span><span class="sy0">-</span>1, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component, layout.<span class="me1">getConstraints</span><span class="br0">&#40;</span>0, 1, 2, 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component, layout.<span class="me1">getConstraints</span><span class="br0">&#40;</span>3, 1, <span class="sy0">-</span>1, 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component, layout.<span class="me1">getConstraints</span><span class="br0">&#40;</span>0, 2, <span class="sy0">-</span>2, <span class="sy0">-</span>1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component, layout.<span class="me1">getConstraints</span><span class="br0">&#40;</span><span class="sy0">-</span>1, 2, <span class="sy0">-</span>1, <span class="sy0">-</span>1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
</ol>
</div>
</div>
<p></div><div class="tab-me-tab-content" id="tab1498" style="display:none"></p>
<div class="codesnip-container" >
<div class="lua codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2">panel:add<span class="br0">&#40;</span>stub<span class="br0">&#40;</span><span class="br0">&#41;</span>, layout:getConstraints<span class="br0">&#40;</span>0, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel:add<span class="br0">&#40;</span>stub<span class="br0">&#40;</span><span class="br0">&#41;</span>, layout:getConstraints<span class="br0">&#40;</span>1, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel:add<span class="br0">&#40;</span>stub<span class="br0">&#40;</span><span class="br0">&#41;</span>, layout:getConstraints<span class="br0">&#40;</span>2, 0, -2, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel:add<span class="br0">&#40;</span>stub<span class="br0">&#40;</span><span class="br0">&#41;</span>, layout:getConstraints<span class="br0">&#40;</span>-1, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">panel:add<span class="br0">&#40;</span>stub<span class="br0">&#40;</span><span class="br0">&#41;</span>, layout:getConstraints<span class="br0">&#40;</span>0, 1, 2, 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel:add<span class="br0">&#40;</span>stub<span class="br0">&#40;</span><span class="br0">&#41;</span>, layout:getConstraints<span class="br0">&#40;</span>3, 1, -1, 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">panel:add<span class="br0">&#40;</span>stub<span class="br0">&#40;</span><span class="br0">&#41;</span>, layout:getConstraints<span class="br0">&#40;</span>0, 2, -2, -1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel:add<span class="br0">&#40;</span>stub<span class="br0">&#40;</span><span class="br0">&#41;</span>, layout:getConstraints<span class="br0">&#40;</span>-1, 2, -1, -1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
</ol>
</div>
</div>
<p></div></div></div><!-- .tabs-wrapper --></p>
<p style="text-align: center"><a href="https://blog.sibvisions.com/wp-content/uploads/2017/11/formlayout-grid.png" rel="lightbox[7334]"><img src="https://blog.sibvisions.com/wp-content/uploads/2017/11/formlayout-grid.png" alt="FormLayout with a grid layout" width="400" style="border: 1px solid #cccccc" /></a></p>
<p>With the main difference being that the columns and rows are sized according to the components in it and not given a fixed slice of the width of the panel.</p>
<h3 style="padding-top: 10px">The advanced usage: Anchor Configuration</h3>
<p>Additionally, the FormLayout offers the possibility to manually set the anchor positions, for example when it is necessary to give the first elements a certain size:</p>
<div class="tab-me-wrapper"><ul class="tab-me-tabs"><li class="active first"><a href="javascript:void(0)" rel="tab1874"><span>Java</span></a></li><li><a href="javascript:void(0)" rel="tab1090"><span>Lua (Demo Application)</span></a></li></ul><!-- .tab-me-tabs --><div class="tab-me-content-wrapper"><div class="tab-me-tab-content" id="tab1874" ><div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component, layout.<span class="me1">getConstraints</span><span class="br0">&#40;</span>0, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component, layout.<span class="me1">getConstraints</span><span class="br0">&#40;</span>1, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component, layout.<span class="me1">getConstraints</span><span class="br0">&#40;</span>2, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component, layout.<span class="me1">getConstraints</span><span class="br0">&#40;</span>0, 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component, layout.<span class="me1">getConstraints</span><span class="br0">&#40;</span>1, 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component, layout.<span class="me1">getConstraints</span><span class="br0">&#40;</span>2, 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component, layout.<span class="me1">getConstraints</span><span class="br0">&#40;</span>0, 2<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component, layout.<span class="me1">getConstraints</span><span class="br0">&#40;</span>1, 2<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel.<span class="me1">add</span><span class="br0">&#40;</span>component, layout.<span class="me1">getConstraints</span><span class="br0">&#40;</span>2, 2<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">layout.<span class="me1">setAnchorConfiguration</span><span class="br0">&#40;</span><span class="st0">&quot;r0=64,r1=8,r2=128,b1=32&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
</ol>
</div>
</div>
<p></div><div class="tab-me-tab-content" id="tab1090" style="display:none"></p>
<div class="codesnip-container" >
<div class="lua codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2">panel:add<span class="br0">&#40;</span>stub<span class="br0">&#40;</span><span class="br0">&#41;</span>, layout:getConstraints<span class="br0">&#40;</span>0, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel:add<span class="br0">&#40;</span>stub<span class="br0">&#40;</span><span class="br0">&#41;</span>, layout:getConstraints<span class="br0">&#40;</span>1, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel:add<span class="br0">&#40;</span>stub<span class="br0">&#40;</span><span class="br0">&#41;</span>, layout:getConstraints<span class="br0">&#40;</span>2, 0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">panel:add<span class="br0">&#40;</span>stub<span class="br0">&#40;</span><span class="br0">&#41;</span>, layout:getConstraints<span class="br0">&#40;</span>0, 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel:add<span class="br0">&#40;</span>stub<span class="br0">&#40;</span><span class="br0">&#41;</span>, layout:getConstraints<span class="br0">&#40;</span>1, 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel:add<span class="br0">&#40;</span>stub<span class="br0">&#40;</span><span class="br0">&#41;</span>, layout:getConstraints<span class="br0">&#40;</span>2, 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">panel:add<span class="br0">&#40;</span>stub<span class="br0">&#40;</span><span class="br0">&#41;</span>, layout:getConstraints<span class="br0">&#40;</span>0, 2<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel:add<span class="br0">&#40;</span>stub<span class="br0">&#40;</span><span class="br0">&#41;</span>, layout:getConstraints<span class="br0">&#40;</span>1, 2<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">panel:add<span class="br0">&#40;</span>stub<span class="br0">&#40;</span><span class="br0">&#41;</span>, layout:getConstraints<span class="br0">&#40;</span>2, 2<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">layout:setAnchorConfiguration<span class="br0">&#40;</span><span class="st0">&quot;r0=64,r1=8,r2=128,b1=32&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
</ol>
</div>
</div>
<p></div></div></div><!-- .tabs-wrapper --></p>
<p>Together with the ability to span components, this allows to create complex and rich layouts.</p>
<p style="text-align: center"><a href="https://blog.sibvisions.com/wp-content/uploads/2017/11/formlayout-anchorconfiguration.png" rel="lightbox[7334]"><img src="https://blog.sibvisions.com/wp-content/uploads/2017/11/formlayout-anchorconfiguration.png" alt="FormLayout with a set anchor configuration" width="400" style="border: 1px solid #cccccc" /></a></p>
<h3 style="padding-top: 10px">Conclusion</h3>
<p>The JVx FormLayout allows to quickly and easily create complex, good looking and working layouts which are still flexible enough for the cases when a component is swapped, removed or added. It can be used in many different circumstances and is still easy enough to use to make sure that even beginners are able to create a basic layout within seconds.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.sibvisions.com/2017/11/15/jvx-reference-the-formlayout/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JVx Reference, Launchers and Applications</title>
		<link>https://blog.sibvisions.com/2017/09/28/jvx-reference-launchers-and-applications/</link>
		<comments>https://blog.sibvisions.com/2017/09/28/jvx-reference-launchers-and-applications/#comments</comments>
		<pubDate>Thu, 28 Sep 2017 15:57:38 +0000</pubDate>
		<dc:creator>rzenz</dc:creator>
				<category><![CDATA[API]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[JVx]]></category>
		<category><![CDATA[JVx Reference]]></category>

		<guid isPermaLink="false">https://blog.sibvisions.com/?p=6661</guid>
		<description><![CDATA[Let's talk about Launchers, and how they are used to start JVx applications.
Starting an application
We've previously outlined a simple way to start a JVx application, and now we're going to look at how to do it with a launcher to benefit from everything JVx has to offer. From a technical point of view, there are [...]]]></description>
			<content:encoded><![CDATA[<p>Let's talk about Launchers, and how they are used to start JVx applications.</p>
<h3 style="padding-top: 10px">Starting an application</h3>
<p>We've previously outlined <a href="https://blog.sibvisions.com/2017/04/24/jvx-reference-application-basics/">a simple way to start a JVx application</a>, and now we're going to look at how to do it with a launcher to benefit from everything JVx has to offer. From a technical point of view, there are two prerequisites which must be fulfilled before a JVx application can run:</p>
<ol>
<li>the JVM must have started.</li>
<li>the technology specific system must have started.</li>
</ol>
<p>Then, and only then, the JVx application can run. Depending on the implementation that is used, that can be as easily as instancing the factory (Swing, JavaFX), but can also mean that a servlet server has to start (Vaadin). Because we do not wish to encumber our applications with technology specific code, we have to entrust all this to an encapsulated entity, meaning the implementations of ILauncher and IApplication.</p>
<h3 style="padding-top: 10px">Following the chain</h3>
<p>The steps for getting an application to start are as follows:</p>
<ol>
<li>The first thing that must run is obviously the JVM, without it we won't have much luck starting anything.</li>
<li>The launcher must be created and it must start the Technology.</li>
<li>The launcher than creates the application which the user is seeing.</li>
</ol>
<p style="text-align: center"><a href="https://blog.sibvisions.com/wp-content/uploads/2017/09/launcher.png" rel="lightbox[6661]"><img src="https://blog.sibvisions.com/wp-content/uploads/2017/09/launcher.png" alt="Launcher chain" width="400" style="border: 1px solid #cccccc" /></a></p>
<p>So we need two classes, the ILauncher implementation which knows how to start the Technology and the IApplication implementation. That we already knew, so let's try to put this into code. For simplicity reasons (and because I don't want to write a complete factory from scratch for this example) we will reuse the Swing implementation and write a new launcher and application for it.</p>
<h3 style="padding-top: 10px">Entry point</h3>
<p>The Main class that we will use as example is very straightforward:</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="kw1">public</span> <span class="kw1">class</span> Main</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw1">static</span> <span class="kw4">void</span> main<span class="br0">&#40;</span><span class="kw3">String</span><span class="br0">&#91;</span><span class="br0">&#93;</span> pArgs<span class="br0">&#41;</span> </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// All we have to do here is kickoff the creation of the launcher.</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// The launcher will do everything that is required to start for us.</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// In a real world scenario and/or application there might be more</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// setup or groundwork required, for example processing the arguments,</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// but we don't need any of that here.</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">new</span> SwingLauncher<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
</div>
<p>All we have to do there is start the launcher itself. As the comment suggests, there might be work required for a "real" application startup. For this example, it is all we need to do. Of course <strong>we could also directly embed this little function</strong> into the launcher implementation itself, <strong>to save us one class</strong>.</p>
<h3 style="padding-top: 10px">The launcher</h3>
<p>The ILauncher implementation on the other hand contains quite some logic, but nothing not manageable:</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="kw1">public</span> <span class="kw1">class</span> SwingLauncher <span class="kw1">extends</span> SwingFrame </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">implements</span> ILauncher</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">// We have to extend from SwingFrame because there is no factory</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">// instantiated at that point, so we can't use UI components.</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> IApplication application<span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">public</span> SwingLauncher<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">super</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">try</span> </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">SwingUtilities</span>.<span class="me1">invokeAndWait</span><span class="br0">&#40;</span><span class="kw1">this</span><span class="sy0">::</span>startup<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">catch</span> <span class="br0">&#40;</span><span class="kw3">InvocationTargetException</span> <span class="sy0">|</span> <span class="kw3">InterruptedException</span> e<span class="br0">&#41;</span> </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.<span class="me1">printStackTrace</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; @Override</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">void</span> dispose<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">try</span> </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// We must notify the application that we are being disposed.</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; application.<span class="me1">notifyDestroy</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">catch</span> <span class="br0">&#40;</span><span class="kw3">SecurityException</span> e<span class="br0">&#41;</span> </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.<span class="me1">printStackTrace</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">super</span>.<span class="me1">dispose</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// We have to make sure that the application is exiting when</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// the frame is disposed of.</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">System</span>.<span class="me1">exit</span><span class="br0">&#40;</span>0<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> <span class="kw4">void</span> startup<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// We create a new SwingFactory and it is directly registered as global</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// instance, that means it will be used by all components which are</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// created from now on.</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; UIFactoryManager.<span class="me1">getFactoryInstance</span><span class="br0">&#40;</span>SwingFactory.<span class="kw1">class</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Also we set it as our factory instance.</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; setFactory<span class="br0">&#40;</span>UIFactoryManager.<span class="me1">getFactory</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Because the IApplication implementation we use is based upon</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// UI components (which is advisable) we have to wrap this launcher</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// in an UILauncher.</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; UILauncher uiLauncher <span class="sy0">=</span> <span class="kw1">new</span> UILauncher<span class="br0">&#40;</span><span class="kw1">this</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Now we create the main application.</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Note that the ExampleApplication is already based upon</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// UI components.</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; application <span class="sy0">=</span> <span class="kw1">new</span> ExampleApplication<span class="br0">&#40;</span>uiLauncher<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Then we add the application as content to the launcher.</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; uiLauncher.<span class="me1">add</span><span class="br0">&#40;</span>application<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Perform some setup work and start everything.</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; uiLauncher.<span class="me1">pack</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; uiLauncher.<span class="me1">setVisible</span><span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// We also have to notify the application itself.</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; application.<span class="me1">notifyVisible</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">// SNIP</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
</div>
<p>In short, the launcher is kicking off the Swing thread by invoking the startup method on the main Swing thread. This startup method will instantiate the factory and then create the application. From there we only need to set it visible and then our application has started.</p>
<p>The launcher extends from SwingFrame, that is required because there hasn't been a factory created yet which could be used by UI components to create themselves. If we'd try to use an UI component before creating/setting a factory, we would obviously see the constructor of the component fail with a NullPointerException.</p>
<p>The method startup() is invoked on the main Swing thread, which also happens to be the main UI thread for JVx in this application. Once we are on the main UI thread we can create the application, add it and then set everything to visible.</p>
<h3 style="padding-top: 10px">The application</h3>
<p>The IApplication implementation is quite short, because we extend com.sibvisions.rad.application.Application, an IApplication implementation created with UI components.</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="kw1">public</span> <span class="kw1">class</span> ExampleApplication <span class="kw1">extends</span> Application</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">public</span> ExampleApplication<span class="br0">&#40;</span>UILauncher pParamUILauncher<span class="br0">&#41;</span> </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">super</span><span class="br0">&#40;</span>pParamUILauncher<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; @Override</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">protected</span> IConnection createConnection<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="kw1">throws</span> <span class="kw3">Exception</span> </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Not required for this example.</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">null</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; @Override</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">protected</span> <span class="kw3">String</span> getApplicationName<span class="br0">&#40;</span><span class="br0">&#41;</span> </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="st0">&quot;Example Application&quot;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
</div>
<p>Because the launcher has previously started the technology and created the factory we can from here on now use UI components, which means we are already independent of the underlying technology. So the IApplication implementation can already be used with different technologies and is completely independent.</p>
<h3 style="padding-top: 10px">Notes on the launcher</h3>
<p>As you might have noticed, in our example the launcher is a (window) frame, that makes sense for nearly every desktop GUI toolkit as they all depend upon a window as main method to display their applications. But the launcher could also be simpler, for example just a call to start the GUI thread. Or it could be something completely different, for example an incoming HTTP request.</p>
<p>Also don't forget that the launcher is providing additional functionality to the application, like saving file handles, reading and writing the configuration and similar platform and toolkit dependent operations, see the <a href="https://sourceforge.net/p/jvx/code/HEAD/tree/trunk/java/swing/src/com/sibvisions/rad/ui/swing/impl/SwingApplication.java">launcher for Swing for further details</a>.</p>
<h3 style="padding-top: 10px">Conclusion</h3>
<p>This example demonstrates how a simple launcher is implemented and why it is necessary to have a launcher in the first place. Compared with the "just set the factory" method this seems like a lot of work, but the launchers used by JVx are of course a lot more complex than these examples, that is because they implement all the required functionality and also take care of a lot of boiler plate operations. It is taking care of all technology specific code and allows to keep your application free from knowing about the platform it runs on.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.sibvisions.com/2017/09/28/jvx-reference-launchers-and-applications/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JVx and Lua, a proof of concept</title>
		<link>https://blog.sibvisions.com/2017/09/25/jvx-lua-proof-of-concept/</link>
		<comments>https://blog.sibvisions.com/2017/09/25/jvx-lua-proof-of-concept/#comments</comments>
		<pubDate>Mon, 25 Sep 2017 19:57:03 +0000</pubDate>
		<dc:creator>rzenz</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[JVx]]></category>
		<category><![CDATA[Lua]]></category>

		<guid isPermaLink="false">https://blog.sibvisions.com/?p=7221</guid>
		<description><![CDATA[We've found the time to look at something that was floating around the office for quite some time. A few of us had previous experiences with Lua, a simple scripting language, but nothing too concrete and while doing a prototype a question popped up: Would it be easy to create a JVx GUI in Lua? [...]]]></description>
			<content:encoded><![CDATA[<p>We've found the time to look at something that was floating around the office for quite some time. A few of us had previous experiences with <a href="https://www.lua.org/">Lua</a>, a simple scripting language, but nothing too concrete and while doing a prototype a question popped up: Would it be easy to create a JVx GUI in Lua? As it turns out, the answer is "yes".</p>
<h3 style="padding-top: 10px">Lua, a short tour</h3>
<blockquote><p>Lua is a lightweight, multi-paradigm programming language designed primarily for embedded systems and clients.</p>
<p>Lua was originally designed in 1993 as a language for extending software applications to meet the increasing demand for customization at the time. It provided the basic facilities of most procedural programming languages, but more complicated or domain-specific features were not included; rather, it included mechanisms for extending the language, allowing programmers to implement such features. As Lua was intended to be a general embeddable extension language, the designers of Lua focused on improving its speed, portability, extensibility, and ease-of-use in development.</p></blockquote>
<p>That is what <a href="https://en.wikipedia.org/wiki/Lua_%28programming_language%29">Wikipedia</a> has to say about Lua, but personally I like to think about it as "Basic done right", no insults intended. Lua is easy to write, easy to read and allows to quickly write and edit scripts.  There are <a href="http://lua-users.org/wiki/LuaImplementations">quite a few implementations for different languages and systems available</a> which makes it very versatile and usable from in nearly every environment.</p>
<p>The most simple Lua script is one that prints "Hello World":</p>
<div class="codesnip-container" >
<div class="lua codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="kw1">print</span><span class="br0">&#40;</span><span class="st0">&quot;Hello World&quot;</span><span class="br0">&#41;</span></div>
</li>
</ol>
</div>
</div>
<p>Because it is a prototype based language, functions are first-class citizens, which can be easily created, passed around and invoked:</p>
<div class="codesnip-container" >
<div class="lua codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="kw1">local</span> <span class="kw1">call</span> <span class="sy0">=</span> <span class="kw1">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">print</span><span class="br0">&#40;</span><span class="st0">&quot;Hello World&quot;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="kw1">end</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2"><span class="kw1">call</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
</ol>
</div>
</div>
<p>Additionally, we can use tables to store state. They work like a simple key/value store:</p>
<div class="codesnip-container" >
<div class="lua codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="kw1">local</span> operation <span class="sy0">=</span> <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; method <span class="sy0">=</span> <span class="kw1">function</span><span class="br0">&#40;</span><span class="kw1">string</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span><span class="br0">&#40;</span><span class="kw1">string</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">end</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; value <span class="sy0">=</span> <span class="st0">&quot;Hello World&quot;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">operation.method<span class="br0">&#40;</span>operation.value<span class="br0">&#41;</span></div>
</li>
</ol>
</div>
</div>
<div class="codesnip-container" >
<div class="lua codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="kw1">local</span> operation <span class="sy0">=</span> <span class="br0">&#123;</span><span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">operation.method <span class="sy0">=</span> <span class="kw1">function</span><span class="br0">&#40;</span><span class="kw1">string</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">print</span><span class="br0">&#40;</span><span class="kw1">string</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="kw1">end</span></div>
</li>
<li class="li2">
<div class="de2">operation.value <span class="sy0">=</span> <span class="st0">&quot;Hello World&quot;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">operation.method<span class="br0">&#40;</span>operation.value<span class="br0">&#41;</span></div>
</li>
</ol>
</div>
</div>
<p>Additionally, with some syntactic sugar, we can even emulate "real" objects. This is done by using a colon for invoking functions, which means that the table on which the function is invoked from will be provided as first parameter:</p>
<div class="codesnip-container" >
<div class="lua codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="kw1">local</span> operation <span class="sy0">=</span> <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; method <span class="sy0">=</span> <span class="kw1">function</span><span class="br0">&#40;</span>valueContainer, <span class="kw1">string</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span><span class="br0">&#40;</span>valueContainer.value .. <span class="st0">&quot; &quot;</span> .. <span class="kw1">string</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">end</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; value <span class="sy0">=</span> <span class="st0">&quot;Hello World&quot;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">operation:method<span class="br0">&#40;</span><span class="st0">&quot;and others&quot;</span><span class="br0">&#41;</span></div>
</li>
</ol>
</div>
</div>
<p>Last but not least, the rules about "new lines" and "end of statements" are very relaxed in Lua, we can either write everything on one line or use semicolons as statement end:</p>
<div class="codesnip-container" >
<div class="lua codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="kw1">local</span> <span class="kw1">call</span> <span class="sy0">=</span> <span class="kw1">function</span><span class="br0">&#40;</span>value<span class="br0">&#41;</span> <span class="kw1">return</span> value + 5 <span class="kw1">end</span> <span class="kw1">print</span><span class="br0">&#40;</span><span class="kw1">call</span><span class="br0">&#40;</span>10<span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2"><span class="kw1">local</span> <span class="kw1">call</span> <span class="sy0">=</span> <span class="kw1">function</span><span class="br0">&#40;</span>value<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">return</span> value + <span class="nu0">5</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="kw1">end</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2"><span class="kw1">print</span><span class="br0">&#40;</span><span class="kw1">call</span><span class="br0">&#40;</span>10<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
</ol>
</div>
</div>
<p>But enough of the simple things, let's jump right to the case.</p>
<h3 style="padding-top: 10px">World, meet JVx.Lua</h3>
<p><a href="https://github.com/sibvisions/jvx.lua">JVx.Lua</a> is a proof of concept Java/Lua bridge, which allows to use the JVx classes in Lua scripts. Additionally, we've created a short demo application, <a href="https://github.com/sibvisions/jvx.lua-live">JVx.Lua Live</a>, which allows to directly write Lua code and see the output live in the application.</p>
<p style="text-align: center"><a href="https://blog.sibvisions.com/wp-content/uploads/2017/09/jvxlualive1.png" rel="lightbox[7221]"><img src="https://blog.sibvisions.com/wp-content/uploads/2017/09/jvxlualive1.png" alt="JVx/Lua live demo" width="400" style="border: 1px solid #cccccc" /></a></p>
<p>The example code should be self-explanatory and the API is as close to the Java one as is possible. If an exception is thrown by the Lua environment it will be displayed in the live preview.</p>
<p style="text-align: center"><a href="https://blog.sibvisions.com/wp-content/uploads/2017/09/jvxlualive2.png" rel="lightbox[7221]"><img src="https://blog.sibvisions.com/wp-content/uploads/2017/09/jvxlualive2.png" alt="JVx/Lua live demo" width="400" style="border: 1px solid #cccccc" /></a></p>
<p>This allows to quickly test out the Lua bindings and create a simple GUI in no time. But note that this simple demo application does not store what you've created, when you close it, it will be gone.</p>
<h3 style="padding-top: 10px">How does it work?</h3>
<p>Glad you asked! The demo application is, of course, a simple GUI build with JVx, there are two core components which make it possible:</p>
<ol>
<li><a href="https://github.com/bobbylight/RSyntaxTextArea">RSyntaxTextArea</a>, a Swing component for displaying and editing code.</li>
<li><a href="http://www.luaj.org/luaj.html">LuaJ</a>, a Lua interpreter and compiler which allows to compile Lua directly to Java bytecode.</li>
</ol>
<p><a href="https://github.com/bobbylight/RSyntaxTextArea">RSyntaxTextArea</a> does not need to be further explained, it just works, and working very well it does. So does <a href="http://www.luaj.org/luaj.html">LuaJ</a>, but that one has to be explained.</p>
<p>To create a new "Lua environment" one has to instance a new set of Globals and install the Lua-to-Lua-Bytecode and Lua-Bytecode-to-Java-Bytecode compilers into it.</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2">Globals globals <span class="sy0">=</span> <span class="kw1">new</span> Globals<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">LuaC.<span class="me1">install</span><span class="br0">&#40;</span>globals<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">LuaJC.<span class="me1">install</span><span class="br0">&#40;</span>globals<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">globals.<span class="me1">load</span><span class="br0">&#40;</span><span class="st0">&quot;print(<span class="es0">\&quot;</span>Hello World<span class="es0">\&quot;</span>)&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
</ol>
</div>
</div>
<p>And that's it! With this we can already execute Lua code directly in Java, and most importantly, at runtime.</p>
<p>By default, LuaJ does provide <em>nothing</em> for the Lua environment, which means that it is sandboxed by default. If we want to add functionality and libraries, we'll have to load it into the Globals as so called "libs". For example if we want to provide all functions which can be found inside the <a href="http://lua-users.org/wiki/StringLibraryTutorial">string table</a>, we'll have to load the StringLib:</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2">Globals globals <span class="sy0">=</span> <span class="kw1">new</span> Globals<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">LuaC.<span class="me1">install</span><span class="br0">&#40;</span>globals<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">LuaJC.<span class="me1">install</span><span class="br0">&#40;</span>globals<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">globals.<span class="me1">load</span><span class="br0">&#40;</span><span class="kw1">new</span> StringLib<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">globals.<span class="me1">load</span><span class="br0">&#40;</span><span class="st0">&quot;print(string.sub(<span class="es0">\&quot;</span>Hello World<span class="es0">\&quot;</span>, 7))&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
</ol>
</div>
</div>
<p>There are multiple libs provided with LuaJ which contain the standard library functions of Lua or provide access directly into the Java environment. For example we can coerce Java objects directly into Lua ones:</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="kw3">BigDecimal</span> value <span class="sy0">=</span> <span class="kw1">new</span> <span class="kw3">BigDecimal</span><span class="br0">&#40;</span><span class="st0">&quot;-5.1234&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">globals.<span class="me1">set</span><span class="br0">&#40;</span><span class="st0">&quot;value&quot;</span>, CoerceJavaToLua.<span class="me1">coerce</span><span class="br0">&#40;</span>value<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
</ol>
</div>
</div>
<div class="codesnip-container" >
<div class="lua codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="kw1">local</span> absoluteValue <span class="sy0">=</span> value:<span class="kw1">abs</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="kw1">local</span> squaredValue <span class="sy0">=</span> absoluteValue:pow<span class="br0">&#40;</span>2<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2"><span class="kw1">print</span><span class="br0">&#40;</span>squaredValue:toString<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
</ol>
</div>
</div>
<p>Which gives us all the power of Java at our fingertips in Lua.</p>
<h3 style="padding-top: 10px">JVx bindings for Lua</h3>
<p>Armed with that knowledge, we can have a look at the bindings which make it possible to use the JVx classes. JVxLib and LuaUtil are the main classes which coerce a single class to be used by Lua, the procedure looks as follows:</p>
<ol>
<li>Create a LuaTable to hold the class and register it globally.</li>
<li>Add all public static fields (constants) to it.</li>
<li>Add all static methods to it.</li>
<li>Add a single constructor with a vararg argument to it.</li>
</ol>
<p>The most interesting point is the constructor call, we simply register a method called "new" on the table and give it a vararg argument, which means that it can be called with any number of arguments. When this function is invoked the arguments are processed and a fitting constructor for the object is chosen. The found constructor is invoked and the created object is coerced to a Lua object, that created Lua object is returned.</p>
<p>This allows us to use a clean syntax when it comes to accessing the static or instance state of the objects. Static methods and constants, including constructors, are always accessed using the "dot" notation, while everything related to the instance is accessed using the "colon" notation.</p>
<h3 style="padding-top: 10px">Downside, binding events</h3>
<p>For events and event handlers we had to dig a little deeper into LuaJ. The main problem with our EventHandler is that it has two methods: addListener(L) and addListener(IRunnable), at runtime the first one is reduced to addListener(Object). Let's assume the following code:</p>
<div class="codesnip-container" >
<div class="lua codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2">button:eventAction<span class="br0">&#40;</span><span class="br0">&#41;</span>:addListener<span class="br0">&#40;</span>listener<span class="br0">&#41;</span></div>
</li>
</ol>
</div>
</div>
<p>With such a construct LuaJ had a hard time finding the correct overload to use even when listener was a coerced IRunnable. This turned out to be undefined behavior, because the order of methods returned by a class object during runtime is undefined, sometimes LuaJ would choose the correct method and all other times it would use the addListener(Object) method. Which had "interesting" side effects, obviously, because an IRunnable object ended up in a list which should only hold objects of type L.</p>
<p>We've added a workaround so that functions with no parameters can be easily used, but for "full blown listener" support we'd have to invest quite some time. Which we might do at some point, but currently this is alright for a proof of concept.</p>
<h3 style="padding-top: 10px">Conclusion</h3>
<p>Using Lua from Java is easy thanks to <a href="http://www.luaj.org/luaj.html">LuaJ</a>, another possible option is <a href="https://github.com/mjanicek/rembulan/">Rembulan</a>, which can not go unmentioned when one talks about Java and Lua. It does not only allow to quickly and easily write logic, but with the right bindings one can even create complete GUIs and applications in it and thanks to the ability to compile it directly to Java bytecode it is nearly as fast as the Java code. But, with the big upside that it can be easily changed at runtime, even by users.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.sibvisions.com/2017/09/25/jvx-lua-proof-of-concept/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Vaadin, let&#039;s hack the Profiler</title>
		<link>https://blog.sibvisions.com/2017/09/11/vaadin-hack-the-profiler/</link>
		<comments>https://blog.sibvisions.com/2017/09/11/vaadin-hack-the-profiler/#comments</comments>
		<pubDate>Mon, 11 Sep 2017 09:00:30 +0000</pubDate>
		<dc:creator>rzenz</dc:creator>
				<category><![CDATA[Information]]></category>
		<category><![CDATA[Vaadin]]></category>

		<guid isPermaLink="false">https://blog.sibvisions.com/?p=7155</guid>
		<description><![CDATA[Vaadin comes with a builtin Profiler which is only available during debug mode, which might not be available or reasonable. So, let us see if we can use it without the debug mode enabled.
It has a profiler?
Yes, there is one right builtin on the client side. You can activate it easily enough by adding the [...]]]></description>
			<content:encoded><![CDATA[<p>Vaadin comes with a builtin Profiler which is only available during debug mode, which might not be available or reasonable. So, let us see if we can use it without the debug mode enabled.</p>
<h3 style="padding-top: 10px">It has a profiler?</h3>
<p>Yes, there is one right builtin on the client side. You can activate it easily enough by adding the following to the widgetset:</p>
<div class="codesnip-container" >
<div class="xml codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="sc3"><span class="re1">&lt;set-property</span> <span class="re0">name</span>=<span class="st0">&quot;vaadin.profiler&quot;</span> <span class="re0">value</span>=<span class="st0">&quot;true&quot;</span> <span class="re2">/&gt;</span></span></div>
</li>
</ol>
</div>
</div>
<p>But to see the results, you also have to switch the application into debug mode by changing the web.xml to the following:</p>
<div class="codesnip-container" >
<div class="xml codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="sc3"><span class="re1">&lt;context-param<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;description<span class="re2">&gt;</span></span></span>Vaadin production mode<span class="sc3"><span class="re1">&lt;/description<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;param-name<span class="re2">&gt;</span></span></span>productionMode<span class="sc3"><span class="re1">&lt;/param-name<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;param-value<span class="re2">&gt;</span></span></span>false<span class="sc3"><span class="re1">&lt;/param-value<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li2">
<div class="de2"><span class="sc3"><span class="re1">&lt;/context-param<span class="re2">&gt;</span></span></span></div>
</li>
</ol>
</div>
</div>
<p>This allows you to enter the debug mode of an application, though, that requires to restart the application (or in the worst case, a redeploy). One upside of testing new Widgetsets can be that one can apply them to any running application without modifications, because that is purely client-side. So changing the configuration of the application might not be possible or desirable.</p>
<p>There are some forum posts out there which talk about that it is enough to enable the profiler and see the the output of it being logged to the debug console of the browser, but that is not the case anymore.</p>
<h3 style="padding-top: 10px">Let's have a deeper look</h3>
<p>The Profiler can be found in the class <strong>com.vaain.vaadin.client.Profiler</strong> and is comletely client-side. It will store all gathered information until the function logTimings() is called, which then will hand the gathered information to a consumer which can do with it whatever it wants. Now comes the interesting part, there is no public default implementation for the consumer provided. If you want to log what was profiled to the debug console you'll have to write your own. Even if there were, the function setProfilerResultConsumer(ProfilerResultConsumer) is commented with a warning that it might change in future versions without notice and should not be used - interesting. Also interesting is the fact that it can only be set once. Once set, it can not be changed.</p>
<p>Hm, looks a little bare bone. Of course there is an "internal" class that is utilizing it to send its output to the debug window, but we can't use any of that code, unfortunately. So let's see what we can do with it.</p>
<h3 style="padding-top: 10px">Send everything to the debug console</h3>
<p>The easiest thing is to simply send all the output to the debug console of the browser, we can do this easily enough:</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="kw1">import</span> <span class="co2">java.util.LinkedHashMap</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="kw1">import</span> <span class="co2">java.util.List</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2"><span class="kw1">import</span> <span class="co2">com.vaadin.client.Profiler.Node</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="kw1">import</span> <span class="co2">com.vaadin.client.Profiler.ProfilerResultConsumer</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2"><span class="co3">/**</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp;* A simple {@link ProfilerResultConsumer} which is outputting everything to the</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp;* debug console of the browser.</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp;* </span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp;* @author Robert Zenz</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp;*/</span></div>
</li>
<li class="li2">
<div class="de2"><span class="kw1">public</span> <span class="kw1">class</span> DebugConsoleProfilerResultConsumer <span class="kw1">implements</span> ProfilerResultConsumer</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">// Initialization</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co3">/**</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* Creates a new instance of {@link DebugConsoleProfilerResultConsumer}.</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;*/</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">public</span> DebugConsoleProfilerResultConsumer<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">super</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">// Interface implementation</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co3">/**</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* {@inheritDoc}</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;*/</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; @Override</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">void</span> addProfilerData<span class="br0">&#40;</span>Node pRootNode, <span class="kw3">List</span> pTotals<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; debug<span class="br0">&#40;</span>pRootNode<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span>Node node <span class="sy0">:</span> pTotals<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; debug<span class="br0">&#40;</span>node<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co3">/**</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* {@inheritDoc}</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;*/</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; @Override</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">void</span> addBootstrapData<span class="br0">&#40;</span>LinkedHashMap pTimings<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// TODO We'll ingore this for now.</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">// User-defined methods</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co3">/**</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* Sends the given {@link Node} to the debug console if it is</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* {@link #isValid(Node) valid}.</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* </span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* @param pNode the {@link Node} to log.</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* @see #isValid(Node)</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;*/</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> <span class="kw4">void</span> debug<span class="br0">&#40;</span>Node pNode<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>isValid<span class="br0">&#40;</span>pNode<span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; debug<span class="br0">&#40;</span>pNode.<span class="me1">getStringRepresentation</span><span class="br0">&#40;</span><span class="st0">&quot;&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co3">/**</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* Tests if the given {@link Node} is valid, meaning not {@code null}, has a</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* {@link Node#getName() name} and was {@link Node#getCount() invoked at</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* all}.</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* </span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* @param pNode the {@link Node} to test}.</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* @return {@code true} if the given {@link Node} is considered valid.</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;*/</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> <span class="kw4">boolean</span> isValid<span class="br0">&#40;</span>Node pNode<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> pNode <span class="sy0">!=</span> <span class="kw2">null</span> <span class="sy0">&amp;&amp;</span> pNode.<span class="me1">getName</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">!=</span> <span class="kw2">null</span> <span class="sy0">&amp;&amp;</span> pNode.<span class="me1">getCount</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">&gt;</span> <span class="nu0">0</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">// Native methods</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co3">/**</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* Logs the given message to the debug console.</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* </span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* @param pMessage the message to log.</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;*/</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> <span class="kw1">native</span> <span class="kw4">void</span> debug<span class="br0">&#40;</span><span class="kw3">String</span> pMessage<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="coMULTI">/*-{</span></div>
</li>
<li class="li2">
<div class="de2"><span class="coMULTI">&nbsp; &nbsp; &nbsp; &nbsp; console.debug(pMessage);</span></div>
</li>
<li class="li2">
<div class="de2"><span class="coMULTI">&nbsp; &nbsp; }-*/</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span> &nbsp; &nbsp;<span class="co1">// DebugConsoleProfilerResultConsumer</span></div>
</li>
</ol>
</div>
</div>
<p>And we can attach it rather easily, too:</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2">Profiler.<span class="me1">setProfilerResultConsumer</span><span class="br0">&#40;</span><span class="kw1">new</span> DebugConsoleProfilerResultConsumer<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
</ol>
</div>
</div>
<p>Make sure to do this only once, otherwise an Exception will be thrown, stating that it can only be done once. Also the application should not be in debug mode, otherwise the Vaadin consumer will be attached. Now that we've attached a consumer we can recompile the Widgetset and actually try it, and low and behold, we see output in the debug window of the browser. Quite a lot, actually, seems like the Profiler is used often, which is good.</p>
<h3 style="padding-top: 10px">Filter the results</h3>
<p>Skimming through the results is tedious, luckily most browsers come with the possibility to filter the results, but that possibility is quite limited. If we are interested in multiple results, the easiest way will be to filter them on the server side, obviously we can do that just as easily:</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="kw1">import</span> <span class="co2">java.util.HashSet</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="kw1">import</span> <span class="co2">java.util.LinkedHashMap</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="kw1">import</span> <span class="co2">java.util.List</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="kw1">import</span> <span class="co2">java.util.Set</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2"><span class="kw1">import</span> <span class="co2">com.vaadin.client.Profiler.Node</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="kw1">import</span> <span class="co2">com.vaadin.client.Profiler.ProfilerResultConsumer</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2"><span class="co3">/**</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp;* A simple {@link ProfilerResultConsumer} which is outputting everything to the</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp;* debug console of the browser.</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp;* </span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp;* @author Robert Zenz</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp;*/</span></div>
</li>
<li class="li2">
<div class="de2"><span class="kw1">public</span> <span class="kw1">class</span> DebugConsoleProfilerResultConsumer <span class="kw1">implements</span> ProfilerResultConsumer</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">// Class members</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co3">/** The names of nodes we want to output. */</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> <span class="kw3">Set</span> wantedNames <span class="sy0">=</span> <span class="kw1">new</span> <span class="kw3">HashSet</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">// Initialization</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co3">/**</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* Creates a new instance of {@link DebugConsoleProfilerResultConsumer}.</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* </span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* @param pWantedNames the names of the profiler data which should be</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;displayed.</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;*/</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">public</span> DebugConsoleProfilerResultConsumer<span class="br0">&#40;</span><span class="kw3">String</span>... <span class="me1">pWantedNames</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">super</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>pWantedNames <span class="sy0">!=</span> <span class="kw2">null</span> <span class="sy0">&amp;&amp;</span> pWantedNames.<span class="me1">length</span> <span class="sy0">&gt;</span> 0<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw3">String</span> wantedName <span class="sy0">:</span> pWantedNames<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; wantedNames.<span class="me1">add</span><span class="br0">&#40;</span>wantedName<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">// Interface implementation</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co3">/**</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* {@inheritDoc}</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;*/</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; @Override</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">void</span> addProfilerData<span class="br0">&#40;</span>Node pRootNode, <span class="kw3">List</span> pTotals<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; debug<span class="br0">&#40;</span>pRootNode<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span>Node node <span class="sy0">:</span> pTotals<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; debug<span class="br0">&#40;</span>node<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co3">/**</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* {@inheritDoc}</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;*/</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; @Override</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">void</span> addBootstrapData<span class="br0">&#40;</span>LinkedHashMap pTimings<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// TODO We'll ingore this for now.</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">// User-defined methods</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co3">/**</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* Sends the given {@link Node} to the debug console if it is</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* {@link #isValid(Node) valid}.</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* </span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* @param pNode the {@link Node} to log.</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* @see #isValid(Node)</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;*/</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> <span class="kw4">void</span> debug<span class="br0">&#40;</span>Node pNode<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>isValid<span class="br0">&#40;</span>pNode<span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; debug<span class="br0">&#40;</span>pNode.<span class="me1">getStringRepresentation</span><span class="br0">&#40;</span><span class="st0">&quot;&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co3">/**</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* Tests if the given {@link Node} is valid, meaning not {@code null}, has a</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* {@link Node#getName() name} and was {@link Node#getCount() invoked at</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* all}.</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* </span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* @param pNode the {@link Node} to test}.</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* @return {@code true} if the given {@link Node} is considered valid.</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;*/</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> <span class="kw4">boolean</span> isValid<span class="br0">&#40;</span>Node pNode<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> pNode <span class="sy0">!=</span> <span class="kw2">null</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">&amp;&amp;</span> pNode.<span class="me1">getName</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">!=</span> <span class="kw2">null</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">&amp;&amp;</span> pNode.<span class="me1">getCount</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">&gt;</span> 0</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">&amp;&amp;</span> <span class="br0">&#40;</span>wantedNames.<span class="me1">isEmpty</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">||</span> wantedNames.<span class="me1">contains</span><span class="br0">&#40;</span>pNode.<span class="me1">getName</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">// Native methods</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co3">/**</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* Logs the given message to the debug console.</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* </span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;* @param pMessage the message to log.</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co3">&nbsp; &nbsp; &nbsp;*/</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">private</span> <span class="kw1">native</span> <span class="kw4">void</span> debug<span class="br0">&#40;</span><span class="kw3">String</span> pMessage<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="coMULTI">/*-{</span></div>
</li>
<li class="li2">
<div class="de2"><span class="coMULTI">&nbsp; &nbsp; &nbsp; &nbsp; console.debug(pMessage);</span></div>
</li>
<li class="li2">
<div class="de2"><span class="coMULTI">&nbsp; &nbsp; }-*/</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span> &nbsp; &nbsp;<span class="co1">// DebugConsoleProfilerResultConsumer</span></div>
</li>
</ol>
</div>
</div>
<p>Now we can simply pass the list of "interesting" event names to the consumer and see only these.</p>
<h3 style="padding-top: 10px">JavaScript hacking</h3>
<p>But there is more, instead of setting a consumer we can attach ourselves to the JavaScript function and instead process each profiled section individually. So in the debug console we can simply run something like this:</p>
<div class="codesnip-container" >
<div class="javascript codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2">window.__gwtStatsEvent <span class="sy0">=</span> <span class="kw2">function</span><span class="br0">&#40;</span>event<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; console.<span class="me1">debug</span><span class="br0">&#40;</span>event<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span><span class="sy0">;</span></div>
</li>
</ol>
</div>
</div>
<p>This will output every single profiler event into the console. Now, if we want to process these events, we must first understand there is always a "begin" and an "end" event, which respectively are marking the begin and end of an event.</p>
<p>We can now listen for a certain event and simply output how long it took, like this:</p>
<div class="codesnip-container" >
<div class="javascript codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2">window.__profiler <span class="sy0">=</span> <span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">window.__gwtStatsEvent <span class="sy0">=</span> <span class="kw2">function</span><span class="br0">&#40;</span>event<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>event.<span class="me1">subSystem</span> <span class="sy0">===</span> <span class="st0">&quot;Layout pass&quot;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>event.<span class="me1">type</span> <span class="sy0">===</span> <span class="st0">&quot;begin&quot;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; window.__profiler<span class="br0">&#91;</span>event.<span class="me1">subSystem</span><span class="br0">&#93;</span> <span class="sy0">=</span> event.<span class="me1">millis</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.<span class="me1">log</span><span class="br0">&#40;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; event.<span class="me1">subSystem</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">+</span> <span class="st0">&quot;: &quot;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">+</span> <span class="br0">&#40;</span>event.<span class="me1">millis</span> <span class="sy0">-</span> window.__profiler<span class="br0">&#91;</span>event.<span class="me1">subSystem</span><span class="br0">&#93;</span><span class="br0">&#41;</span>.<span class="me1">toFixed</span><span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">+</span> <span class="st0">&quot;ms&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span><span class="sy0">;</span></div>
</li>
</ol>
</div>
</div>
<p>Or, to go over the top, we could create a generic listener which informs us about everything:</p>
<div class="codesnip-container" >
<div class="javascript codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2">window.__wantedEvents <span class="sy0">=</span> <span class="br0">&#91;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="st0">&quot;Layout pass&quot;</span><span class="sy0">,</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="st0">&quot;Layout measure connectors&quot;</span><span class="sy0">,</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="st0">&quot;layout PostLayoutListener&quot;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#93;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">window.__profiler <span class="sy0">=</span> <span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">window.__gwtStatsEvent <span class="sy0">=</span> <span class="kw2">function</span><span class="br0">&#40;</span>event<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>window.__wantedEvents.<span class="me1">indexOf</span><span class="br0">&#40;</span>event.<span class="me1">subSystem</span><span class="br0">&#41;</span> <span class="sy0">&gt;=</span> 0<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">typeof</span> window.__profiler<span class="br0">&#91;</span>event.<span class="me1">subSystem</span><span class="br0">&#93;</span> <span class="sy0">===</span> <span class="st0">&quot;undefined&quot;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; window.__profiler<span class="br0">&#91;</span>event.<span class="me1">subSystem</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; averageRuntime <span class="sy0">:</span> 0<span class="sy0">,</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; count <span class="sy0">:</span> 0<span class="sy0">,</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lastBegin <span class="sy0">:</span> 0<span class="sy0">,</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lastEnd <span class="sy0">:</span> 0<span class="sy0">,</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lastRuntime<span class="sy0">:</span> 0<span class="sy0">,</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lastRuntimes <span class="sy0">:</span> <span class="kw2">new</span> Array<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">,</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; minRuntime <span class="sy0">:</span> 999999999<span class="sy0">,</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; maxRuntime <span class="sy0">:</span> <span class="sy0">-</span>999999999<span class="sy0">,</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; totalRuntime <span class="sy0">:</span> 0</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> info <span class="sy0">=</span> window.__profiler<span class="br0">&#91;</span>event.<span class="me1">subSystem</span><span class="br0">&#93;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>event.<span class="me1">type</span> <span class="sy0">===</span> <span class="st0">&quot;begin&quot;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; info.<span class="me1">count</span> <span class="sy0">=</span> info.<span class="me1">count</span> <span class="sy0">+</span> <span class="nu0">1</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; info.<span class="me1">lastBegin</span> <span class="sy0">=</span> event.<span class="me1">millis</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; info.<span class="me1">lastEnd</span> <span class="sy0">=</span> event.<span class="me1">millis</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; info.<span class="me1">lastRuntime</span> <span class="sy0">=</span> info.<span class="me1">lastEnd</span> <span class="sy0">-</span> info.<span class="me1">lastBegin</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; info.<span class="me1">lastRuntimes</span>.<span class="me1">push</span><span class="br0">&#40;</span>info.<span class="me1">lastRuntime</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; info.<span class="me1">minRuntime</span> <span class="sy0">=</span> Math.<span class="me1">min</span><span class="br0">&#40;</span>info.<span class="me1">lastRuntime</span><span class="sy0">,</span> info.<span class="me1">minRuntime</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; info.<span class="me1">maxRuntime</span> <span class="sy0">=</span> Math.<span class="me1">max</span><span class="br0">&#40;</span>info.<span class="me1">lastRuntime</span><span class="sy0">,</span> info.<span class="me1">maxRuntime</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; info.<span class="me1">totalRuntime</span> <span class="sy0">=</span> info.<span class="me1">totalRuntime</span> <span class="sy0">+</span> info.<span class="me1">lastRuntime</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; info.<span class="me1">averageRuntime</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw2">var</span> index <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span> index <span class="sy0">&lt;</span> info.<span class="me1">lastRuntimes</span>.<span class="me1">length</span><span class="sy0">;</span> index<span class="sy0">++</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; info.<span class="me1">averageRuntime</span> <span class="sy0">=</span> info.<span class="me1">averageRuntime</span> <span class="sy0">+</span> info.<span class="me1">lastRuntimes</span><span class="br0">&#91;</span>index<span class="br0">&#93;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; info.<span class="me1">averageRuntime</span> <span class="sy0">=</span> info.<span class="me1">averageRuntime</span> <span class="sy0">/</span> info.<span class="me1">lastRuntimes</span>.<span class="me1">length</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.<span class="me1">log</span><span class="br0">&#40;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; event.<span class="me1">subSystem</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">+</span> <span class="st0">&quot;: &quot;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">+</span> info.<span class="me1">count</span>.<span class="me1">toFixed</span><span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">+</span> <span class="st0">&quot; times at &quot;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">+</span> info.<span class="me1">averageRuntime</span>.<span class="me1">toFixed</span><span class="br0">&#40;</span><span class="nu0">3</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">+</span> <span class="st0">&quot; totaling &quot;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">+</span> info.<span class="me1">totalRuntime</span>.<span class="me1">toFixed</span><span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">+</span> <span class="st0">&quot;ms with current at &quot;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">+</span> info.<span class="me1">lastRuntime</span>.<span class="me1">toFixed</span><span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">+</span> <span class="st0">&quot;ms (&quot;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">+</span> info.<span class="me1">minRuntime</span>.<span class="me1">toFixed</span><span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">+</span> <span class="st0">&quot;ms/&quot;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">+</span> info.<span class="me1">maxRuntime</span>.<span class="me1">toFixed</span><span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">+</span> <span class="st0">&quot;ms)&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span><span class="sy0">;</span></div>
</li>
</ol>
</div>
</div>
<p>And we now have a neat little system in place which displays everything we&#39;d like to know, and it is easily extendable and modifiable, too.</p>
<h3 style="padding-top: 10px">Conclusion</h3>
<p>As we see, we have quite a few ways to get the information from the profiler even without the application running in debug mode, some might not be as obvious as others, though. The interesting part is that many things are easily accessible on the JavaScript side of Vaadin, directly from the debug console of the browser, one only has to look for it.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.sibvisions.com/2017/09/11/vaadin-hack-the-profiler/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VisionX, a short look at Validators</title>
		<link>https://blog.sibvisions.com/2017/09/10/visionx-validators/</link>
		<comments>https://blog.sibvisions.com/2017/09/10/visionx-validators/#comments</comments>
		<pubDate>Sun, 10 Sep 2017 04:49:36 +0000</pubDate>
		<dc:creator>rzenz</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Information]]></category>
		<category><![CDATA[VisionX]]></category>

		<guid isPermaLink="false">https://blog.sibvisions.com/?p=7178</guid>
		<description><![CDATA[It is time to have a short look at Validators, what they are, how they work and how they can be used.
Okay, what are they?
A Validator is a component which is available to our customers who have purchased VisionX, it allows to quickly and easily add field validation to a form or any screen with [...]]]></description>
			<content:encoded><![CDATA[<p>It is time to have a short look at Validators, what they are, how they work and how they can be used.</p>
<h3 style="padding-top: 10px">Okay, what are they?</h3>
<p>A Validator is a <a href="http://www.sibvisions.com/en/jvx">component</a> which is available to our customers who have purchased <a href="http://www.sibvisions.com/en/visionx">VisionX</a>, it allows to quickly and easily add field validation to a form or any screen with records.</p>
<h3 style="padding-top: 10px">Validators in VisionX</h3>
<p>Validators are readily available in VisionX as components which can be added to the screen.</p>
<p style="text-align: center"><a href="https://blog.sibvisions.com/wp-content/uploads/2017/09/visionx-validators-toolbox.png" rel="lightbox[7178]"><img src="https://blog.sibvisions.com/wp-content/uploads/2017/09/visionx-validators-toolbox.png" alt="VisionX Validators - Toolbox" width="400" style="border: 1px solid #cccccc" /></a></p>
<p>It can be added to the screen by simply dragging it like any other component, but must be configured afterwards to know which field required validation.</p>
<p style="text-align: center"><a href="https://blog.sibvisions.com/wp-content/uploads/2017/09/visionx-validators-properties.png" rel="lightbox[7178]"><img src="https://blog.sibvisions.com/wp-content/uploads/2017/09/visionx-validators-properties.png" alt="VisionX Validators - Properties" width="400" style="border: 1px solid #cccccc" /></a></p>
<p>There are three important properties to the Validator:</p>
<ul>
<li><strong>Binding:</strong> The field to which the Validator should be bound to. This works analog to selecting to a field for an Editor.</li>
<li><strong>Automatic validate:</strong> If the validation process should be automatically performed on value changes.<br />
  If this is checked, the Validator will listen for value changes on the specified field and will automatically run the validation action on every change. If not checked, the validation process must be run manually by calling <em>Validator.validate()</em> as needed.</li>
<li><strong>Hide until first validate:</strong> If the Validator should stay hidden until at least one validation was performed.<br />
  If this is checked, the Validator will not be visible until at least its validation has been called once, afterwards it will always be visible.</li>
</ul>
<h3 style="padding-top: 10px">Validating values</h3>
<p>To actually validate something, we have to attach an action to the Validator which will perform the validation. This can be readily done through the VisionX action designer, which provides everything needed to create such an action and we will not go into detail on how to do this.</p>
<p>We will, however, have a short look at the code of a simple action.</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="kw1">public</span> <span class="kw4">void</span> doValidateNonEmpty<span class="br0">&#40;</span>Validator pValidator<span class="br0">&#41;</span> <span class="kw1">throws</span> <span class="kw3">Throwable</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>Logical.<span class="me1">equals</span><span class="br0">&#40;</span>rdbData.<span class="me1">getValue</span><span class="br0">&#40;</span><span class="st0">&quot;COLUMN&quot;</span><span class="br0">&#41;</span>, <span class="st0">&quot;&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">throw</span> <span class="kw1">new</span> <span class="kw3">Exception</span><span class="br0">&#40;</span><span class="st0">&quot;A value for the COLUMN must be entered.&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
</div>
<p>It is a very simple action, the current value of the DataBook is checked and if it is empty, an Exception is. This is the most simple validation action one can create.</p>
<h3 style="padding-top: 10px">Validators in action</h3>
<p>Once we have everything setup, we can put the Validators to good use. When the validation is performed, may it be automatically or manually, the validation actions will be invoked and if all of them return without throwing an Exception, the Validator will display a green check mark. However, if the actions should throw an Exception, the Validator will display a red "X".</p>
<p style="text-align: center"><a href="https://blog.sibvisions.com/wp-content/uploads/2017/09/visionx-validators-failed.png" rel="lightbox[7178]"><img src="https://blog.sibvisions.com/wp-content/uploads/2017/09/visionx-validators-failed.png" alt="VisionX Validators - Failed" width="400" style="border: 1px solid #cccccc" /></a></p>
<h3 style="padding-top: 10px">Manual validation</h3>
<p>Manually invoking the validation process as needed is quite simple by calling <em>Validator.isValid()</em>, which will return either true or false.</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="kw1">public</span> <span class="kw4">void</span> doSaveButtonPressed<span class="br0">&#40;</span>UIActionEvent pEvent<span class="br0">&#41;</span> <span class="kw1">throws</span> <span class="kw3">Throwable</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>validator.<span class="me1">isValid</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; rdbData.<span class="me1">saveSelectedRow</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">else</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; labelError.<span class="me1">setVisible</span><span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
</div>
<p>Above you see a sample action which manually performs the validation process and either saves the data or sets an error label to visible.</p>
<h3 style="padding-top: 10px">The ValidationResult</h3>
<p>One can quickly end up with many Validators in a single screen, which might make it difficult for the user to directly see why a field is not correctly validated. So it suggest itself that there should be a short summary close to the save button to make sure that the user is readily provided with the information why the action could not be performed. For this scenario there is the ValidationResult, which is another component which can be added to the screen from the toolbox.</p>
<p>It will automatically find all Validators in the screen and will perform their validation as needed. Afterwards it will gather all error messages and display them in a list.</p>
<p style="text-align: center"><a href="https://blog.sibvisions.com/wp-content/uploads/2017/09/visionx-validators-validationresult.png" rel="lightbox[7178]"><img src="https://blog.sibvisions.com/wp-content/uploads/2017/09/visionx-validators-validationresult.png" alt="VisionX Validators - ValidationResult" width="400" style="border: 1px solid #cccccc" /></a></p>
<p>The ValidationResult can be used similar to the Validator in an action.</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">
<ol>
<li class="li2">
<div class="de2"><span class="kw1">public</span> <span class="kw4">void</span> doSaveButtonPressed<span class="br0">&#40;</span>UIActionEvent pEvent<span class="br0">&#41;</span> <span class="kw1">throws</span> <span class="kw3">Throwable</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>validationResult.<span class="me1">isValid</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; rdbData.<span class="me1">saveSelectedRow</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">else</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; labelError.<span class="me1">setVisible</span><span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
</div>
<p>Additionally, there is the clearMessage() method which allows to clear the list of errors.</p>
<h3 style="padding-top: 10px">Conclusion</h3>
<p>The Validator and ValidationResult provide quick and easy means to add data validation to forms and screens with records and can be added and configured completely through the VisionX designer. Additionally, it provides a rich API which allows it to be easily used when writing the code manually or extending it with additional functionality.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.sibvisions.com/2017/09/10/visionx-validators/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
