<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Vincent Zurczak&#039;s Blog</title>
	<atom:link href="http://vzurczak.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://vzurczak.wordpress.com</link>
	<description>My technical blog</description>
	<lastBuildDate>Tue, 17 Jan 2012 14:03:52 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='vzurczak.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Vincent Zurczak&#039;s Blog</title>
		<link>http://vzurczak.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://vzurczak.wordpress.com/osd.xml" title="Vincent Zurczak&#039;s Blog" />
	<atom:link rel='hub' href='http://vzurczak.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Git, Patches and new Contributors</title>
		<link>http://vzurczak.wordpress.com/2012/01/05/git-patches-new-contributors/</link>
		<comments>http://vzurczak.wordpress.com/2012/01/05/git-patches-new-contributors/#comments</comments>
		<pubDate>Thu, 05 Jan 2012 21:51:41 +0000</pubDate>
		<dc:creator>vzurczak</dc:creator>
				<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Diff files]]></category>
		<category><![CDATA[Eclipse contributions]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[Paches]]></category>

		<guid isPermaLink="false">http://vzurczak.wordpress.com/?p=325</guid>
		<description><![CDATA[I have recently committed in the Eclipse BPEL Designer some patches that were contributed in our Bugzilla. This fact itself is not important. However, I used the Git command apply and kept the author name in the commit. I had never used this feature before, but it is extremely powerful. And very convenient to track [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=vzurczak.wordpress.com&amp;blog=10081016&amp;post=325&amp;subd=vzurczak&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I have recently committed in the Eclipse BPEL Designer some patches that were contributed in our Bugzilla. This fact itself is not important. However, I used the Git command <strong>apply</strong> and kept the author name in the commit. I had never used this feature before, but it is extremely powerful. And very convenient to <strong>track activities and propose new committers on a project</strong>.</p>
<p>I let some traces in this article (as an example and for me, for later).<br />
Notice that the <strong>apply</strong> command did not work with EGit, I had to use the command line. I guess it will be fixed in a future version.</p>
<ul>
<li>First, we need a patch, given as a diff file, e.g. in <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=357512">a bug entry</a>.</li>
<li>As a committer, you should apply and check this patch. So, you first need to copy the patch in your (cloned) Git repository.</li>
<li>Get some stats about the patch :
<pre><em>git apply --stat myPatchFile</em></pre>
</li>
</ul>
<ul>
<li>Make sure the patch can be applied :
<pre><em>git apply --check myPatchFile</em></pre>
</li>
</ul>
<ul>
<li>Apply the patch :
<pre><em>git apply myPatchFile</em></pre>
</li>
</ul>
<ul>
<li>Delete the patch file.</li>
</ul>
<p>Then, you can check that the patch works and then commit it, before pushing the modification.<br />
One important thing is to keep the author&#8217;s name in the commit. The author and the committer are different. And both can be kept in the commit and in the history. Here is an example in the command line:</p>
<blockquote>
<pre>git commit -a --author="authorUsername &lt;author.mail.address@sth.com&gt;"</pre>
</blockquote>
<p>After the push, both the author and commiter names will appear in the repository.</p>
<p><a href="http://vzurczak.files.wordpress.com/2012/01/git-patches.jpg"><img class="alignnone size-medium wp-image-326" title="Git-Patches" src="http://vzurczak.files.wordpress.com/2012/01/git-patches.jpg?w=300&#038;h=61" alt="The author and committer names appear in the history" width="300" height="61" /></a></p>
<p>I don&#8217;t know if everyone in Eclipse projects uses this feature, but from the community perspective, this is very interesting (IMO).</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/vzurczak.wordpress.com/325/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/vzurczak.wordpress.com/325/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/vzurczak.wordpress.com/325/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/vzurczak.wordpress.com/325/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/vzurczak.wordpress.com/325/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/vzurczak.wordpress.com/325/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/vzurczak.wordpress.com/325/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/vzurczak.wordpress.com/325/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/vzurczak.wordpress.com/325/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/vzurczak.wordpress.com/325/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/vzurczak.wordpress.com/325/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/vzurczak.wordpress.com/325/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/vzurczak.wordpress.com/325/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/vzurczak.wordpress.com/325/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=vzurczak.wordpress.com&amp;blog=10081016&amp;post=325&amp;subd=vzurczak&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://vzurczak.wordpress.com/2012/01/05/git-patches-new-contributors/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/45cf3bb2253fd4285acb0cfeba915a18?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">vzurczak</media:title>
		</media:content>

		<media:content url="http://vzurczak.files.wordpress.com/2012/01/git-patches.jpg?w=300" medium="image">
			<media:title type="html">Git-Patches</media:title>
		</media:content>
	</item>
		<item>
		<title>Enhanced Tabs thanks to ScrolledPageBook</title>
		<link>http://vzurczak.wordpress.com/2012/01/04/enhanced-tabs-thanks-to-scrolledpagebook/</link>
		<comments>http://vzurczak.wordpress.com/2012/01/04/enhanced-tabs-thanks-to-scrolledpagebook/#comments</comments>
		<pubDate>Wed, 04 Jan 2012 21:49:45 +0000</pubDate>
		<dc:creator>vzurczak</dc:creator>
				<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Java tips]]></category>
		<category><![CDATA[Scrolled Page Book]]></category>
		<category><![CDATA[SWT]]></category>
		<category><![CDATA[Tabs]]></category>

		<guid isPermaLink="false">http://vzurczak.wordpress.com/?p=312</guid>
		<description><![CDATA[With SWT, tab folders are a way to integrate in a same container several widgets. However, it appears to be quite limited in terms of design and creativity. I here propose some alternatives for sexier user interfaces. Tab Folder This is our witness section. Here is a snippet (the full code is avilable at the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=vzurczak.wordpress.com&amp;blog=10081016&amp;post=312&amp;subd=vzurczak&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>With SWT, <a href="http://www.eclipse.org/swt/widgets/">tab folders</a> are a way to integrate in a same container several widgets. However, it appears to be quite limited in terms of design and creativity. I here propose some alternatives for sexier user interfaces.</p>
<h2>Tab Folder</h2>
<p>This is our witness section.<br />
Here is a snippet (the full code is avilable at the end of the article)&#8230;</p>
<p><pre class="brush: java;">public void createTabs( Composite parent ) {

	final TabFolder tabFolder = new TabFolder( parent, SWT.NONE );
	tabFolder.setLayoutData( new GridData( GridData.FILL_BOTH ));

	for( int i=0; i&lt;=4; i++) {
		TabItem tabItem = new TabItem( tabFolder, SWT.NONE );
		tabItem.setText( &quot;Item &quot; + i );
		tabItem.setControl( createTabContent( tabFolder ));
	}
}

private Composite createTabContent( Composite parent ) {

	Composite c = new Composite( parent, SWT.NONE );
	c.setLayout( new GridLayout( 2, false ));
	String[] properties = { &quot;First Name:&quot;, &quot;Last Name:&quot;, &quot;Nick Name:&quot; };

	for( String property : properties ) {
		new Label( c, SWT.NONE ).setText( property );
		new Text( c, SWT.SINGLE | SWT.BORDER ).setLayoutData( new GridData( GridData.FILL_HORIZONTAL ));
	}

	return c;
}</pre></p>
<p>And here is a screenshot.</p>
<p><a href="http://vzurczak.files.wordpress.com/2012/01/enhanced-tabs-thanks-to-scrolledpagebook-tabfolder.jpg"><img class="alignnone size-medium wp-image-313" title="Enhanced-Tabs-thanks-to-ScrolledPageBook--TabFolder" src="http://vzurczak.files.wordpress.com/2012/01/enhanced-tabs-thanks-to-scrolledpagebook-tabfolder.jpg?w=300&#038;h=203" alt="An example with a Tab folder" width="300" height="203" /></a></p>
<p>As you can see, everything is centered, except the tabs.<br />
And that&#8217;s not cool at all.</p>
<h2>Custom Tab Folder</h2>
<p>The <a href="http://help.eclipse.org/indigo/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/custom/CTabFolder.html">CTabFolder class</a> is a little more powerful, but similar limitations appear quickly. It is not possible to center the tabs. And they are either above or below the content, never on side.</p>
<p><a href="http://vzurczak.files.wordpress.com/2012/01/enhanced-tabs-thanks-to-scrolledpagebook-ctabfolder.jpg"><img class="alignnone size-medium wp-image-314" title="Enhanced-Tabs-thanks-to-ScrolledPageBook--CTabFolder" src="http://vzurczak.files.wordpress.com/2012/01/enhanced-tabs-thanks-to-scrolledpagebook-ctabfolder.jpg?w=300&#038;h=201" alt="An example with a CTab folder" width="300" height="201" /></a></p>
<p><pre class="brush: java;">public void createTabs( Composite parent ) {

	final CTabFolder tabFolder = new CTabFolder( parent, SWT.BORDER );
	tabFolder.setLayoutData( new GridData( GridData.FILL_BOTH ));
	tabFolder.setSimple( false );

	for( int i=0; i&lt;=4; i++ ) {
		CTabItem tabItem = new CTabItem( tabFolder, SWT.NONE );
		tabItem.setText( &quot; Item &quot; + i + &quot; &quot; );
		tabItem.setControl( createTabContent( tabFolder ));
	}
}</pre></p>
<p>Note that you can <a href="http://www.java2s.com/Tutorial/Java/0280__SWT/AddImagetoCTabFolder.htm">add images</a> on the tab.</p>
<h2>Scrolled Page Book</h2>
<p>An alternative to these classes is <a href="http://help.eclipse.org/indigo/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/ui/forms/widgets/ScrolledPageBook.html">ScrolledPageBook</a>.<br />
It can be used in Eclipse plugins, but also in standalone applications. In addition to SWT bundles, you only have to add <strong>org.eclipse.ui.forms</strong> to your classpath. No need to be in a form to use it.</p>
<p>Let&#8217;s see a first illustration, with navigation labels and not (yet) tabs.<br />
The principle is simple: you have a set of labels and a scrolled page book. When the user clicks on a label, we change the displayed page in the book.</p>
<p><pre class="brush: java;">public void createTabs( Composite parent ) {

	// Add the container for navigation labels
	final int tabCpt = 5;
	Composite container = new Composite( parent, SWT.NONE );
	container.setLayout( new GridLayout( tabCpt, true ));
	container.setLayoutData( new GridData( SWT.CENTER, SWT.DEFAULT, true, false ));

	// Add the page book
	final ScrolledPageBook pageBook = new ScrolledPageBook( parent );
	pageBook.setLayoutData( new GridData( GridData.FILL_BOTH ));

	// The listener when the user clicks on a &quot;tab&quot;
	Listener listener = new Listener() {
		@Override
		public void handleEvent( Event event ) {
			pageBook.showPage( event.widget.getData());
		}
	};

	// Register the pages and bind it all
	for( int i=0; i&lt;=4; i++ ) {
		Label l = new Label( container, SWT.BORDER );
		l.setText( &quot;Item &quot; + i );
		l.setData( i );

		pageBook.registerPage( i, createTabContent( pageBook.getContainer(), i ));
		l.addListener( SWT.MouseDown, listener );
	}

	// Force to display the first tab
	pageBook.showPage( 0 );
}</pre></p>
<p>And here is a preview.</p>
<p><a href="http://vzurczak.files.wordpress.com/2012/01/enhanced-tabs-thanks-to-scrolledpagebook-simple-scrolledpagebook.jpg"><img class="alignnone size-medium wp-image-315" title="Enhanced-Tabs-thanks-to-ScrolledPageBook--Simple-ScrolledPageBook" src="http://vzurczak.files.wordpress.com/2012/01/enhanced-tabs-thanks-to-scrolledpagebook-simple-scrolledpagebook.jpg?w=300&#038;h=202" alt="A first try with a scrolled page book" width="300" height="202" /></a></p>
<p>Ugly, isn&#8217;t it?<br />
But we can fix it.</p>
<h2>Tabs with a Scrolled Page Book</h2>
<p>To have a real tab&#8217;s look &amp; feel, we have to reduce the margin between the content and the labels. We also need make our labels look better. Partial borders will be added around the labels thanks to a paint listener.</p>
<p><a href="http://vzurczak.files.wordpress.com/2012/01/enhanced-tabs-thanks-to-scrolledpagebook-tabs-with-scrolledpagebook.jpg"><img class="alignnone size-medium wp-image-316" title="Enhanced-Tabs-thanks-to-ScrolledPageBook--Tabs-With-ScrolledPageBook" src="http://vzurczak.files.wordpress.com/2012/01/enhanced-tabs-thanks-to-scrolledpagebook-tabs-with-scrolledpagebook.jpg?w=300&#038;h=200" alt="Tabs with a scrolled page book" width="300" height="200" /></a></p>
<p>Here is the code (it&#8217;s a little bit longer than before).</p>
<p><pre class="brush: java;">/**
 * Remember the selected index.
 */
private Integer selectedIndex = 0;

/**
 * Creates the tabs.
 * @param parent the parent
 */
public void createTabs( Composite parent ) {
		
	// Add the container for navigation labels
	final int tabCpt = 5;
	Composite container = new Composite( parent, SWT.NONE );
	GridLayout layout = new GridLayout( tabCpt, true );
	layout.marginHeight = 0;
	container.setLayout( layout );
	container.setLayoutData( new GridData( SWT.CENTER, SWT.DEFAULT, true, false ));
		
	// Add the page book
	final ScrolledPageBook pageBook = new ScrolledPageBook( parent );
	pageBook.setLayoutData( new GridData( GridData.FILL_BOTH ));
		
	// The listener when the user clicks on a &quot;tab&quot;
	final List&lt;Label&gt; navigationLabels = new ArrayList&lt;Label&gt; ();
	Listener listener = new Listener() {
		@Override
		public void handleEvent( Event event ) {
			pageBook.showPage( event.widget.getData());
				
			// Remember the last selected index
			TabsWithScrolledPageBookSnippet.this.selectedIndex = (Integer) event.widget.getData();
			
			// Highlight the selected tab
			for( Label l : navigationLabels ) {
				Color color;
				if( l != event.widget &amp;&amp; l.getParent() != event.widget )
					color = Display.getDefault().getSystemColor( SWT.COLOR_WIDGET_BACKGROUND );
				else
					color = Display.getDefault().getSystemColor( SWT.COLOR_WHITE );
					
				l.setBackground( color );
				l.getParent().setBackground( color );
			}
		}
	};
		
	// The paint listener, to paint partial borders
	PaintListener paintListener = new PaintListener() {
		@Override
		public void paintControl( PaintEvent event ) {
			
			Color color;
			if( TabsWithScrolledPageBookSnippet.this.selectedIndex.equals( event.widget.getData()))
				color = Display.getDefault().getSystemColor( SWT.COLOR_GRAY );
			else
				color = Display.getDefault().getSystemColor( SWT.COLOR_WIDGET_DARK_SHADOW );
				
			Rectangle rect = ((Composite) event.widget).getBounds();
			event.gc.setForeground( color );
			event.gc.setAntialias( SWT.ON );
			event.gc.drawLine( 0, 0, rect.width - 1, 0 );
			event.gc.drawLine( 0, 0, 0, rect.height - 1 );
			event.gc.drawLine( rect.width - 1, 0, rect.width - 1, rect.height - 1 );
		}
	};
		
	// Register the pages and bind it all
	for( int i=0; i&lt;tabCpt; i++ ) {
		Label l = createTabLabel( i, container, paintListener, listener );
		navigationLabels.add( l );
		pageBook.registerPage( i, createTabContent( pageBook.getContainer(), i ));
	}
		
	// Force to display the first tab (and force it to be highlighted)
	navigationLabels.get( 0 ).notifyListeners( SWT.MouseDown, new Event());
}
	
	
/**
 * Creates a label for the tab (wrapped in a composite for better display).
 * @param index the tab index
 * @param parent the container for the label
 * @param paintListener the paint listener for the label's container (to paint partial borders)
 * @param mouseDownListener the listener for when a tab is selected
 * @return the created label
 */
private Label createTabLabel( int index, Composite parent, PaintListener paintListener, Listener mouseDownListener ) {
	
	// Wrap the labels in a composite
	Composite c = new Composite( parent, SWT.NONE );
	c.setLayout( new GridLayout());
	c.setLayoutData( new GridData( 80, 25 ));
	c.setData( index );

	// To paint partial borders
	c.addPaintListener( paintListener );

	// Deal with the content
	Label l = new Label( c, SWT.NONE );
	l.setLayoutData( new GridData( SWT.CENTER, SWT.CENTER, true, true ));
	l.setText( &quot;Item &quot; + index );
	l.setData( index );

	// The click listener
	l.addListener( SWT.MouseDown, mouseDownListener );
	c.addListener( SWT.MouseDown, mouseDownListener );

	return l;
}</pre></p>
</pre>
<h2>Horizontal Tabs</h2>
<p>By playing with the previous example, we can also obtain a result similar to the Eclipse tabbed properties. In the following example, the navigation labels are placed on the left of the content. I hardly changed the code (about 10 lines, it is just about the layout).</p>
<p><a href="http://vzurczak.files.wordpress.com/2012/01/enhanced-tabs-thanks-to-scrolledpagebook-other-tabs-with-scrolledpagebook.jpg"><img class="alignnone size-medium wp-image-317" title="Enhanced-Tabs-thanks-to-ScrolledPageBook--Other-Tabs-With-ScrolledPageBook" src="http://vzurczak.files.wordpress.com/2012/01/enhanced-tabs-thanks-to-scrolledpagebook-other-tabs-with-scrolledpagebook.jpg?w=300&#038;h=203" alt="Another illustration of tabs implemented with a scrolled page book" width="300" height="203" /></a></p>
<p>The code is available in the archive below.</p>
<h2>Conclusion</h2>
<p>I hope these snippets (and screenshots) will help some of you.<br />
They also illustrate the use of the Scrolled Page Book class. Obviously, this could be used to create a custom and reusable widget (as an example shared in the <a href="http://eclipse.org/nebula/">Nebula project</a>). No need to say that it would be more simple with a HTML and CSS approach. <a href="http://www.eclipse.org/e4/">E4</a> may help in such an approach.</p>
<p>The complete source code for the snippets is available in <a title="The source code" href="http://www.mediafire.com/?s0arjgxybwwewj6">this archive</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/vzurczak.wordpress.com/312/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/vzurczak.wordpress.com/312/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/vzurczak.wordpress.com/312/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/vzurczak.wordpress.com/312/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/vzurczak.wordpress.com/312/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/vzurczak.wordpress.com/312/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/vzurczak.wordpress.com/312/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/vzurczak.wordpress.com/312/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/vzurczak.wordpress.com/312/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/vzurczak.wordpress.com/312/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/vzurczak.wordpress.com/312/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/vzurczak.wordpress.com/312/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/vzurczak.wordpress.com/312/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/vzurczak.wordpress.com/312/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=vzurczak.wordpress.com&amp;blog=10081016&amp;post=312&amp;subd=vzurczak&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://vzurczak.wordpress.com/2012/01/04/enhanced-tabs-thanks-to-scrolledpagebook/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/45cf3bb2253fd4285acb0cfeba915a18?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">vzurczak</media:title>
		</media:content>

		<media:content url="http://vzurczak.files.wordpress.com/2012/01/enhanced-tabs-thanks-to-scrolledpagebook-tabfolder.jpg?w=300" medium="image">
			<media:title type="html">Enhanced-Tabs-thanks-to-ScrolledPageBook--TabFolder</media:title>
		</media:content>

		<media:content url="http://vzurczak.files.wordpress.com/2012/01/enhanced-tabs-thanks-to-scrolledpagebook-ctabfolder.jpg?w=300" medium="image">
			<media:title type="html">Enhanced-Tabs-thanks-to-ScrolledPageBook--CTabFolder</media:title>
		</media:content>

		<media:content url="http://vzurczak.files.wordpress.com/2012/01/enhanced-tabs-thanks-to-scrolledpagebook-simple-scrolledpagebook.jpg?w=300" medium="image">
			<media:title type="html">Enhanced-Tabs-thanks-to-ScrolledPageBook--Simple-ScrolledPageBook</media:title>
		</media:content>

		<media:content url="http://vzurczak.files.wordpress.com/2012/01/enhanced-tabs-thanks-to-scrolledpagebook-tabs-with-scrolledpagebook.jpg?w=300" medium="image">
			<media:title type="html">Enhanced-Tabs-thanks-to-ScrolledPageBook--Tabs-With-ScrolledPageBook</media:title>
		</media:content>

		<media:content url="http://vzurczak.files.wordpress.com/2012/01/enhanced-tabs-thanks-to-scrolledpagebook-other-tabs-with-scrolledpagebook.jpg?w=300" medium="image">
			<media:title type="html">Enhanced-Tabs-thanks-to-ScrolledPageBook--Other-Tabs-With-ScrolledPageBook</media:title>
		</media:content>
	</item>
		<item>
		<title>Detecting New Images in the Clipboard</title>
		<link>http://vzurczak.wordpress.com/2011/12/20/detecting-new-images-in-the-clipboard/</link>
		<comments>http://vzurczak.wordpress.com/2011/12/20/detecting-new-images-in-the-clipboard/#comments</comments>
		<pubDate>Tue, 20 Dec 2011 21:13:17 +0000</pubDate>
		<dc:creator>vzurczak</dc:creator>
				<category><![CDATA[Java tips]]></category>
		<category><![CDATA[clipboard monitor]]></category>
		<category><![CDATA[clipboard poller]]></category>
		<category><![CDATA[clipboard watcher]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://vzurczak.wordpress.com/?p=303</guid>
		<description><![CDATA[I have 2 applications that should work together. These applications are end-user applications. The link between them is in fact the system&#8217;s clipboard (this is a Windows 7&#8242;s use case, but it might be encountered on other platforms). Basically, the idea is that the user selects an image in the first application and copies it [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=vzurczak.wordpress.com&amp;blog=10081016&amp;post=303&amp;subd=vzurczak&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I have 2 applications that should work together.<br />
These applications are end-user applications. The link between them is in fact the system&#8217;s clipboard (this is a Windows 7&#8242;s use case, but it might be encountered on other platforms). Basically, the idea is that the user selects an image in the first application and copies it in the clipboard. The second application should detect this new image and process it.</p>
<p>By browsing the web, I found out that there is no perfect solution. Sun did not provide a complete solution for this in Java because there were portability issues. One alternative was to use the <em>ava.awt.datatransfer.ClipboardOwner</em> class. A subclass instance acquires the ownership of the clipboard by putting something into it. When another application copies something into the clipboard, the previous owner is notified that it has lost the ownership. The implementation would be something like:</p>
<p><pre class="brush: java;">public class ClipboardWatcher implements ClipboardOwner {

	/**
	 * @see java.awt.datatransfer.ClipboardOwner
	 * #lostOwnership(java.awt.datatransfer.Clipboard, java.awt.datatransfer.Transferable)
	 */
	@Override
	public void lostOwnership( Clipboard clipboard, Transferable contents ) {
		// Get the clipboard's content and process it if required
		// ...

		// Acquire the ownership again by putting the same content
		// (Same content because otherwise, copy/paste does not work anymore for other applications)
		// ...
	}
}</pre></p>
<p>This is not very convenient.<br />
I also discovered it was not working very well when there are several running applications.<br />
So, I implemented a solution with a thread which polls the clipboard regularly. I put here a complete sample with an example of image processing.</p>
<p><pre class="brush: java;">import java.awt.Image;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.imageio.ImageIO;

/**
 * @author Vincent Zurczak
 */
public class ClipboardWatcher implements ClipboardOwner {
	
	static final File PREVIEW_DIRECTORY = new File( System.getProperty( &quot;java.io.tmpdir&quot; ), &quot;Image-Store&quot; );
	private final List&lt;PreviewFileListener&gt; listeners;
	private final SimpleDateFormat sdf;
	private final AtomicBoolean run;
	
	
	/**
	 * Constructor.
	 */
	public ClipboardWatcher() {
		 this.listeners = new ArrayList&lt;PreviewFileListener&gt; ();
		 this.sdf = new SimpleDateFormat( &quot;yy-MM-dd---HH-mm-ss&quot; );
		 this.run = new AtomicBoolean( true );
		 
		 if( ! PREVIEW_DIRECTORY.exists()
				 &amp;&amp; ! PREVIEW_DIRECTORY.mkdir()) {
			 // TODO: process this case in a better way
			 System.out.println( &quot;The preview directory could not be created.&quot; );
		 }
	}
	
	
	/**
	 * @param e
	 * @return
	 * @see java.util.List#add(java.lang.Object)
	 */
	public boolean addPreviewFileListener( PreviewFileListener e ) {
		synchronized( this.listeners ) {
			return this.listeners.add( e );
		}
	}


	/**
	 * @param o
	 * @return
	 * @see java.util.List#remove(java.lang.Object)
	 */
	public boolean removePreviewFileListener( PreviewFileListener o ) {
		synchronized( this.listeners ) {
			return this.listeners.remove( o );
		}
	}
	
	
	/**
	 * @see java.awt.datatransfer.ClipboardOwner
	 * #lostOwnership(java.awt.datatransfer.Clipboard, java.awt.datatransfer.Transferable)
	 */
	@Override
	public void lostOwnership( Clipboard clipboard, Transferable contents ) {
		// Acquire the ownership again is not working very well for a periodic check
	}
	
	
	/**
	 * Starts polling the clipboard.
	 */
	public void start() {
		
		// Define the polling delay
		final int pollDelay = 5000;
		
		// Create the runnable
		Runnable runnable = new Runnable() {
			@Override
			public void run() {
				
				Transferable contents = null;
				while( ClipboardWatcher.this.run.get()) {
					
					// Get the clipboard's content
					Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
					try {
						contents = clipboard.getContents( null );
						if ( contents == null 
								|| ! contents.isDataFlavorSupported( DataFlavor.imageFlavor ))
							continue;
						
						Image img = (Image) clipboard.getData( DataFlavor.imageFlavor );
						saveClipboardImage( img );
						clipboard.setContents( new StringSelection( &quot;The clipboard watcher was here!&quot; ), ClipboardWatcher.this );
						
					} catch( UnsupportedFlavorException ex ) {
						ex.printStackTrace();

					} catch( IOException ex ) {
						ex.printStackTrace();
						
					} catch( Exception e1 ) {
						// We get here if we could not get the clipboard's content
						continue;
					
					} finally {						
					
						try {
							Thread.sleep( pollDelay );
							
						} catch( InterruptedException e ) {
							e.printStackTrace();
						}
					}
				}
			}
		};
		
		// Run it in a thread
		Thread thread = new Thread( runnable );
		thread.start();
	}
	
	
	/**
	 * Stops listening.
	 */
	public void stop() {
		this.run.set( false );
	}
	

	/**
	 * Saves the image residing on the clip board.
	 */
	public void saveClipboardImage( Image img ) {

		if( img != null ) {	    	
			if( img instanceof BufferedImage ) {
				try {
					File file = new File( PREVIEW_DIRECTORY, this.sdf.format( new Date()) + &quot;.jpg&quot; );
					ImageIO.write((BufferedImage) img, &quot;jpg&quot;, file );
					for( PreviewFileListener listener : this.listeners )
						listener.newCreatedFile( file );

				} catch ( IOException e ) {
					e.printStackTrace();
				}

			} else {
				System.out.println( &quot;Unsupported image: &quot; + img.getClass());
			}	
		}
	}
	
	
	/**
	 * A interface to listen to image detection.
	 */
	public interface PreviewFileListener {

		/**
		 * Notifies this instance that an image file was created from the clip board.
		 * @param imageFile the image file that was saved on the disk
		 */
		void newCreatedFile( File imageFile );
	}
}</pre></p>
<p>There is another alternative for Windows platforms.<br />
However, it was only implemented for an OSGi context. Notice that it should not be too difficult to adapt it for standalone Java applications. I read and understood most of the code, but I was a little bit lazy on this one. Check <a href="http://philondev.blogspot.com/2010/02/osgi-clipboard-monitor-for-java-on.html">this blog entry</a> for more details. The code is hosted <a href="https://github.com/pke/clipboard.monitor">on GitHub</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/vzurczak.wordpress.com/303/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/vzurczak.wordpress.com/303/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/vzurczak.wordpress.com/303/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/vzurczak.wordpress.com/303/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/vzurczak.wordpress.com/303/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/vzurczak.wordpress.com/303/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/vzurczak.wordpress.com/303/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/vzurczak.wordpress.com/303/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/vzurczak.wordpress.com/303/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/vzurczak.wordpress.com/303/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/vzurczak.wordpress.com/303/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/vzurczak.wordpress.com/303/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/vzurczak.wordpress.com/303/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/vzurczak.wordpress.com/303/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=vzurczak.wordpress.com&amp;blog=10081016&amp;post=303&amp;subd=vzurczak&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://vzurczak.wordpress.com/2011/12/20/detecting-new-images-in-the-clipboard/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/45cf3bb2253fd4285acb0cfeba915a18?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">vzurczak</media:title>
		</media:content>
	</item>
	</channel>
</rss>
