System look and feel layout on JFileChooser but with nimbus look and feel theme

前端 未结 2 1889
天命终不由人
天命终不由人 2021-02-09 00:49

The windows look and feel layout on JFileChooser is much better than other look and feels like nimbus.

So I\'m looking for a way to have the layout of a system look and

2条回答
  •  渐次进展
    2021-02-09 01:07

    It's possible, though I don't know whether it's recommended. I managed to get it to work by asking the view to update itself on all but the topmost JFileChooser component (since that would replace all the chooser components with the Nimbus ones which you don't want).

    I'd regard this as a hack that may or may not work depending on the internals of the Windows look and feel. It relies on pretty much the whole JFileChooser being built up by Swing components. If it ever was changed to use more direct native rendering (i.e. Java asks Windows to paint a significant portion of the chooser), it wont work. Don't know how well that trick will work with other components.

    Anyway, this code seemed to work with JDK 7:

    package test;
    
    import java.awt.Component;
    
    import javax.swing.JComponent;
    import javax.swing.JFileChooser;
    import javax.swing.UIManager;
    import javax.swing.plaf.nimbus.NimbusLookAndFeel; //Or use com.sun.... if you are using JDK < 7
    
    public class LAFTester
    {
        public static void main(String... args)
        throws Exception
        {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            JFileChooser chooser = new JFileChooser();
            chooser.updateUI(); //Create UI objects
            UIManager.setLookAndFeel(NimbusLookAndFeel.class.getName()); //Now set look and feel
            //UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); //works with metal as well
            refreshUI(chooser, false);
    
            chooser.showOpenDialog(null);
        }
    
        private static void refreshUI(JComponent c, boolean includeParent)
        {
            if (includeParent)
                c.updateUI();
    
            for (int i = 0; i < c.getComponentCount(); i++)
            {
                Component child = c.getComponent(i);
                if (child instanceof JComponent)
                {
                    refreshUI((JComponent)child, true);
                }
            }
        }
    }
    

提交回复
热议问题