<?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>Martin&#039;s Weekend Coding &#187; Scrolling</title>
	<atom:link href="http://blog.alutam.com/tag/scrolling/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.alutam.com</link>
	<description>Sharing useful tips from my &#34;weekend projects&#34;</description>
	<lastBuildDate>Sat, 31 Oct 2009 13:14:32 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
   <image>
    <title>Martin&#039;s Weekend Coding</title>
    <url>http://www.gravatar.com/avatar/fe13f36272d010f4b3c09e477a620991?s=</url>
    <link>http://blog.alutam.com</link>
   </image>
		<item>
		<title>Implementing a Scroll View in JavaFX</title>
		<link>http://blog.alutam.com/2009/08/30/implementing-a-scroll-view-in-javafx/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</link>
		<comments>http://blog.alutam.com/2009/08/30/implementing-a-scroll-view-in-javafx/#comments</comments>
		<pubDate>Sun, 30 Aug 2009 12:51:47 +0000</pubDate>
		<dc:creator>Martin</dc:creator>
				<category><![CDATA[JavaFX]]></category>
		<category><![CDATA[Scrolling]]></category>

		<guid isPermaLink="false">http://blog.alutam.com/?p=53</guid>
		<description><![CDATA[JavaFX does not seem to have support for scroll views. So, you have to
implement it on your own. Here is how I started implementing my own scroll view supporting
vertical scrolling:

package scrollviewdemo;

import javafx.scene.CustomNode;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.control.ScrollBar;
import javafx.util.Math;
import javafx.scene.shape.Rectangle;
import javafx.scene.paint.Paint;

public class ScrollView extends CustomNode {
    public-init var node: Node;
    public var [...]]]></description>
			<content:encoded><![CDATA[<p>JavaFX does not seem to have support for scroll views. So, you have to<br />
implement it on your own. Here is how I started implementing my own scroll view supporting<br />
vertical scrolling:</p>
<div class="codebox">
<pre><span class="Include"><span class="ReservedWord">package</span> scrollviewdemo;</span>

<span class="Include"><span class="ReservedWord">import</span> javafx.scene.CustomNode;</span>
<span class="Include"><span class="ReservedWord">import</span> javafx.scene.Group;</span>
<span class="Include"><span class="ReservedWord">import</span> javafx.scene.Node;</span>
<span class="Include"><span class="ReservedWord">import</span> javafx.scene.control.ScrollBar;</span>
<span class="Include"><span class="ReservedWord">import</span> javafx.util.Math;</span>
<span class="Include"><span class="ReservedWord">import</span> javafx.scene.shape.Rectangle;</span>
<span class="Include"><span class="ReservedWord">import</span> javafx.scene.paint.Paint;</span>

<span class="ReservedWord">public</span> <span class="ReservedWord">class</span> <span class="Identifier">ScrollView</span> <span class="ReservedWord">extends</span> <span class="Identifier">CustomNode</span> <span class="Braces">{</span>
    <span class="ReservedWord">public-init</span> <span class="ReservedWord">var</span> <span class="Identifier">node</span><span class="Symbol">:</span> <span class="Identifier">Node</span><span class="Symbol">;</span>
    <span class="ReservedWord">public</span> <span class="ReservedWord">var</span> <span class="Identifier">width</span><span class="Symbol">:</span> <span class="Identifier">Float</span><span class="Symbol">;</span>
    <span class="ReservedWord">public</span> <span class="ReservedWord">var</span> <span class="Identifier">height</span><span class="Symbol">:</span> <span class="Identifier">Float</span><span class="Symbol">;</span>

    <span class="ReservedWord">var</span> <span class="Identifier">group</span><span class="Symbol">:</span> <span class="Identifier">Group</span><span class="Symbol">;</span>
    <span class="ReservedWord">var</span> <span class="Identifier">gap</span> <span class="Symbol">=</span> <span class="ReservedWord">bind</span> <span class="Identifier">group</span>.<span class="Identifier">layoutBounds</span>.<span class="Identifier">height</span> <span class="Symbol">-</span> <span class="Identifier">height</span><span class="Symbol">;</span>

    <span class="ReservedWord">def</span> <span class="Identifier">scrollBar</span><span class="Symbol">:</span> <span class="Identifier">ScrollBar</span> <span class="Symbol">=</span> <span class="Identifier">ScrollBar</span> <span class="Braces">{</span>
        <span class="Identifier">translateX</span><span class="Symbol">:</span> <span class="ReservedWord">bind</span> <span class="Identifier">width</span> <span class="Symbol">-</span> <span class="Identifier">scrollBar</span>.<span class="Identifier">width</span>
        <span class="Identifier">min</span><span class="Symbol">:</span> <span class="Numeric">0</span>
        <span class="Identifier">max</span><span class="Symbol">:</span> <span class="ReservedWord">bind</span> <span class="Identifier">Math</span>.<span class="Identifier">max</span><span class="Braces">(</span><span class="Numeric">0</span>, <span class="Identifier">gap</span><span class="Braces">)</span>
        <span class="Identifier">visible</span><span class="Symbol">:</span> <span class="ReservedWord">bind</span> <span class="Identifier">gap</span> <span class="Symbol">&gt;</span> <span class="Numeric">0</span>
        <span class="Identifier">vertical</span><span class="Symbol">:</span> <span class="ReservedWord">true</span>
        <span class="Identifier">height</span><span class="Symbol">:</span> <span class="ReservedWord">bind</span> <span class="Identifier">height</span>
    <span class="Braces">}</span>

    <span class="ReservedWord">override</span> <span class="ReservedWord">function</span> <span class="Identifier">create</span><span class="Braces">(</span><span class="Braces">)</span> <span class="Braces">{</span>
        <span class="Identifier">Group</span> <span class="Braces">{</span>
            <span class="Identifier">content</span><span class="Symbol">:</span> <span class="Braces">[</span>
                <span class="Identifier">Group</span> <span class="Braces">{</span>
                    <span class="Identifier">content</span><span class="Symbol">:</span> <span class="Braces">[</span>
                        <span class="Identifier">group</span> <span class="Symbol">=</span> <span class="Identifier">Group</span> <span class="Braces">{</span>
                            <span class="Identifier">translateY</span><span class="Symbol">:</span> <span class="ReservedWord">bind</span> <span class="Symbol">-</span> <span class="Identifier">scrollBar</span>.<span class="Identifier">value</span>
                            <span class="Identifier">content</span><span class="Symbol">:</span> <span class="Braces">[</span><span class="Identifier">node</span><span class="Braces">]</span>
                        <span class="Braces">}</span>
                    <span class="Braces">]</span>
                    <span class="Identifier">clip</span><span class="Symbol">:</span> <span class="Identifier">Rectangle</span> <span class="Braces">{</span>
                        <span class="Identifier">width</span><span class="Symbol">:</span> <span class="ReservedWord">bind</span> <span class="Identifier">width</span> <span class="Symbol">-</span> <span class="Braces">{</span><span class="ReservedWord">if</span> <span class="Braces">(</span><span class="Identifier">gap</span> <span class="Symbol">&gt;</span> <span class="Numeric">0</span><span class="Braces">)</span> <span class="Identifier">scrollBar</span>.<span class="Identifier">width</span> <span class="ReservedWord">else</span> <span class="Numeric">0</span><span class="Braces">}</span>
                        <span class="Identifier">height</span><span class="Symbol">:</span> <span class="ReservedWord">bind</span> <span class="Identifier">height</span>
                    <span class="Braces">}</span>
                <span class="Braces">}</span>,
                <span class="Identifier">scrollBar</span>
            <span class="Braces">]</span>
        <span class="Braces">}</span>
    <span class="Braces">}</span>
<span class="Braces">}</span></pre>
</div>
<p>This is how it can be used in a simple application:</p>
<div class="codebox">
<pre><span class="ReservedWord">var</span> <span class="Identifier">stage</span><span class="Symbol">:</span> <span class="Identifier">Stage</span> <span class="Symbol">=</span> <span class="Identifier">Stage</span> <span class="Braces">{</span>
    <span class="Identifier">title</span><span class="Symbol">:</span> <span class="String">&quot;Application title&quot;</span>
    <span class="Identifier">width</span><span class="Symbol">:</span> <span class="Numeric">200</span>
    <span class="Identifier">height</span><span class="Symbol">:</span> <span class="Numeric">200</span>
    <span class="Identifier">scene</span><span class="Symbol">:</span> <span class="Identifier">Scene</span> <span class="Braces">{</span>
        <span class="Identifier">content</span><span class="Symbol">:</span> <span class="Braces">[</span>
            <span class="Identifier">ScrollView</span> <span class="Braces">{</span>
                <span class="Identifier">width</span><span class="Symbol">:</span> <span class="ReservedWord">bind</span> <span class="Identifier">stage</span>.<span class="Identifier">scene</span>.<span class="Identifier">width</span>
                <span class="Identifier">height</span><span class="Symbol">:</span> <span class="ReservedWord">bind</span> <span class="Identifier">stage</span>.<span class="Identifier">scene</span>.<span class="Identifier">height</span>
                <span class="Identifier">node</span><span class="Symbol">:</span> <span class="Identifier">VBox</span> <span class="Braces">{</span>
                    <span class="Identifier">content</span><span class="Symbol">:</span> <span class="ReservedWord">for</span> <span class="Braces">(</span><span class="Identifier">i</span> <span class="ReservedWord">in</span> <span class="Braces">[</span><span class="Numeric">0</span>..<span class="Numeric">20</span><span class="Braces">]</span><span class="Braces">)</span> <span class="Identifier">ImageView</span> <span class="Braces">{</span>
                        <span class="Identifier">image</span><span class="Symbol">:</span> <span class="Identifier">Image</span> <span class="Braces">{</span>
                            <span class="Comment">// some picture</span>
                            <span class="Identifier">url</span><span class="Symbol">:</span> <span class="String">&quot;{__DIR__}pic.png&quot;</span>
                        <span class="Braces">}</span>
                    <span class="Braces">}</span>
                <span class="Braces">}</span>
            <span class="Braces">}</span>
        <span class="Braces">]</span>
    <span class="Braces">}</span>
<span class="Braces">}</span></pre>
</div>
<p>To support mouse scroll wheel I added the following to the ScrollView class:</p>
<div class="codebox">
<pre>    <span class="ReservedWord">override</span> <span class="ReservedWord">var</span> <span class="Identifier">onMouseWheelMoved</span> <span class="Symbol">=</span> <span class="ReservedWord">function</span><span class="Braces">(</span><span class="Identifier">event</span><span class="Braces">)</span> <span class="Braces">{</span>
        <span class="Comment">// multiplying by 4 makes the scrolling faster and still smooth</span>
        <span class="Identifier">scrollBar</span>.<span class="Identifier">value</span> <span class="Symbol">+</span><span class="Symbol">=</span> <span class="Identifier">event</span>.<span class="Identifier">wheelRotation</span> <span class="Symbol">*</span> <span class="Numeric">4</span><span class="Symbol">;</span>
    <span class="Braces">}</span></pre>
</div>
<p>However, as it turned out, transparent components don&#8217;t receive mouse events, so the mouse<br />
wheel worked only when the mouse pointer was on top of a non-transparent object. So, to work<br />
around this, I had to fill the scroll view background using an opaque rectangle. The resulting<br />
ScrollView component looks like this:</p>
<div class="codebox">
<pre><span class="Include"><span class="ReservedWord">package</span> scrollviewdemo;</span>

<span class="Include"><span class="ReservedWord">import</span> javafx.scene.CustomNode;</span>
<span class="Include"><span class="ReservedWord">import</span> javafx.scene.Group;</span>
<span class="Include"><span class="ReservedWord">import</span> javafx.scene.Node;</span>
<span class="Include"><span class="ReservedWord">import</span> javafx.scene.control.ScrollBar;</span>
<span class="Include"><span class="ReservedWord">import</span> javafx.util.Math;</span>
<span class="Include"><span class="ReservedWord">import</span> javafx.scene.shape.Rectangle;</span>
<span class="Include"><span class="ReservedWord">import</span> javafx.scene.paint.Paint;</span>

<span class="ReservedWord">public</span> <span class="ReservedWord">class</span> <span class="Identifier">ScrollView</span> <span class="ReservedWord">extends</span> <span class="Identifier">CustomNode</span> <span class="Braces">{</span>
    <span class="ReservedWord">public-init</span> <span class="ReservedWord">var</span> <span class="Identifier">node</span><span class="Symbol">:</span> <span class="Identifier">Node</span><span class="Symbol">;</span>
    <span class="ReservedWord">public</span> <span class="ReservedWord">var</span> <span class="Identifier">width</span><span class="Symbol">:</span> <span class="Identifier">Float</span><span class="Symbol">;</span>
    <span class="ReservedWord">public</span> <span class="ReservedWord">var</span> <span class="Identifier">height</span><span class="Symbol">:</span> <span class="Identifier">Float</span><span class="Symbol">;</span>
    <span class="ReservedWord">public</span> <span class="ReservedWord">var</span> <span class="Identifier">fill</span><span class="Symbol">:</span> <span class="Identifier">Paint</span><span class="Symbol">;</span>

    <span class="ReservedWord">var</span> <span class="Identifier">group</span><span class="Symbol">:</span> <span class="Identifier">Group</span><span class="Symbol">;</span>
    <span class="ReservedWord">var</span> <span class="Identifier">gap</span> <span class="Symbol">=</span> <span class="ReservedWord">bind</span> <span class="Identifier">group</span>.<span class="Identifier">layoutBounds</span>.<span class="Identifier">height</span> <span class="Symbol">-</span> <span class="Identifier">height</span><span class="Symbol">;</span>

    <span class="ReservedWord">def</span> <span class="Identifier">scrollBar</span><span class="Symbol">:</span> <span class="Identifier">ScrollBar</span> <span class="Symbol">=</span> <span class="Identifier">ScrollBar</span> <span class="Braces">{</span>
        <span class="Identifier">translateX</span><span class="Symbol">:</span> <span class="ReservedWord">bind</span> <span class="Identifier">width</span> <span class="Symbol">-</span> <span class="Identifier">scrollBar</span>.<span class="Identifier">width</span>
        <span class="Identifier">min</span><span class="Symbol">:</span> <span class="Numeric">0</span>
        <span class="Identifier">max</span><span class="Symbol">:</span> <span class="ReservedWord">bind</span> <span class="Identifier">Math</span>.<span class="Identifier">max</span><span class="Braces">(</span><span class="Numeric">0</span>, <span class="Identifier">gap</span><span class="Braces">)</span>
        <span class="Identifier">visible</span><span class="Symbol">:</span> <span class="ReservedWord">bind</span> <span class="Identifier">gap</span> <span class="Symbol">&gt;</span> <span class="Numeric">0</span>
        <span class="Identifier">vertical</span><span class="Symbol">:</span> <span class="ReservedWord">true</span>
        <span class="Identifier">height</span><span class="Symbol">:</span> <span class="ReservedWord">bind</span> <span class="Identifier">height</span>
    <span class="Braces">}</span>

    <span class="ReservedWord">override</span> <span class="ReservedWord">function</span> <span class="Identifier">create</span><span class="Braces">(</span><span class="Braces">)</span> <span class="Braces">{</span>
        <span class="Identifier">Group</span> <span class="Braces">{</span>
            <span class="Identifier">content</span><span class="Symbol">:</span> <span class="Braces">[</span>
                <span class="Identifier">Rectangle</span> <span class="Braces">{</span>
                    <span class="Identifier">fill</span><span class="Symbol">:</span> <span class="ReservedWord">bind</span> <span class="Identifier">fill</span>
                    <span class="Identifier">width</span><span class="Symbol">:</span> <span class="ReservedWord">bind</span> <span class="Identifier">width</span> <span class="Symbol">-</span> <span class="Braces">{</span><span class="ReservedWord">if</span> <span class="Braces">(</span><span class="Identifier">gap</span> <span class="Symbol">&gt;</span> <span class="Numeric">0</span><span class="Braces">)</span> <span class="Identifier">scrollBar</span>.<span class="Identifier">width</span> <span class="ReservedWord">else</span> <span class="Numeric">0</span><span class="Braces">}</span>
                    <span class="Identifier">height</span><span class="Symbol">:</span> <span class="ReservedWord">bind</span> <span class="Identifier">height</span>
                <span class="Braces">}</span>,
                <span class="Identifier">Group</span> <span class="Braces">{</span>
                    <span class="Identifier">content</span><span class="Symbol">:</span> <span class="Braces">[</span>
                        <span class="Identifier">group</span> <span class="Symbol">=</span> <span class="Identifier">Group</span> <span class="Braces">{</span>
                            <span class="Identifier">translateY</span><span class="Symbol">:</span> <span class="ReservedWord">bind</span> <span class="Symbol">-</span> <span class="Identifier">scrollBar</span>.<span class="Identifier">value</span>
                            <span class="Identifier">content</span><span class="Symbol">:</span> <span class="Braces">[</span><span class="Identifier">node</span><span class="Braces">]</span>
                        <span class="Braces">}</span>
                    <span class="Braces">]</span>
                    <span class="Identifier">clip</span><span class="Symbol">:</span> <span class="Identifier">Rectangle</span> <span class="Braces">{</span>
                        <span class="Identifier">width</span><span class="Symbol">:</span> <span class="ReservedWord">bind</span> <span class="Identifier">width</span> <span class="Symbol">-</span> <span class="Braces">{</span><span class="ReservedWord">if</span> <span class="Braces">(</span><span class="Identifier">gap</span> <span class="Symbol">&gt;</span> <span class="Numeric">0</span><span class="Braces">)</span> <span class="Identifier">scrollBar</span>.<span class="Identifier">width</span> <span class="ReservedWord">else</span> <span class="Numeric">0</span><span class="Braces">}</span>
                        <span class="Identifier">height</span><span class="Symbol">:</span> <span class="ReservedWord">bind</span> <span class="Identifier">height</span>
                    <span class="Braces">}</span>
                <span class="Braces">}</span>,
                <span class="Identifier">scrollBar</span>
            <span class="Braces">]</span>
        <span class="Braces">}</span>
    <span class="Braces">}</span>

    <span class="ReservedWord">override</span> <span class="ReservedWord">var</span> <span class="Identifier">onMouseWheelMoved</span> <span class="Symbol">=</span> <span class="ReservedWord">function</span><span class="Braces">(</span><span class="Identifier">event</span><span class="Braces">)</span> <span class="Braces">{</span>
        <span class="Comment">// multiplying by 4 makes the scrolling faster and still smooth</span>
        <span class="Identifier">scrollBar</span>.<span class="Identifier">value</span> <span class="Symbol">+</span><span class="Symbol">=</span> <span class="Identifier">event</span>.<span class="Identifier">wheelRotation</span> <span class="Symbol">*</span> <span class="Numeric">4</span><span class="Symbol">;</span>
    <span class="Braces">}</span>
<span class="Braces">}</span></pre>
</div>
<p>And the following line should be added to the Main.fx to make it work:</p>
<div class="codebox">
<pre><span class="Include"><span class="ReservedWord">package</span> scrollviewdemo;</span>

<span class="Include"><span class="ReservedWord">import</span> javafx.stage.Stage;</span>
<span class="Include"><span class="ReservedWord">import</span> javafx.scene.Scene;</span>
<span class="Include"><span class="ReservedWord">import</span> javafx.scene.layout.VBox;</span>
<span class="Include"><span class="ReservedWord">import</span> javafx.scene.image.Image;</span>
<span class="Include"><span class="ReservedWord">import</span> javafx.scene.image.ImageView;</span>
<span class="Include"><span class="ReservedWord">import</span> javafx.scene.paint.Color;</span>

<span class="ReservedWord">var</span> <span class="Identifier">stage</span><span class="Symbol">:</span> <span class="Identifier">Stage</span> <span class="Symbol">=</span> <span class="Identifier">Stage</span> <span class="Braces">{</span>
    <span class="Identifier">title</span><span class="Symbol">:</span> <span class="String">&quot;Application title&quot;</span>
    <span class="Identifier">width</span><span class="Symbol">:</span> <span class="Numeric">200</span>
    <span class="Identifier">height</span><span class="Symbol">:</span> <span class="Numeric">200</span>
    <span class="Identifier">scene</span><span class="Symbol">:</span> <span class="Identifier">Scene</span> <span class="Braces">{</span>
        <span class="Identifier">content</span><span class="Symbol">:</span> <span class="Braces">[</span>
            <span class="Identifier">ScrollView</span> <span class="Braces">{</span>
                <span class="Identifier">width</span><span class="Symbol">:</span> <span class="ReservedWord">bind</span> <span class="Identifier">stage</span>.<span class="Identifier">scene</span>.<span class="Identifier">width</span>
                <span class="Identifier">height</span><span class="Symbol">:</span> <span class="ReservedWord">bind</span> <span class="Identifier">stage</span>.<span class="Identifier">scene</span>.<span class="Identifier">height</span>
                <span style="background: yellow;"><span class="Identifier">fill</span><span class="Symbol">:</span> <span class="Identifier">Color</span>.<span class="Identifier">WHITE</span></span>
                <span class="Identifier">node</span><span class="Symbol">:</span> <span class="Identifier">VBox</span> <span class="Braces">{</span>
                    <span class="Identifier">content</span><span class="Symbol">:</span> <span class="ReservedWord">for</span> <span class="Braces">(</span><span class="Identifier">i</span> <span class="ReservedWord">in</span> <span class="Braces">[</span><span class="Numeric">0</span>..<span class="Numeric">20</span><span class="Braces">]</span><span class="Braces">)</span> <span class="Identifier">ImageView</span> <span class="Braces">{</span>
                        <span class="Identifier">image</span><span class="Symbol">:</span> <span class="Identifier">Image</span> <span class="Braces">{</span>
                            <span class="Comment">// some picture</span>
                            <span class="Identifier">url</span><span class="Symbol">:</span> <span class="String">&quot;{__DIR__}pic.png&quot;</span>
                        <span class="Braces">}</span>
                    <span class="Braces">}</span>
                <span class="Braces">}</span>
            <span class="Braces">}</span>
        <span class="Braces">]</span>
    <span class="Braces">}</span>
<span class="Braces">}</span></pre>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.alutam.com/2009/08/30/implementing-a-scroll-view-in-javafx/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
