views:

318

answers:

3

I am trying to set the look and feel (LAF) of a Java applet that is used via a web browser. I wish to set the system default LAF, but when loaded in a browser, the applet returns to the Metal LAF. When I run it as a stand-alone applet, the LAF is applied correctly. The only item I am showing the user is a JFileChooser. I have tried a number of methods to overcome this including:

1) Override the applet's start() method:

@Override
public void start() {
    try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        SwingUtilities.updateComponentTreeUI(this);
        System.out.println("LOOK AND FEEL SET!");
    }
    catch (Exception ex) {
        System.out.println(ex);
    }
}

2) Set it in the static initializer of the applet class:

static {
    try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        System.out.println("LOOK AND FEEL SET!");
    }
    catch (Exception ex) {
        System.out.println(ex);
    }
}

3) Set it in the constructor of the applet:

public MyApplet() {
    try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        SwingUtilities.updateComponentTreeUI(this);
        System.out.println("LOOK AND FEEL SET!");
    }
    catch (Exception ex) {
        System.out.println(ex);
    }
}

I am using Java 6, but targeting Java 5 on Windows. In every case, LOOK AND FEEL SET! gets printed to the console, so I know that it set it without throwing an exception. This happens irrespective of browser (using Firefox 3.6 and IE7). Why is it doing this and how can I get it to respect the LAF I designate?

A: 

I used this code in an applet I developed recently:

public void init() {
    try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (Exception ex) {
        // Just accept the default L&F
    }
    SwingUtilities.updateComponentTreeUI(this);
    super.init();

    // Now add components...
}

See also http://stackoverflow.com/questions/1606011/look-and-feel-of-an-applet-window-changes-on-subsequent-displays (I have not solved this problem because my applet did not need to open pop-up windows.)

finnw
A: 

So I tried finnw's answer and marked it accepted without realizing that I had also made some other modifications to my code. When I was cleaning out code I removed my mods and left finnw's, but then it was broken again.

These were the changes that had made that worked:

JFileChooser chooser = new JFileChooser();

try {
    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    SwingUtilities.updateComponentTreeUI(chooser);
}
catch (Exception ex) {
    System.out.println(ex);
}

So what I ended up doing here is setting the look and feel for the file chooser outright, instead of trying to force the LAF for the whole applet. It's kind of a hack, but the file chooser is the only part of the UI that the user even sees anyway.

Wayne Hartman
A: 

There does appear to be one obscure mistake that virtually every applet ever makes. Swing (also AWT components) is being used off the AWT Event Dispatch Thread (EDT). The applet threading model is a little eccentric.

This is the one time when invokeAndWait should be used with this extreme boilerplate:

@Override public void init() {
     try {
         java.awt.EventQueue.invokeAndWait(new Runnable() { public void run() {
             initEDT();
         }});
    } catch (java.lang.InterruptedException exc) {
         Thread.currentThread().interrupt();
    } catch (java.lang.reflect.InvocationTargetException exc) {
         throw new Error(exc.getCause());
    }
}
Tom Hawtin - tackline