<?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>Andi&#039;s Blog</title>
	<atom:link href="http://sahits.ch/blog/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://sahits.ch/blog</link>
	<description></description>
	<lastBuildDate>Sat, 23 Feb 2013 07:18:20 +0000</lastBuildDate>
	<language>de-DE</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>The full Win9x Experiance</title>
		<link>http://sahits.ch/blog/?p=2330</link>
		<comments>http://sahits.ch/blog/?p=2330#comments</comments>
		<pubDate>Sat, 23 Feb 2013 07:18:20 +0000</pubDate>
		<dc:creator>Andi</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[game]]></category>
		<category><![CDATA[Pharao]]></category>
		<category><![CDATA[Virtual Box]]></category>
		<category><![CDATA[wine]]></category>

		<guid isPermaLink="false">http://sahits.ch/blog/?p=2330</guid>
		<description><![CDATA[I don&#8217;t remember what caused me to pull out an old game and trying to install it. The game in question is Pharao which runs on Windows 98. It does not run on Windows XP and certainly not on Linux. Therefore I searched for ways to get it to run. The first approach was to [...]]]></description>
				<content:encoded><![CDATA[<p>I don&#8217;t remember what caused me to pull out an old game and trying to install it. The game in question is Pharao which runs on Windows 98. It does not run on Windows XP and certainly not on Linux. Therefore I searched for ways to get it to run.</p>
<p><span id="more-2330"></span></p>
<p>The first approach was to use Wine. While installation was without a hitch (and way faster than in the old Win98 days), I could not get it running.</p>
<p><a href="http://sahits.ch/blog/?attachment_id=2332" rel="attachment wp-att-2332"><img class="size-medium wp-image-2332 alignnone" alt="pharao_start_wine" src="http://sahits.ch/blog/wp-content/uploads/2013/02/pharao_start_wine-300x130.png" width="300" height="130" /></a></p>
<p>So it seems that my 64 bit OS cannot execute the 32 bit binaries. The next logical step then seemed to try another wine version from the days before 32 bit. To do that I installed PlayOnLinux. There the Pharao game already was reconfigured, meaning you could just say install and then the appropriate wine version was downloaded and installed, the wine prefix created and the game installed from CD drive. Unfortunately the result was the same:</p>
<p>&nbsp;</p>
<pre class="brush:shell">err:process:create_process starting 64-bit process L"C:\\windows\\system32\\wineboot.exe" not supported on this platform
err:process:start_wineboot failed to start wineboot, err 193
wine: could not load L"C:\\windows\\system32\\Pharaoh.exe": Module not found</pre>
<p>Then I decided to install VirtualBox and there install my Windows 98. This first step was no problem, but when Win98 started for the first time, it chose a standard monitor with a resolution of 800&#215;600. That is so small, that the whole dialog for changing the screen resolution has no place. Further more the resolution could not be changed. Some research produced the fact that I could use a generic graphic driver to resolve this issue. The drivers can be found in the <a href="http://bearwindows.boot-land.net/vbe9x.htm">BearWindows</a> project. So I hit the web hell program Internet Explorer (probably in version 4) only to discover that the application refuses to start before I have set up an Internet connection through a modem.</p>
<p>Fortunately I found some old DVD containing old versions of real browsers for a 32 bit operating system. So I installed first a version of Firefox1.5, then downloaded the driver. Once again I had to install an additional package from the web as Windows 98 does not come along with any utility to unzip an archive. Finally I managed to install the driver and fix the resolution of the screen. While it would have been possible to set the resolution real high, that does not make much sense, as the game has only a max resolution of 1024&#215;768. The rest is black border.</p>
<p>So now I have to end this article, to play Pharao!</p>
]]></content:encoded>
			<wfw:commentRss>http://sahits.ch/blog/?feed=rss2&#038;p=2330</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Combining standalone application with Spring</title>
		<link>http://sahits.ch/blog/?p=2326</link>
		<comments>http://sahits.ch/blog/?p=2326#comments</comments>
		<pubDate>Fri, 11 Jan 2013 09:21:16 +0000</pubDate>
		<dc:creator>Andi</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Programmieren]]></category>
		<category><![CDATA[application context]]></category>
		<category><![CDATA[autowire]]></category>
		<category><![CDATA[dependency injection]]></category>
		<category><![CDATA[DI]]></category>
		<category><![CDATA[Spring]]></category>

		<guid isPermaLink="false">http://sahits.ch/blog/?p=2326</guid>
		<description><![CDATA[When you are developing a standalone application, that you want to use with the SpringFramework, somewhere in your code you will have to load the application context. Potentially this results in chicken-egg problem, especially when you want to use a component in some class that is not a bean. This may have different causes: It [...]]]></description>
				<content:encoded><![CDATA[<p>When you are developing a standalone application, that you want to use with the SpringFramework, somewhere in your code you will have to load the application context. Potentially this results in chicken-egg problem, especially when you want to use a component in some class that is not a bean. This may have different causes:</p>
<ul>
<li>It is the main class, that is used to start up the application</li>
<li>The constructor uses arguments that cannot be resolved with autowireing</li>
</ul>
<p>There are different approaches to solve this, the most elegant one I will demonstrate.<span id="more-2326"></span>Some brains storming produces the following approaches:</p>
<ul>
<li>Use of a factory class that can be used to initialize the no-bean class</li>
<li>Using aspects to resolve the autowiring dependencies</li>
<li>Initiate autowiring manually</li>
</ul>
<h2>The factory approach</h2>
<p>While this is a simple solution, it is not entirely elegant. It involves the creation of a factory class as a bean which has the components wired in, that are needed to create the non-bean class and some static create method. However the fact that the factory is a bean is not exploited. It has to be declared as a bean so autowiring can take place.</p>
<h2>Using Aspects</h2>
<p>This is perhaps the most elegant solution from the view point of the application code, as the autowiring works as if it were a bean. On the downside the Aspect needs to be declared.</p>
<p>If the constructor calls a init method, this can be intercepted. Unfortunately you can only intercept public methods with Spring AOP, as it is proxy based. Additionally to define the pointcut you should define a annotation for the class, so you can single out all the classes with an init method, which should be considered by this aspect.</p>
<p>Using AspectJ for this seams the better solution, as then the pointcut can be defined on the level of the constructor. The actual code that has to be executed looks similar to the one in the manual case.</p>
<h2>Initialize autowiring manually</h2>
<p>The first question that pops up is, why would anyone do such a thing? Why not wire the dependencies manually:</p>
<pre class="brush:java">  private ComponentConsumer consumer; // &lt;== Spring main class

  public Main(){
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    consumer = context.getBean(ComponentConsumer.class);
  }</pre>
<p>One answer is flexibility. If you have only one bean to wire both approaches are about the same. However if you have more, you get an additional line of code for each additional bean. The other point is expendability during time: when you want to add a dependency to another bean tomorrow, you will have to define the bean and its initialisation.</p>
<p>But now let&#8217;s have a look at some code. First there are two beans one a Service and one a Component:</p>
<pre class="brush:java">package ch.sahits.test.spring.components;

import org.springframework.stereotype.Component;

@Component
public class SimpleWriter {

  public void sayHello() {
    System.out.println("Hello Spring DI Component!");
  }
}</pre>
<pre class="brush:java">package ch.sahits.test.spring.components;

import org.springframework.stereotype.Service;

@Service
public class SimpleWriterService {

  public void sayHello() {
    System.out.println("Hello Spring DI service!");
  }
}</pre>
<p>Next is another Component, which consumes from these two writers:</p>
<pre class="brush:java">package ch.sahits.test.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import ch.sahits.test.spring.components.SimpleWriter;
import ch.sahits.test.spring.components.SimpleWriterService;

@Component
public class ComponentConsumer {

  @Autowired
  private SimpleWriter component;
  @Autowired
  private SimpleWriterService service;

  public void consume() {
    component.sayHello();
    service.sayHello();
  }
}</pre>
<p>Now the really interesting part is the class containing the main method.</p>
<pre class="brush:java">package ch.sahits.test.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
  @Autowired
  private ComponentConsumer consumer; // &lt;== Spring main class

  public Main(){
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    AutowireCapableBeanFactory acbFactory = context.getAutowireCapableBeanFactory();
    acbFactory.autowireBean(this);
  }

  public static void main(String[] args) {

    Main main = new Main();
    main.consumer.consume();
  }
}</pre>
<p>The &#8216;miraculous&#8217; part happens in the constructor. Retrieving the application-context, getting an <a href="http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/beans/factory/config/AutowireCapableBeanFactory.html">AutowireCapableBeanFactory </a>and then tell the factory to resolve all autowired dependencies in this class. The ugly part here is the reference escape of this in the constructor.</p>
<p>For completeness</p>
<pre class="brush:xml">&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 

http://www.springframework.org/schema/beans/spring-beans.xsd


http://www.springframework.org/schema/context

                      http://www.springframework.org/schema/context/spring-context-2.5.xsd"&gt;

  &lt;context:component-scan base-package="ch.sahits.test.spring"/&gt;

&lt;/beans&gt;</pre>
<p>sake here the applicationContext.xml:</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://sahits.ch/blog/?feed=rss2&#038;p=2326</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Transaction isolation with Spring and Hibernate</title>
		<link>http://sahits.ch/blog/?p=2322</link>
		<comments>http://sahits.ch/blog/?p=2322#comments</comments>
		<pubDate>Thu, 10 Jan 2013 09:08:51 +0000</pubDate>
		<dc:creator>Andi</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Programmieren]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[optimistic locking]]></category>
		<category><![CDATA[spring 3.0]]></category>
		<category><![CDATA[transaction]]></category>

		<guid isPermaLink="false">http://sahits.ch/blog/?p=2322</guid>
		<description><![CDATA[Recently I had to investigate the question of stale data that may be passed over transactional borders in our application. The application is Spring based using JPA with Hibernate to access the database. The answer to the above question is not that interesting, but to give it I had to understand how this whole stuff [...]]]></description>
				<content:encoded><![CDATA[<p>Recently I had to investigate the question of stale data that may be passed over transactional borders in our application. The application is Spring based using JPA with Hibernate to access the database. The answer to the above question is not that interesting, but to give it I had to understand how this whole stuff is set up and configured. There are are quite some resources which address something like this, but when coming to Spring, in recent time the approach to implement this when from directly using Hibernate to using Hibernate through JPA, while there are quite some books and tutorials on this, none also include specific information how to set the isolation level and what happens when you use the optimistic locking approach.</p>
<p><span id="more-2322"></span></p>
<p>When talking about the <a href="http://en.wikipedia.org/wiki/Isolation_%28database_systems%29">I</a> in the <a href="http://en.wikipedia.org/wiki/ACID">ACID</a> principle, one has to consider three things that can happen:</p>
<ul>
<li><strong>Dirty reads</strong>: One transaction reads data, that is not committed by another transaction.</li>
<li><strong>Non-repeatable reads</strong>: One transaction reads data, another transaction updates this data and commits it, then the first transaction reads the &#8220;same&#8221; data again with a different result. A special case of this are lost updates. If the first transaction would update the data, the update of the second transaction is lost, as the update happened on the original data.</li>
<li><strong>Phantom reads</strong>: One transaction reads a set of data. Another transaction than inserts, deletes additional data (this would also include some form of update) in such a way that when the first transaction reads the data again, the number of results is different.</li>
</ul>
<p>This list is ordered: If phantom reads are handled by the transaction, dirty reads and non-repeatable reads cannot occur, while on the other preventing dirty reads does not prevent non-repeatable reads.</p>
<p>JPA defines four different isolation levels. There is a level for each separation of these phenomena:</p>
<ul>
<li>TRANSACTION_READ_UNCOMMITTED: Allows dirty reads, non-repeatable reads, and phantom reads to occur.</li>
<li>TRANSACTION_READ_COMMITTED: Prevents dirty reads, but non-repeatable reads and phantom reads may occur.</li>
<li>TRANSACTION_REPEATABLE_READ: Prevents dirty and non-repeatable reads, but phantom reads may occur.</li>
<li>TRANSACTION_SERIALIZABLE: Prevent everything &#8211; phantom reads may not occur.</li>
</ul>
<p>That is the technical basis, but how exactly is this applied in the concrete context. When using Spring the isolation level can be configured as part of the Transactional configuration. This is described at length in &#8220;Spring in Action&#8221; third edition by Craig Walls or the <a href="http://static.springsource.org/spring/docs/3.0.x/reference/transaction.html">SpringFramework documentation</a>.</p>
<p>Our application is largely configured using annotation, so I was used to seeing the occasional <code>@Transactional</code> annotation. However this annotation was at most accompanied with a specification of the propagation of the transaction. Nowhere the isolation level was defined, neither in the annotated form nor configured in XML. As Spring generally uses Convention over configuration, it&#8217;s save to assume that there are default values set, but what exactly is the default?</p>
<p>Spring defines an additional isolation level: DEFAULT. This however is not a proxy value for another of the defined transaction level, but simply states to use the use the default transaction level of the underlining data store. As I&#8217;m reading this, that could either mean Hibernate or the Oracle database. As it <a href="http://stackoverflow.com/questions/7839964/what-will-be-default-isolation-level-of-transaction-in-case-of-hibernate-with-or">turns out</a> it is the default level of the database itself. <a href="http://docs.oracle.com/cd/B10500_01/server.920/a96524/c21cnsis.htm">For oracle</a> this is read committed. Oracle also provides the isolation levels read-only and serializable.</p>
<p>Setting the isolation level to serializable would mean that on any read the data (row(s) of the whole table) is locked until the transaction completes. In most cases this is not a good idea (the number of reads is far greater than the number of updates). This can be a real damper on performance. For our application TRANSACTION_REPEATABLE_READ would be the ideal choice, as updating of viewed data may happen but it is perfectly normal that two queries do not result in the same amount of results. As Oracle does not support this I had to investigate into another direction.</p>
<p>This is exactly where Hibernate comes into play with its caching. When data is read hibernate puts it into the cache. If data that was modified by a different transaction Hibernate recognizes this. When using the isolation level of serializable, this results in a pessimistic locking strategy: The data is locked against any other access by another transaction. The opposite is an <a href="http://en.wikipedia.org/wiki/Optimistic_concurrency_control">optimistic locking</a> strategy. This strategy follows the saying: &#8220;Hope for the best, but prepare for the worst!&#8221; That means we hope that there will not arrive any issues with concurrent modification of data by different transactions, but it might happen and we are prepared to handle these OptimisticLockingExceptions. One point that should be mentioned here, the OptimisticLockingException is a Hibernate exception. Normally it is good practice to let Spring wrap these specific exceptions into neutral RuntimeExceptions. This would be done by annotating the DAO classes with @Repository, which we did not do, so we can use the Hibernate exceptions directly.</p>
<p>Now how exactly is an application configured to use optimistic locking. There are two approaches:</p>
<ul>
<li>Configuration in XML</li>
<li>Extension of the the database scheme with special fields and annotation</li>
</ul>
<p>Configuration in XML means in the persistence.xml or wherever you configured your hibernate mapping. To every class element you add the attribute <code>optimistic-lock="all"</code>. See also <a href="http://www.intertech.com/Blog/Post/Hibernate-Optimistic-Lock-without-a-Version-(or-Timestamp).aspx">Hibernate Optimistic Locking without Version (or Timestamp)</a>. The locking with Version or Timestamp is the second approach, the one we have chosen in our application. In the configuration with XML approach you had to configure something for every class element. Here you have to do the same in the code: To every table a version or timestamp field has to be added which then has to be annotated in the entity class. This looks like can be seen <a href="http://www.intertech.com/Blog/Post/Versioning-Optimistic-Locking-in-Hibernate.aspx">here</a> and <a href="http://matteoformica.wordpress.com/2011/02/24/jpa-and-hibernate-version-for-optimistic-locking/">here </a>(Optimistic vs. pesimistic).</p>
<p>But now it&#8217;s time to look at some code to configure the transactional stuff in Spring. The SpringFramework handles Transaction using AOP. This means that you have to specify the namespaces for aop and transaction:</p>
<pre class="brush:xml">  xmlns:aop="http://www.springframework.org/schema/aop"
  xmlns:tx="http://www.springframework.org/schema/tx"
...
xsi:schemaLocation="
  ...
  http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
  http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
  ...</pre>
<p>Let&#8217;s first have a look at the advice, which defines what methods should be handled how:</p>
<pre class="brush:xml">  &lt;tx:annotation-driven /&gt;

  &lt;tx:advice id="txAdvice" transaction-manager="transactionManager"&gt;
    &lt;tx:attributes&gt;
      &lt;tx:method name="get*" propagation="REQUIRED" read-only="true" rollback-for="Exception" /&gt;
      &lt;tx:method name="*" propagation="REQUIRED" rollback-for="Exception" /&gt;
    &lt;/tx:attributes&gt;
  &lt;/tx:advice&gt;</pre>
<p>The &#8220;annotation-driven&#8221; element defines that the transaction configuration is handled with Annotations. The advice references a transaction manager (in this case it could also be omitted, as Spring asumes there is a transaction manager defined with the id &#8220;transactionManager&#8221; by default). What this advice does is defining the default propagation level to REQUIRED and rollback behavior for any Exception. For methods which start with get it specified that the transaction is read only.</p>
<p>Now let&#8217;s take a look at the pointcut: where this transactional advice should be applied to:</p>
<pre class="brush:xml">    &lt;aop:pointcut id="repository_methods"
        expression="execution(* (@ch.sahits.spring.MyRepository ch.sahits.spring.dataaccess*)+.*(..))"/&gt;</pre>
<p>This defines all methods in the package <code>ch.sahits.spring.dataaccess</code> which are annotated with <code>MyRepository</code>, which is an extension of <code>@Component</code>.</p>
<p>Now let&#8217;s put this together:</p>
<pre class="brush:xml">  &lt;aop:config&gt;
    &lt;aop:pointcut id="repository_methods"
        expression="execution(* (@ch.sahits.spring.MyRepository ch.sahits.spring.dataaccess*)+.*(..))"/&gt;
    &lt;aop:advisor advice-ref="txAdvice" pointcut-ref="repository_methods" /&gt;
  &lt;/aop:config&gt;</pre>
<p>There is more stuff: How to configure the transaction-manager. The Transaction manager obviously will need the DataSource. I omit the configuration of that one, as there are enough examples for just that out there. The Transaction manager is defined as a JpaTransactionManager. As I mentioned earlier on, we are using JPA as a facade for Hibernate:</p>
<pre class="brush:xml">  &lt;bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"&gt;
    &lt;property name="entityManagerFactory" ref="emFactory" /&gt;
  &lt;/bean&gt;</pre>
<p>Next the definition of the emFactory:</p>
<pre class="brush:xml">  &lt;bean id="emFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"&gt;
    &lt;property name="persistenceXmlLocation" value="classpath:META-INF/da-oracle-persistence.xml" /&gt;
  &lt;/bean&gt;</pre>
<p>This bit of code bridges the JPA with the persistence.xml mentioned earlier on. The last bit is just that XML:</p>
<pre class="brush:xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"&gt;

  &lt;persistence-unit name="myPersistence" transaction-type="RESOURCE_LOCAL"&gt;
    &lt;provider&gt;org.hibernate.ejb.HibernatePersistence&lt;/provider&gt;
    &lt;non-jta-data-source&gt;java:comp/env/jdbc/MyDataSource&lt;/non-jta-data-source&gt;

    &lt;!-- no need to list entity classes here, automatically found in same jar/directory --&gt;

    &lt;properties&gt;
      &lt;property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" /&gt;
      &lt;property name="hibernate.show_sql" value="false" /&gt;
      &lt;property name="hibernate.jdbc.batch_size" value="100" /&gt;
      &lt;property name="hibernate.order_inserts" value="true" /&gt;
      &lt;property name="hibernate.order_updates" value="true" /&gt;

      &lt;property name="javax.persistence.validation.group.pre-persist"
          value="ch.sahits.spring.datamodel.validation.PrePersist" /&gt;
      &lt;property name="javax.persistence.validation.group.pre-update"
          value="ch.sahits.spring.datamodel.validation.PrePersist" /&gt;
      &lt;property name="javax.persistence.validation.group.pre-remove"
          value="" /&gt;
    &lt;/properties&gt;
  &lt;/persistence-unit&gt;

&lt;/persistence&gt;</pre>
<p>First we define Hibernate as persistance provider. Next I retrieve the data source. In this case it will be retrieved from JNDI. Compare:</p>
<pre class="brush:xml">  &lt;bean id="myDataSource" class="org.springframework.jndi.JndiObjectFactoryBean"&gt;
    &lt;property name="jndiName" value="java:comp/env/jdbc/MyDataSource" /&gt;
  &lt;/bean&gt;</pre>
<p>In the properties section Hibernate specific configurations are made, most notable the definition of the dialect. The PrePersist is a marker interface for a group for validation before save/update.</p>
<p>The mapping must not be configured here as it is handled with annotations (<code>@Entity</code> and <code>Column</code>).</p>
]]></content:encoded>
			<wfw:commentRss>http://sahits.ch/blog/?feed=rss2&#038;p=2322</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaFX: Fixed size label</title>
		<link>http://sahits.ch/blog/?p=2318</link>
		<comments>http://sahits.ch/blog/?p=2318#comments</comments>
		<pubDate>Fri, 04 Jan 2013 15:24:35 +0000</pubDate>
		<dc:creator>Andi</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Programmieren]]></category>
		<category><![CDATA[fixed size]]></category>
		<category><![CDATA[JavaFX]]></category>
		<category><![CDATA[label]]></category>
		<category><![CDATA[pagination]]></category>

		<guid isPermaLink="false">http://sahits.ch/blog/?p=2318</guid>
		<description><![CDATA[Though JavaFX provides a component for Pagination this is based on a fixed number of pages. However consider the following use case: You have some text of undefined length but definitely longer than can fit on a page. The text is dynamic so it is not feasible to split up the text onto several pages. [...]]]></description>
				<content:encoded><![CDATA[<p>Though JavaFX provides a component for Pagination this is based on a fixed number of pages. However consider the following use case:</p>
<p>You have some text of undefined length but definitely longer than can fit on a page. The text is dynamic so it is not feasible to split up the text onto several pages. Further more it may be possible that while displaying the font or the font style changes and thereby resulting in a different paging of the text.</p>
<p>As I have just such a use case in OpenPatrician, I did a quick test on how such a thing could be implemented.</p>
<p><span id="more-2318"></span></p>
<p>The implemented solution is a simplification of the above use case as I only tested for a single line. However from here it is possible to add multiple lines and when the page is full, add another page with a next button.</p>
<p>In the example I continually add more text but not more will be displayed but I get the not displayed text back.</p>
<p>Without further here is the Control component:</p>
<pre class="brush:java">package javafxtest.label;

import java.util.StringTokenizer;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.control.Control;
import javafx.scene.text.Font;

/**
 * Text control that has a fixed size text field. Pushing more
 * text than is displayable into it will result in an exception.
 * @author andi
 */
public class FixedSizedText extends Control {
    private final DoubleProperty localWidth;
    private final DoubleProperty localHeigth;
    private final StringProperty text;
    private final ReadOnlyObjectWrapper&lt;Font&gt; font;

    public FixedSizedText() {
        localWidth = new SimpleDoubleProperty(this, "width");
        localHeigth = new SimpleDoubleProperty(this, "heigth");
        text = new SimpleStringProperty(this, "text", "");
        font = new ReadOnlyObjectWrapper&lt;&gt;(this, "font");
        getStyleClass().add("fixed-size-text");
    }

    @Override
    protected String getUserAgentStylesheet() {
        return getClass().getResource("/javafxtest/label/"+getClass().getSimpleName()+".css").toExternalForm();
    }
    /**
     * Fill in as much of the text as possible and return the rest.
     * @param text to be filled in
     * @return not filled in text
     */
    public String fillIn(String text) {
        final StringTokenizer tokenizer = new StringTokenizer(text, " ");
        //final String oldText = getText();
        try {
            while (tokenizer.hasMoreTokens()) {
                String next = tokenizer.nextToken();
                setText(getText()+" "+next);
            }
        } catch (FixedSizeTextOverflowException e) {
            StringBuilder sb = new StringBuilder();
            while (tokenizer.hasMoreTokens()) {
                sb.append(" ").append(tokenizer.nextToken());
            }
            return sb.toString();
        }
        return "";
    }  

    public double getLocalHeigth() {
        return localHeigth.get();
    }

    public void setLocalHeigth(double value) {
        localHeigth.set(value);
    }

    public DoubleProperty localHeigthProperty() {
        return localHeigth;
    }

    public double getLocalWidth() {
        return localWidth.get();
    }

    public void setLocalWidth(double value) {
        localWidth.set(value);
    }

    public DoubleProperty localWidthProperty() {
        return localWidth;
    }

    public String getText() {
        return text.get();
    }

    public void setText(String value) {
        text.set(value);
    }

    public StringProperty textProperty() {
        return text;
    }
    public Font getFont() {
        return font.get();
    }

    public ReadOnlyObjectWrapper&lt;Font&gt; fontProperty() {
        return font;
    }

}</pre>
<p>The most important method is the fillIn method which will gruadualy append word by word to the components text property. There is this funny bit about catching a FixedSizeTextOverflowException which is a RuntimeException. To understand this properly we have to take a look at the skin:</p>
<pre class="brush:java">public class FixedSizedTextSkin extends SkinBase&lt;FixedSizedText&gt; {

    private final Label label;

    public FixedSizedTextSkin(FixedSizedText control) {
        super(control);
        label = new Label();
        label.setWrapText(false);
        StyleChangeListener styleListener = new StyleChangeListener();
        control.styleProperty().addListener(styleListener);
        //FontChangeListener fontChangeListener = new FontChangeListener();
        //control.fontProperty().addListener(fontChangeListener);
        control.textProperty().addListener(new TextChangeListener());
        getChildren().add(label);
    }
    /**
     * The text style may be defined style, therefore it must be checked when changeing.
     */
    private class StyleChangeListener implements ChangeListener&lt;String&gt; {

         @Override
        public void changed(ObservableValue&lt;? extends String&gt; ov, String t, String t1) {
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }

    }
    /**
     * If the text changes make sure all can be displayed.
     */
    private class TextChangeListener implements ChangeListener&lt;String&gt; {

         @Override
        public void changed(ObservableValue&lt;? extends String&gt; observable, String oldText, String newText) {
            final double maxWidth = getSkinnable().localWidthProperty().getValue();
            final double maxHeigth = getSkinnable().localHeigthProperty().getValue();
            if (label.getWidth()&gt;maxWidth || label.getHeight()&gt;maxHeigth) {
                throw new FixedSizeTextOverflowException();
            }
            label.setText(newText);
            if (label.getWidth()&gt;maxWidth || label.getHeight()&gt;maxHeigth) {
                label.setText(oldText);
                throw new FixedSizeTextOverflowException();
            }
        }

    }
    /**
     * If the font changes this may have an impact on what can be displayed.
     */
        private class FontChangeListener implements ChangeListener&lt;Font&gt; {

         @Override
        public void changed(ObservableValue&lt;? extends Font&gt; ov, Font t, Font t1) {
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }    
    }
}</pre>
<p>On the text property of the control a listener is registered, which will check that the size of the label with the new text does not exceed the width and height constraint of the control. If they are exceeded a FixedSizeTextOverflowException will be thrown. Besides changes on the text itself we should also listen to font changes and style changes, as well as size changes of the control.</p>
<p>The test code looks like this:</p>
<pre class="brush:java">package javafxtest.label;

import com.sun.javafx.tk.TKPulseListener;
import com.sun.javafx.tk.Toolkit;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class FixedSizedTextTest extends Application {

    @Override
    public void start(Stage primaryStage) {
        FixedSizedText text = new FixedSizedText();
        text.setLocalHeigth(20);
        text.setLocalWidth(200);

        StackPane root = new StackPane();
        root.getChildren().add(text);

        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("Fixed size table");
        primaryStage.setScene(scene);
        primaryStage.show();
        Toolkit.getToolkit().addSceneTkPulseListener(new LabelGrowth(text));
    }

    public static void main(String[] args) {
        launch(args);
    }

        private static class LabelGrowth implements TKPulseListener {

        private final FixedSizedText text;
        private int counter = 0;

        public LabelGrowth(FixedSizedText label) {
            this.text = label;
        }

        @Override
        public void pulse() {
                String exeeding = text.fillIn(text.getText()+"blah ");
                System.out.println("Update no. "+counter+" to: "+text.getText());
                System.out.println("Exeeding text: "+exeeding);
                counter++;
        }        
    }
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://sahits.ch/blog/?feed=rss2&#038;p=2318</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaFX: Perspective Transformation</title>
		<link>http://sahits.ch/blog/?p=2314</link>
		<comments>http://sahits.ch/blog/?p=2314#comments</comments>
		<pubDate>Thu, 03 Jan 2013 19:51:20 +0000</pubDate>
		<dc:creator>Andi</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Programmieren]]></category>
		<category><![CDATA[JavaFX]]></category>
		<category><![CDATA[matrix]]></category>
		<category><![CDATA[perspective]]></category>
		<category><![CDATA[transform]]></category>

		<guid isPermaLink="false">http://sahits.ch/blog/?p=2314</guid>
		<description><![CDATA[As stated in one of my previous articles, the PerspectiveTransformation is good for transforming the visual repensentation of a node/shape, but its original position still stays the same. This means that if I want an transformed area to react on events (like mouse clicks), I have to transform the coordinates and then define the position. [...]]]></description>
				<content:encoded><![CDATA[<p>As stated in one of my <a href="http://sahits.ch/blog/?p=2286">previous articles</a>, the PerspectiveTransformation is good for transforming the visual repensentation of a node/shape, but its original position still stays the same. This means that if I want an transformed area to react on events (like mouse clicks), I have to transform the coordinates and then define the position.</p>
<p><span id="more-2314"></span></p>
<p>As all I need is the location of a shape, a polygon in general, to be transformed, this can be done by trans-locating each point. All transformations can be described by a matrix. As this is a 2D operation this will be a 4&#215;3 matrix multiplied with the location vector, augmented by a 1:</p>
<p><img class="alignnone" alt="\begin{bmatrix} \vec{y} \\ 1 \end{bmatrix} = \begin{bmatrix} A &amp; \vec{b} \ \\ 0, \ldots, 0 &amp; 1 \end{bmatrix} \begin{bmatrix} \vec{x} \\ 1 \end{bmatrix}" src="http://upload.wikimedia.org/math/6/5/5/65510671c4bff125774c5d3fa856c0e2.png" width="197" height="51" /></p>
<p>Here x is the original position and y is the trans-located position. This can also be written as:</p>
<p><img class="alignnone" alt="\vec{y} = A \vec{x} + \vec{b}" src="http://upload.wikimedia.org/math/d/6/5/d65e582afbf418e4989971cdee42a167.png" width="98" height="25" /></p>
<p>The transformation matrix of a polygon is defined by the transformation of the bounding box of the polygon. The general case where the four corners of the bounding box are translated can be reduced to the special case where only three corners are translated. Therefore this transformation algorithm will take the source and destination points in 2D space of the three corners that are moved.</p>
<p>This is the result:</p>
<p><a href="http://sahits.ch/blog/?attachment_id=2315" rel="attachment wp-att-2315"><img class="size-medium wp-image-2315 alignnone" alt="JavaFX_Polygon_Perspective_Transformation" src="http://sahits.ch/blog/wp-content/uploads/2013/01/JavaFX_Polygon_Perspective_Transformation-300x176.png" width="300" height="176" /></a></p>
<p>To achieve this three components are needed: A property class defining the Transition from one Point2D to another, the Transformation class which will take three transformation points and caluculates the matrix based on that input, and finally the test program.</p>
<pre class="brush:java">package ch.sahits.javafx.test.transform;

import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.geometry.Point2D;

public class Translation2D {
    private final ReadOnlyObjectProperty&lt;Point2D&gt; source;
    private final ReadOnlyObjectProperty&lt;Point2D&gt; destination;

    public Translation2D(Point2D source, Point2D destination) {
        this.source = new SimpleObjectProperty&lt;&gt;(this, "source", source);
        this.destination = new SimpleObjectProperty&lt;&gt;(this, "destination", destination);
    }

    public Translation2D(double srcX, double srcY, double destX, double destY) {
        this(new Point2D(srcX, srcY), new Point2D(destX, destY));
    }

    public Point2D getSource() {
        return source.getValue();
    }

    public Point2D getDestination() {
        return destination.getValue();
    }

    public ReadOnlyObjectProperty&lt;Point2D&gt; sourceProperty() {
        return source;
    }

    public ReadOnlyObjectProperty&lt;Point2D&gt; destinationProperty() {
        return destination;
    }    
}</pre>
<p>Nothing relay exciting here, but we will relay on this class for in the transformation:</p>
<pre class="brush:java">package ch.sahits.javafx.test.transform;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.geometry.Point2D;
import javafx.scene.shape.Polygon;

public class PolygonPerspectiveTransformation {

    private final static Translation2D ORIGIN_ORIGIN = new Translation2D(0, 0, 0, 0);

    private final ObjectProperty&lt;Translation2D&gt; point1 = new SimpleObjectProperty&lt;&gt;(this, "point-1",ORIGIN_ORIGIN);
    private final ObjectProperty&lt;Translation2D&gt; point2 = new SimpleObjectProperty&lt;&gt;(this, "point-2", ORIGIN_ORIGIN);
    private final ObjectProperty&lt;Translation2D&gt; point3 = new SimpleObjectProperty&lt;&gt;(this, "point-3", ORIGIN_ORIGIN);

    /* Initialize the Matrix with the identity */
    private double a11 = 1;
    private double a12 = 0;
    private double a21 = 0;
    private double a22 = 1;
    private double b1 = 0;
    private double b2 = 0;

    public PolygonPerspectiveTransformation() {
        point1.addListener(new RecalculationEventListener());
        point2.addListener(new RecalculationEventListener());
        point3.addListener(new RecalculationEventListener());
   }
    /**
     * Recalculate the matrix values based on the points.
     */
    private void calculate() {
        a12 = calculateA12();
        a11 = calculateA11(); // requires recalculated a12
        b1 = calculateB1(); // requires recalculated a11 and a12
        a22 = calculateA22();
        a21 = calculateA21(); // requires recalculated a22
        b2 = calculateB2(); // requires recalculated a21 and a22
    }
    private double calculateA12() {
        double y1 = point1.getValue().getSource().getY();
        double y2 = point2.getValue().getSource().getY();
        double y3 = point3.getValue().getSource().getY();
        double x1 = point1.getValue().getSource().getX();
        double x2 = point2.getValue().getSource().getX();
        double x3 = point3.getValue().getSource().getX();
        double x1d = point1.getValue().getDestination().getX();
        double x2d = point2.getValue().getDestination().getX();
        double x3d = point3.getValue().getDestination().getX();

        double diff_x2_x1 = x2 - x1;
        double diff_x3_x1 = x3 - x1;

        double top = x3d - x1d + ((x1d - x2d)*diff_x3_x1/diff_x2_x1);
        double bottom = y3 - y1 - ((y2 - y1)*diff_x3_x1/diff_x2_x1);

        return top / bottom;
    }
    private double calculateA11() {
        double x1 = point1.getValue().getSource().getX();
        double x2 = point2.getValue().getSource().getX();
        double y1 = point1.getValue().getSource().getY();
        double y2 = point2.getValue().getSource().getY();
        double x1d = point1.getValue().getDestination().getX();
        double x2d = point2.getValue().getDestination().getX();

        double top = x2d - x1d - a12*(y2 - y1);
        double bottom = x2 - x1;

        return top / bottom;
   }
    private double calculateB1() {
        double x1 = point1.getValue().getSource().getX();
        double y1 = point1.getValue().getSource().getY();
        double x1d = point1.getValue().getDestination().getX();

        return x1d - a11*x1 - a12*y1;
   }

    private double calculateA22() {
        double y1 = point1.getValue().getSource().getY();
        double y2 = point2.getValue().getSource().getY();
        double y3 = point3.getValue().getSource().getY();
        double x1 = point1.getValue().getSource().getX();
        double x2 = point2.getValue().getSource().getX();
        double x3 = point3.getValue().getSource().getX();
        double y1d = point1.getValue().getDestination().getY();
        double y2d = point2.getValue().getDestination().getY();
        double y3d = point3.getValue().getDestination().getY();

        double diff_x2_x1 = x2 - x1;
        double diff_x3_x1 = x3 - x1;

        double top = y3d - y1d - ((y2d - y1d)*diff_x3_x1/diff_x2_x1);
        double bottom = y3 - y1 - ((y2 - y1)*diff_x3_x1/diff_x2_x1);

        return top / bottom;
    }
    private double calculateA21() {
        double y1 = point1.getValue().getSource().getY();
        double y2 = point2.getValue().getSource().getY();
        double x1 = point1.getValue().getSource().getX();
        double x2 = point2.getValue().getSource().getX();
        double y1d = point1.getValue().getDestination().getY();
        double y2d = point2.getValue().getDestination().getY();

        double top = y2d - y1d - a22*(y2 - y1);
        double bottom = x2 - x1;

        return top / bottom;
    }

    private double calculateB2() {
        double x1 = point1.getValue().getSource().getX();
        double y1 = point1.getValue().getSource().getY();
        double y1d = point1.getValue().getDestination().getY();

        return y1d - a21*x1 - a22*y1;
   }
    /**
     * Transform a polygon using the defined perspective transformation
     * @param polygon
     * @return 
     */
    public Polygon transform(Polygon polygon) {
        List&lt;Point2D&gt; points = convertToPoints(polygon.getPoints());
        Polygon transformedPolygon = new Polygon();
        for (Point2D p : points) {
            double xd = p.getX()*a11 + p.getY()*a12 + b1;
            double yd = p.getX()*a21 + p.getY()*a22 + b2;
            transformedPolygon.getPoints().addAll(xd, yd);
        }
        return transformedPolygon;
    }

    private List&lt;Point2D&gt; convertToPoints(ObservableList&lt;Double&gt; points) {
        ArrayList&lt;Point2D&gt; list = new ArrayList&lt;&gt;();
        for (Iterator&lt;Double&gt; it = points.iterator(); it.hasNext();) {
            double x = it.next();
            double y = it.next();
            list.add(new Point2D(x, y));
        }
        return list;
    }

    public Translation2D getPoint3() {
        return point3.get();
    }

    public void setPoint3(Translation2D value) {
        point3.set(value);
    }

    public ObjectProperty&lt;Translation2D&gt; point3Property() {
        return point3;
    }

    public Translation2D getPoint2() {
        return point2.get();
    }

    public void setPoint2(Translation2D value) {
        point2.set(value);
    }

    public ObjectProperty&lt;Translation2D&gt; point2Property() {
        return point2;
    }

    public Translation2D getPoint1() {
        return point1.get();
    }

    public void setPoint1(Translation2D value) {
        point1.set(value);
    }

    public ObjectProperty&lt;Translation2D&gt; point1Property() {
        return point1;
    }

    /**
     * Ensure that the values are recalculated on property change.
     */
    private class RecalculationEventListener implements ChangeListener&lt;Translation2D&gt; {
        @Override
        public void changed(ObservableValue&lt;? extends Translation2D&gt; ov, Translation2D t, Translation2D t1) {
            calculate();
        }
    }

}</pre>
<p>This is the class that does the heavy lifting. The main work is to recalculate the matrix every time the Translation2D properties change. The derivation of the calculation is trivial but lengthy. The starting point are these four formulas:<br />
x<sub>1</sub>&#8216; = x<sub>1</sub>a<sub>11</sub> + y<sub>1</sub>a<sub>12</sub> + b<sub>1</sub><br />
y<sub>1</sub>&#8216; = x<sub>1</sub>a<sub>21</sub> + y<sub>1</sub>a<sub>22</sub> + b<sub>2</sub><br />
x<sub>2</sub>&#8216; = x<sub>2</sub>a<sub>11</sub> + y<sub>2</sub>a<sub>12</sub> + b<sub>1</sub><br />
y<sub>2</sub>&#8216; = x<sub>2</sub>a<sub>21</sub> + y<sub>2</sub>a<sub>22</sub> + b<sub>2</sub><br />
x<sub>3</sub>&#8216; = x<sub>3</sub>a<sub>11</sub> + y<sub>3</sub>a<sub>12</sub> + b<sub>1</sub><br />
y<sub>3</sub>&#8216; = x<sub>3</sub>a<sub>21</sub> + y<sub>3</sub>a<sub>22</sub> + b<sub>2</sub></p>
<p>The x&#8217;, y&#8217; variables are the destination and in the code represented by x1d, y1d, &#8230;</p>
<p>The final piece is the application itself:</p>
<pre class="brush:java">package ch.sahits.javafx.test.stretch;

import ch.sahits.javafx.test.ResizeableCanvas;
import ch.sahits.javafx.test.transform.PolygonPerspectiveTransformation;
import ch.sahits.javafx.test.transform.Translation2D;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.effect.PerspectiveTransform;
import javafx.scene.effect.PerspectiveTransformBuilder;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.shape.Polygon;
import javafx.scene.shape.RectangleBuilder;
import javafx.stage.Stage;

public class PerspectivePolygonTransformation extends Application {

    @Override
    public void start(Stage primaryStage) {
        try {
            Group root = new Group();
            Image img = new Image(getClass().getResource("PaperScroll.png").openStream());
            final double width = img.getWidth();
            final double height = img.getHeight();
            Scene scene = new Scene(root, width, height);
            ImageView imageView = new ImageView(img);

            Polygon untranformed = new Polygon(370,50,500,30,520,100,330,90);
            untranformed.setFill(Color.RED);
            untranformed.setOpacity(0.5);
            untranformed.setOnMouseClicked(new EventHandler&lt;MouseEvent&gt;(){

                @Override
                public void handle(MouseEvent t) {
                    System.out.println("Clicked on untransformed polygon");
                }
            });

            PolygonPerspectiveTransformation transformer = new PolygonPerspectiveTransformation();
            transformer.setPoint1(new Translation2D(366, 29, 366+200, 29)); // top left
            transformer.setPoint2(new Translation2D(366+559, 29, 366+544, 29+19)); // top right
            transformer.setPoint3(new Translation2D(366, 29+502, 366, 29+403)); // bottom right

            Polygon transformed = transformer.transform(untranformed);
            transformed.setFill(Color.BLUE);
            transformed.setOpacity(0.5);
            transformed.setOnMouseClicked(new EventHandler&lt;MouseEvent&gt;(){

                @Override
                public void handle(MouseEvent t) {
                    System.out.println("Clicked on transformed polygon");
                }
            });

            root.getChildren().addAll(imageView, untranformed, transformed);     
            primaryStage.setTitle("Perspective Polygon Transform");
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch (IOException ex) {
            Logger.getLogger(ResizeableCanvas.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}</pre>
<p>As this transformation does not operate on a node and we push all nodes in the root node, the coordinates relative to the root node have to be specified in Translation2D parameters.</p>
]]></content:encoded>
			<wfw:commentRss>http://sahits.ch/blog/?feed=rss2&#038;p=2314</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
