JFileChooser的Windows外观

10

我正在尝试生成具有Windows外观的JFileChooser。 我找不到更改它的方法,因此我创建了一个扩展JFileChooser的基类,并使用以下代码更改其UI:

public FileChooser(){
  this(null);
}
public FileChooser(String path){
   super(path);
   try {
      UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");

    } catch (Exception e) { System.err.println("Error: " + e.getMessage()); }

然后,在另一个类中,我调用

FileChooser chooser = new FileChooser(fileName);
int val = chooser.showOpenDialog(null);

但弹出的对话框具有Java的外观和感觉。 有什么想法可以改变这种情况吗?JFileChooser类中是否有我可以使用而不是使用这个扩展类的方法?

谢谢!


1
你想让FileChooser只有Windows L&F吗? - b.roth
我原以为你必须为每个组件更改用户界面。 - chama
8个回答

15
我知道你可以设置整个应用程序的外观,但如果你喜欢跨平台的外观,但想要在JFileChoosers中使用系统外观,该怎么办?特别是跨平台甚至没有正确的文件图标(看起来非常俗气)。
这是我所做的。它绝对是一个hack...
import sun.swing.FilePane;
import javax.swing.JFileChooser;
import javax.swing.LookAndFeel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;

public class JSystemFileChooser extends JFileChooser{
    public void updateUI(){
        LookAndFeel old = UIManager.getLookAndFeel();
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }
        catch (Throwable ex) {
            old = null;
        }

        super.updateUI();

        if(old != null){
            FilePane filePane = findFilePane(this);
            filePane.setViewType(FilePane.VIEWTYPE_DETAILS);
            filePane.setViewType(FilePane.VIEWTYPE_LIST);

            Color background = UIManager.getColor("Label.background");
            setBackground(background);
            setOpaque(true);

            try {
                UIManager.setLookAndFeel(old);
            }
            catch (UnsupportedLookAndFeelException ignored) {} // shouldn't get here
        }
    }



    private static FilePane findFilePane(Container parent){
        for(Component comp: parent.getComponents()){
            if(FilePane.class.isInstance(comp)){
                return (FilePane)comp;
            }
            if(comp instanceof Container){
                Container cont = (Container)comp;
                if(cont.getComponentCount() > 0){
                    FilePane found = findFilePane(cont);
                    if (found != null) {
                        return found;
                    }
                }
            }
        }

        return null;
    }
}

1
非常感谢您提供复制粘贴的解决方案,您帮了我很多 :) - Yura Taras
太棒了!谢谢! - Mahsa

9
如果您不需要改变外观和感觉,可以尝试将UIManager.setLookAndFeel(..)代码行放置在入口类的主方法中。这对我有效,但我不知道为什么它不能按照您设置的方式工作。

1
问题在于我在显示JFileChooser之后设置了外观和感觉。我也不明白我可以一次性更改整个UI。谢谢你的提示。 - chama

4

首先,尝试从命令行运行代码并在那里指定外观以查看是否可以应用。

 java -Dswing.defaultlaf=com.sun.java.swing.plaf.windows.WindowsLookAndFeel YourApp

如果应用了正确的外观和感觉,那么在创建JFileChooser对话框之前,您可以将外观和感觉代码添加到程序中。假设一个简单的程序看起来像这样:
 public static void main(String[] args) {
try {

    UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");

} 
catch (Exception e) {
   // handle exception
}

JFileChooser chooser = new JFileChooser(); 
//etc
}

4
问题在于当你调用super(path)时,Look & Feel已经为你选择好了。
来自Java外观和感觉教程
注意:如果您要设置L&F,应该在应用程序的最开始步骤中完成。否则,您会冒初始化Java L&F的风险,而不管您请求的是什么L&F。这可能会在静态字段引用Swing类时无意中发生,从而导致L&F被加载。如果尚未指定L&F,则加载JRE的默认L&F。对于Sun的JRE,默认值为Java L&F,对于Apple的JRE,为Apple L&F,等等。
为了解决这个问题,您应该使用以下代码替换try/catch块 (解释在此处):
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
SwingUtilities.updateComponentTreeUI(this);
this.pack();

这个答案可能会对我有所帮助,那是一个好的引用和简洁的解决方案。 - memnoch_proxy

4

在你的主方法开头尝试这个。或者,如果你正在使用Netbeans或Eclipse Windowbuilder生成的代码,把这个放在生成的代码之前。

try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } 
catch (UnsupportedLookAndFeelException e) {}
catch (ClassNotFoundException e) {}
catch (InstantiationException e) {}
catch (IllegalAccessException e) {}

1

在你的主方法中早期使用UIManager.setLookAndFeel(...);应该是最干净的方法,如前所述,但是如果要将其添加到一个现有的应用程序中,请非常谨慎进行广泛测试。

例如,我尝试将LAF更改为WindowsLookAndFeel(这样JFileChooser就知道“My Documents”实际上是指名为“Documents”的文件夹),但由于以下行导致不同模块中的NullPointerException

int separatorWidth = (new JToolBar.Separator()).getSeparatorSize().width;

在[9595358]中有一个方法可以覆盖单个类的L&F:http://stackoverflow.com/questions/9595358/nullpointerexception-when-using-windowsfilechooserui - RobB

-1

如果你需要这个 -> Windows Look And Feel Sample

你也可以使用下面的代码!

玩得开心!

JFrame w = new FileExplorerJFrame();

    try {
        UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    } catch (ClassNotFoundException ex) {
        Logger.getLogger(ExcelTest.class.getName()).log(Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        Logger.getLogger(ExcelTest.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        Logger.getLogger(ExcelTest.class.getName()).log(Level.SEVERE, null, ex);
    } catch (UnsupportedLookAndFeelException ex) {
        Logger.getLogger(ExcelTest.class.getName()).log(Level.SEVERE, null, ex);
    }
    SwingUtilities.updateComponentTreeUI(w);

    w.pack();
    w.setVisible(true);

哪一部分?这里的代码是用于FileExplorerJFrame()。 - VirtualBlade

-1

首先:

String path = null;
FileChooser fc=new FileChooser(path);
fc.showOpenDialog(null);

然后在另一个类中:

public FileChooser(){
    this(null);
}

public  FileChooser(String path) {
    super(path);
    try {
        UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
        SwingUtilities.updateComponentTreeUI(this);
        this.pack();
    } catch (Exception ex) {
        Logger.getLogger(FileChooser.class.getName()).log(Level.SEVERE, null, ex);
    }

    JFileChooser chooser = new JFileChooser();
}

private void pack() {
    try{
    }catch(UnsupportedOperationException eu){
    };
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接