如何改变Java程序中单个部分的外观和感觉

8
我正在制作一个程序选择工具,目前我喜欢整个界面与 Java LookAndFeel 很相似。唯一想要更改的是 JFileChooser 的 LookAndFeel 为 Windows。当我调用 filechooser 并告诉它更改 LookAndFeel 时,它没有任何反应。当我在程序启动时调用它,它使按钮的外观变得不好看。因此,谷歌上没有任何解决方案,我也无法找到解决办法。请帮帮我!让我知道哪些代码相关且有用。提前感谢! 编辑: 下面是一些关于 JFileChooser 的代码及其启动方式:
public class Start(){
    public static JButton assignButton = new JButton(new AbstractAction(
        "Assign") {
    public void actionPerformed(ActionEvent e) {
        AssignWindow.run();
    }
});
}

public class AssignmentWindow(){
   public static void run() {
    Dialogs.assignmentInfo();

    bgImage = aw.getImage("files/background.png");

            //aw is the object of this class
    aw.makeFrame();     //makes the jframe for all the buttons to sit.
    aw.setGraphics();   //assigns a different graphics variable

    aw.fileChooser();
}

public void fileChooser() {
    JFileChooser jfc = new JFileChooser();
    jfc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);

            // here is where i want to set the look and feel....

    if (jfc.showDialog(null, "Select") == JFileChooser.APPROVE_OPTION) {
        File file = jfc.getSelectedFile();
        fileDir = file.getPath();
    } else {
        Dialogs.msg("You cancled selecting a file. Returning to file frame...");
        AssignWindow.destroy();
    }
}
}

我有一堆代码,所以不确定哪些部分是有用的,应该包含在内... - PulsePanda
你的问题与JFileChooser外观有关。这是需要审查的部分。它还将帮助您自行分析问题,隔离相关代码。 - Alfabravo
4个回答

19

只需要在创建JFileChooser对象时更改UIManager,然后将其设置回先前的状态即可。或者你可以捕获异常,但这是不好的做法。

public void stuff(){
    JFileChooser chooser = null;
    LookAndFeel previousLF = UIManager.getLookAndFeel();
    try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        chooser = new JFileChooser();
        UIManager.setLookAndFeel(previousLF);
    } catch (IllegalAccessException | UnsupportedLookAndFeelException | InstantiationException | ClassNotFoundException e) {}
    //Add whatever other settings you want to the method
    chooser.showOpenDialog(frame);
}

7

是的,这是可以做到的。您可以手动设置用户界面:

JFileChooser jfc = new JFileChooser();
WindowsFileChooserUI wui = new WindowsFileChooserUI(jfc);
wui.installUI(jfc);
jfc.showOpenDialog(parentComponent);

这将设置文件选择器的 Windows 用户界面,同时保留所有其他组件的外观和感觉。


你能解释一下这个有什么帮助吗? - PulsePanda
好的,WindowFileChooserUI是一个导入吗?因为当我尝试这样做时它会给我一个错误... - PulsePanda
如果这不能解决你的问题,我就不明白你在做什么了。你的代码中没有包含你改变外观和感觉的部分。 - Stephan
这个解决方案对我不起作用。我尝试将其与JScrollPane一起使用,因为我使用自己修改过的滚动窗格制作了自己的LaF。滚动窗格也用于组合框,这些应该保持修改,但在我的情况下,如果附加到JTable,则必须使用Metal-LaF来滚动窗格。 - prototype0815

4

点击 Cancel JButton,会将外观从 Metal 更改为 SystemNimbus Look and Feel

所有对已经可见容器的更新必须通过代码行调用。

SwingUtilities.updateComponentTreeUI(Top-Level Container);

代码

import java.io.File;
import javax.swing.*;
import javax.swing.filechooser.FileFilter;

class ChooserFilterTest {

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                String[] properties = {"os.name", "java.version", "java.vm.version", "java.vendor"};
                for (String property : properties) {
                    System.out.println(property + ": " + System.getProperty(property));
                }
                JFileChooser jfc = new JFileChooser();
                jfc.showOpenDialog(null);
                jfc.addChoosableFileFilter(new FileFilter() {

                    @Override
                    public boolean accept(File f) {
                        return f.isDirectory() || f.getName().toLowerCase().endsWith(".obj");
                    }

                    @Override
                    public String getDescription() {
                        return "Wavefront OBJ (*.obj)";
                    }

                    @Override
                    public String toString() {
                        return getDescription();
                    }
                });
                int result = JOptionPane.showConfirmDialog(null, "Description was 'All Files'?");
                System.out.println("Displayed description (Metal): " + (result == JOptionPane.YES_OPTION));
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    SwingUtilities.updateComponentTreeUI(jfc);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                jfc.showOpenDialog(null);
                result = JOptionPane.showConfirmDialog(null, "Description was 'All Files'?");
                System.out.println("Displayed description (System): " + (result == JOptionPane.YES_OPTION));
                result = JOptionPane.showConfirmDialog(null, "Description was 'All Files'?");
                System.out.println("Displayed description (Metal): " + (result == JOptionPane.YES_OPTION));
                try {
                    for (UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                        if ("Nimbus".equals(info.getName())) {
                            UIManager.setLookAndFeel(info.getClassName());
                            SwingUtilities.updateComponentTreeUI(jfc);
                            break;
                        }
                    }
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (javax.swing.UnsupportedLookAndFeelException ex) {
                }
                jfc.showOpenDialog(null);
                result = JOptionPane.showConfirmDialog(null, "Description was 'All Files'?");
                System.out.println("Displayed description (System): " + (result == JOptionPane.YES_OPTION));
            }
        };
        SwingUtilities.invokeLater(r);
    }

    private ChooserFilterTest() {
    }
}

2

你应该了解外观和感觉相关的内容。
另外,我认为你不能为每个组件设置不同的外观和感觉。至少我从未见过非统一外观和感觉的应用程序。


我已经查看了那个链接,并且知道如何做。但那不是我想要的。我想为文件选择器设置L&F,而不是这个窗口。如果我像那样设置,一切都会改变。 - PulsePanda
你在哪里读到可以为每个组件设置不同的L&F?你有参考资料吗? - Cratylus
@wbAnon,你面临的问题是,如果你改变了给定 UI 组件的值,你会影响到所有未来创建的 UI 组件(例如 JListJButtonJLabel 等)。 - MadProgrammer
我听说过可以改变滚动条的外观之类的,但不幸的是我没有参考资料。 - PulsePanda
@wbAnon:你在哪里尝试更新L&F的代码,就像你在OP中说的那样? - Cratylus

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