Pressing on with Poster
Hooray! After moaning about it here yesterday, the bug that's been holding up development of my desktop blogging app "Poster" has finally been vanquished. Finally I can move on with functionality.
It turned out to be something quite esoteric and unlikely, For the sake of anyone else having the same problem and Googling for it in vain, as I did repeatedly, here is the solution. If you're not interested in Java/SWT programming you should probably skip the rest of this post, or risk extreme boredom ...
Anyway, Poster is written in Java, and uses Eclipse's SWT libraries for its GUI. At first everything was peachy, but as time went on I was noticing more and more random lock-ups. Specifically, it seemed to hang if a control gained focus, and then the user pressed a key immediately afterwards. For example, if the user clicked a text box and immediately started typing, the whole app would freeze and need to be terminated. Waiting a little while between clicking on the control and typing would prevent it from happening, but that period got longer and longer as more buttons were added to the toolbar of the main window, confusingly. (It may simply be that more visible controls = longer wait time between the text box receiving focus and being able to handle key events.) However, once one control had successfully handled a key event, a lock-up would never happen no matter how fast the user was. It was only ever on the first key event handled.
The code which kicked off the app and started the main message loop looked something like this (with apologies for crappy indentation):
public PosterApp
{
private Display m_display = new Display();
public startApp()
{
// MainWindow is a wrapper around Shell
MainWindow appWindow = new MainWindow();
while(!m_display.isDisposed() && !appWindow.isDisposed())
{
if(!m_display.readAndDispatch())
{
m_display.sleep();
}
}
if(!m_display.isDisposed())
{
m_display.dispose();
}
}
public static void main(String[] sArgs)
{
PosterApp app = new PosterApp();
app.startApp();
}
}
Pretty standard stuff for an SWT app. Further investigation revealed that it was hanging somewhere in m_display.readAndDispatch();, though down in the native library layer, so I couldn't debug the actual SWT code.
Anyway, after banging my head against it for a while, and trying various things without success, I decided to hack in a version of Sleak, grasping at that last straw which suggested that maybe it was all down to me not disposing of some SWT resources.
To do so, I had to move the instantiation of the Display object ...
public PosterApp
{
private Display m_display;
public startApp()
{
m_display = new Display();
// MainWindow is a wrapper around Shell
MainWindow appWindow = new MainWindow();
...
... And, lo and behold, all my random crashes went away! It seems that instantiating the Display in the header of my class was causing strange issues that instantiating it in the startApp method resolved, but don't ask me why. I'm just glad it's working. I should probably note that this only seemed to happen on Windows. I never saw this happen on OS X, and haven't tried it on Linux. I suspect it's some quirk of the Windows implementation of SWT.
Labels: development, java, poster
