Thursday, December 24, 2009

Nightmare before Christmas: How to use JFace + SWT standalone

I could've as easily called this Eclipse plugins from HELL, but being Christmas and all I thought I would go for the Christmas thing, which gives me the opportunity to wish Merry Xmas to all the geeks who happen to be reading this lame-ass blog over the holidays instead of watching Star Trek as per tradition.

Being mainly a .NET guy, I am not too familiar with the eclipse platform, but I desperately needed to put together a quick UI and decided to go with JFace and SWT after @tarelli suggested so (he's the JAVA guy). Unfortunately, at the time I didn't realize he was talking about an Eclipse plugin project and not about using JFace and SWT in a standalone Java app.

So I went on and got started with some nice tutorials specific to running JFace + SWT standalone, and some more gentle introductions.

Time to get my hands dirty, so I started a new Java project, and dropped in some of the code from the tutorials. In order to get it build I needed to import JFace and SWT plugins as external jars, which I could not find anywhere in my plugins folder (I am on Galileo C:\eclipse 3.5\plugins). I needed to somehow get the damn plugins, but could not quite figure out how to get only those I needed from Help --> Install Software Updates, so I ended up pulling down anything to do with Eclipse SDK. To my delight the SWT and JFace plugins were there (in the plugins folder) after the lengthy process of downloading tons of stuff I didn't need.

After a bit of mocking about (blindly trying to import anything with jface or swt in it) I managed to understand which jars I needed to import to get the damn thing to build (org.eclipse.jface_3.5.1.M20090826-0800.jar and org.eclipse.swt.win32.win32.x86_3.5.1.v3555a.jar) I started mocking about with the code and spent a good while playing around with ContentProviders, ListViewers and so forth. Everything was building nicely, but as soon as I tried to run it as java application got the cold shower:

Exception in thread "main" java.lang.NoClassDefFoundError: org/eclipse/core/runtime/IProgressMonitor
    at demo.ui.test.EntryPoint.main(EntryPoint.java:18)
Caused by: java.lang.ClassNotFoundException: org.eclipse.core.runtime.IProgressMonitor

Apparently some type was missing somewhere. I've seen a lot of sh*t working on Visual Studio and all, but errors don't get much more cryptic than this.

After a good while, after unfruitfully trying to offline troubleshoot the heck out of my project (offline troubleshooting is just madness but I was waiting the phone company to turn on my broadband in the new apt i moved to recently), I reverted to @tarelli, the eclipse guru who got me into this mess, and begged for help: he promptly told me that I was in a bit of a feckin' mess, and if I wanted to get out of it alive I would've had to create a Plugin Project "with a view" and take it from there. I tried, and he was right, but I did not want a plugin and all the overhead that comes with it, so I kept pulling my hair for several hours with no luck, then went to bed. I felt rightly and truely screwed, if you want.

Luckily the day after the phone company turned on my broadband and I could stop passively obsessing about the problem and started aggressively abusing google in search of a solution to the problem.

After a not too long research (God bless THE INTERNET), turns out that if you want to use JFace + SWT outside a plugin based project you need some other jars. Basically if you're using JFace and SWT in a plugin project runtime dependencies are managed for you through the manifest file (I seem to understand) but if you go for the rogue option of having SWT running standalone then you need to know you need that stuff.

In the specific case of the IProgressMonitor thingy, adding a reference to the org.eclipse.equinox.common jar did the trick. After that I got the same error on a different class, EventManager, and after a couple of blind trials I got it working by importing the org.eclipse.core.commands jar. Obviously, not a mention of this in the tutorials, as I seem to understand there was a bit of refactoring on those packages after those tutorials were drafted (looks like this problem is around since eclipse 3.2 --> read this bug report for further info).

What can I say? If you're coming from .NET sometimes Java == Pain.

Thursday, December 10, 2009

What a bunch of ...

... bullshit!

The developers count on the stackoverflow ad page is clearly increased at random.

The count is being increased in a recursively called function at random intervals. Here's the javascript:


$(function(){
       
        var visitors = 5373966;
        var updateVisitors = function()
            {
                visitors++;
                
                var vs = visitors.toString(), 
                     i = Math.floor(vs.length / 3),
                     l = vs.length % 3;
                while (i-->0) if (!(l==0&&i==0))
                    vs = vs.slice(0,i*3+l)
                       + ',' 
                       + vs.slice(i*3+l);
                $('#devCount').text(vs);
                setTimeout(updateVisitors, Math.random()*2000);
            };
        
        setTimeout(updateVisitors, Math.random()*2000);
        
    });

P.S. Posting this from google SideWiki - kinda cool

in reference to: http://inedomedia.com/stackoverflow.aspx (view on Google Sidewiki)

Friday, December 4, 2009

[WPF] How to programmatically add databound item to ListView

In this post I'll show how to programmatically add databound items to a WPF ListView - it's actually pretty straightforward but it's not the most intuitive task if you don't have a lot of experience with WPF.

Here's your xaml - pay attention to the bindings on the grid columns:

<ListView.View>
   <GridView>
      <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Path=Name}"/>
      <GridViewColumn Header="Value" DisplayMemberBinding="{Binding Path=Value}"/>
   </GridView>
</ListView.View>
We need to define a data class with Name and Value properties such as:

public class BoringData
{
    public string Name { get; set; }
    public string Value { get; set; }
}
And here comes the fun - how to programmatically add items to the ListView:

//utterly boring call to generate your data item
BoringData boredom = getBoringData(index);//<-- whatever
//add the item to the listView 
this.myListView.Items.Add(boredom);
If you're thinking I post boring stuff ... well, you're right. Posts like this I mainly post so that I won't forget how it's done (and hopefully will be helpful to some other occasional WPF hacker).