Java MessageBox problems...

Discussion in 'Mac Programming' started by Sean7512, May 13, 2009.

  1. Sean7512 macrumors 6502a

    Joined:
    Jun 8, 2005
    #1
    Hey Guys,

    I am working on a fairly complex project and all is well in Windows and Mac OS X. However, I am having a problem under Linux. Below is my code (simplified) that is causing the problem:

    Code:
    String hash = "testing";
    if(hash.equals("test")) {
         System.out.println("Equal.");
         return;
    }
    else {
         JOptionPane.showMessageDialog(null, "Error Encountered", "Error",
    			JOptionPane.ERROR_MESSAGE, null);
    }
    
    Under Windows and OS X, the message dialogue window displays just fine. However under Ubuntu 9.04 and Eclipse, it is only shown briefly (less than a second) and Eclipse throws the following exception...

    Disposal was interrupted:
    java.lang.InterruptedException
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Object.java:485)
    at java.awt.EventQueue.invokeAndWait(EventQueue.java:992)
    at java.awt.Window.doDispose(Window.java:1029)
    at java.awt.Dialog.doDispose(Dialog.java:1248)
    at java.awt.Window.dispose(Window.java:972)
    at javax.swing.JOptionPane.showOptionDialog(JOptionPane.java:854)
    at javax.swing.JOptionPane.showMessageDialog(JOptionPane.java:650)
    at gui.MyClass.go(MyClass.java:82)
    at gui.MyClass.main(MyClass.java:43)

    It originates at the first line of JOptionPane.showMessageDialog... Is there something wrong with this in Linux that may be different than other OSes?

    If anyone has a clue, I'd greatly appreciate it!

    Thanks
     
  2. Woei macrumors newbie

    Joined:
    May 17, 2009
    Location:
    Brussels
    #2
    Looking at that stacktrace it seems fairly certain you're sinning against the golden rule of Swing: thou shalt not alter showing Swing components or make AWT peers realised on any thread but the Event Dispatch Thread (or EDT) . The thread that starts your application (by calling the main() method) is, unsurprisingly, called the Main thread. In that thread you can do anything you like (numbercrunching, looping on a network event loop, whathever), but If you want to show a JOptionPane, you should call one of JOptionPane's static convenience methods on the EDT. To do that, you'd call the EventQueue.invokeLater() method, passing is a Runnable that will be invoked on the EDT. Normally, that Runnable will just point to some method to kick of window and hierarchy construction. Once the window is shown on the screen, any events for which you have registered listeners will be called on the EDT, so it is safe to alter parts of your GUI from those callback methods.

    So, if you're writing a Swing GUI, you'd normally do something like this:

    Code:
    public static void main(final String[] args) {
      EventQueue.invokeLater(new Runnable() {
         public void run() { constructGui(args); }
      });
    }
    
    private static void constructGui(String[] args) {
       // safe to display Swing components, and do
       // argument parsing
    }
    
    That your code works on Windows and Mac OS X but not on Linux is pure coincidence. I've seen the most bizarre phenomenons (rendering glitches, exceptions and deadlocks) by not abiding by the one-desginated-thread-for-Swing rule. You're bound to run into the same problems on Windows and OS X too.

    See the EventQueue JavaDoc, the AWT threading rules and these search results for more information.
     

Share This Page