views:

197

answers:

2

Anyone knows Why the laf is not changing in the following code? (running in Ubuntu)

import java.awt.Dialog;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;

public class TEST extends JPanel {

    public TEST() {
    final LookAndFeelInfo[] lafArray = UIManager.getInstalledLookAndFeels();
    String[] names = new String[lafArray.length];
    for (int i = 0; i < names.length; i++) {
        names[i] = lafArray[i].getName();
    }

    final JComboBox cb = new JComboBox(names);
    cb.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent ev) {
        try {
            int index = cb.getSelectedIndex();
            LookAndFeelInfo lafInfo = lafArray[index];
            String lafClassName = lafInfo.getClassName();
            System.out.println(lafClassName);
            UIManager.setLookAndFeel(lafClassName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        }
    });

    add(cb);
    }

    public static void main(String[] args) throws Exception {
    System.out.println("start");

    JDialog dialog = new JDialog(null, Dialog.ModalityType.APPLICATION_MODAL);
    dialog.setContentPane(new TEST());
    dialog.pack();
    dialog.setLocationRelativeTo(null);
    dialog.setVisible(true);
    dialog.dispose();

    System.out.println("end");
    }

}
+4  A: 

After you call UIManager.setLookAndFeel(lafClassName), call SwingUtilities.updateComponentTreeUI(cb.getParent). In a more complete application, you have to call it on each top level Container. You should also call pack() on the Container because of the different Component sizes between lafs.

Rob Heiser
I'll try.Strange that I didn't need this in my house running in Windows.
Tom Brito
@Tom Brito: Never-the-less, this is what Sun's tutorial tells you to do: http://java.sun.com/docs/books/tutorial/uiswing/lookandfeel/plaf.html#dynamic
R. Bemrose
Works fine for this example. But isn't there a way to update all swing components, even if they aren't in the tree?
Tom Brito
@Tom: They should always be in some tree, in one of the currently visible top-level containers. If not, they are not being displayed.
Grodriguez
+1  A: 

You shouldn't change the look and feel once a component is rendered. It must be done before initialization of a component. From here:

Note: If you are going to set the L&F, you should do it as the very first step in your application. Otherwise you run the risk of initializing the Java L&F regardless of what L&F you've requested. This can happen inadvertently when a static field references a Swing class, which causes the L&F to be loaded. If no L&F has yet been specified, the default L&F for the JRE is loaded. For Sun's JRE the default is the Java L&F, for Apple's JRE the Apple L&F, and so forth.

Jason Nichols
I want to change at runtime, like the SwingSet3 does
Tom Brito
Depending of the App, looks like the is no other choice than asking user to restart the app. Sad.
Tom Brito
Grodriguez