简体   繁体   English

使用系统外观时,UIManager不更新图标

[英]UIManager not updating icon when using System Look and Feel

I'm developing a file explorer using Java Swing and I need to set all leaves with the same icon (folder icon). 我正在使用Java Swing开发文件浏览器,并且需要使用相同的图标(文件夹图标)设置所有叶子。 Here is what I have when running without updating Look and Feel : 这是我在不更新Look and Feel情况下所拥有的: 在此处输入图片说明

Note that "System Volume Information" is a folder but has a file icon. 请注意,“系统卷信息”是一个文件夹,但是具有文件图标。 To solve it I use this line before showing my JFrame : UIManager.put("Tree.leafIcon", UIManager.getIcon("FileView.directoryIcon")); 为了解决这个问题,我在显示JFrame之前使用了以下代码: UIManager.put("Tree.leafIcon", UIManager.getIcon("FileView.directoryIcon")); .

The problem is that I want to use System Look and Feel : UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 问题是我想使用System Look and FeelUIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); , but the last leaves (folders that do not have any folders inside) are not updating: ,但最后一个叶子(其中没有任何文件夹的文件夹)没有更新:

在此处输入图片说明

Here is my code (removed imports to improve readability): 这是我的代码(删除了导入以提高可读性):

public class Scratch extends JFrame {
    protected JTree m_tree;
    protected DefaultTreeModel m_model;
    protected JTextField m_display;
    protected JScrollPane scrollPane;
    protected Action m_action;
    protected TreePath m_clickedPath;

    public static void main(String argv[]) {
        try {
            UIManager.put("Tree.leafIcon", UIManager.getIcon("FileView.directoryIcon"));
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            e.printStackTrace();
        }

        new Scratch();
    }

    public Scratch() {
        super("Test");
        setSize(500, 400);
        DefaultMutableTreeNode top = new DefaultMutableTreeNode("Computer");

        DefaultMutableTreeNode node;
        File[] roots = File.listRoots();
        for (int k = 0; k < roots.length; k++) {
            node = new DefaultMutableTreeNode(new FileNode(roots[k]));
            top.add(node);
            node.add(new DefaultMutableTreeNode(new Boolean(true)));
        }

        m_model = new DefaultTreeModel(top);
        m_tree = new JTree(m_model);
        m_tree.addTreeExpansionListener(new DirExpansionListener());
        m_tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
        scrollPane = new JScrollPane();
        scrollPane.getViewport().add(m_tree);
        getContentPane().add(scrollPane, BorderLayout.CENTER);

        setVisible(true);
    }

    class DirExpansionListener extends JLabel implements TreeExpansionListener {
        public void treeExpanded(TreeExpansionEvent event) {
            final DefaultMutableTreeNode node = getTreeNode(event.getPath());
            final FileNode fnode = getFileNode(node);

            Thread runner = new Thread() {
                public void run() {
                    if (fnode != null && fnode.expand(node)) {
                        Runnable runnable = new Runnable() {
                            public void run() {
                                m_model.reload(node);
                            }
                        };

                        runnable.run();
                    }
                }
            };
            runner.start();
        }

        public void treeCollapsed(TreeExpansionEvent event) {}
    }

    private FileNode getFileNode(DefaultMutableTreeNode node) {
        if (node == null)
            return null;

        Object obj = node.getUserObject();
        if (obj instanceof FileNode)
            return (FileNode) obj;
        else
            return null;
    }

    private DefaultMutableTreeNode getTreeNode(TreePath path) {
        return (DefaultMutableTreeNode) (path.getLastPathComponent());
    }
}

class FileNode {
    protected File m_file;

    public FileNode(File file) {
        m_file = file;
    }

    public File getFile() {
        return m_file;
    }

    public String toString() {
        return m_file.getName().length() > 0 ? m_file.getName() : m_file.getPath();
    }

    public boolean expand(DefaultMutableTreeNode parent) {
        DefaultMutableTreeNode flag = (DefaultMutableTreeNode) parent.getFirstChild();
        if (flag == null) // No flag
            return false;
        Object obj = flag.getUserObject();
        if (!(obj instanceof Boolean))
            return false; // Already expanded

        // Texto antes de adicionar os nós 
        flag.setUserObject("Loading...");

        parent.removeAllChildren(); // Remove Flag

        File[] files = listFiles();
        if (files == null)
            return true;

        Vector v = new Vector();

        for (int k = 0; k < files.length; k++) {
            File f = files[k];
            if (!f.isDirectory()) {
                continue;
            }

            FileNode newNode = new FileNode(f);

            boolean isAdded = false;
            for (int i = 0; i < v.size(); i++) {
                FileNode nd = (FileNode) v.elementAt(i);
                if (newNode.compareTo(nd) < 0) {
                    v.insertElementAt(newNode, i);
                    isAdded = true;
                    break;
                }
            }
            if (!isAdded)
                v.addElement(newNode);
        }

        for (int i = 0; i < v.size(); i++) {
            FileNode nd = (FileNode) v.elementAt(i);

            DefaultMutableTreeNode node = new DefaultMutableTreeNode(nd);
            parent.add(node);

            if (nd.hasSubDirs()) {
                node.add(new DefaultMutableTreeNode(new Boolean(true)));
            }
        }

        return true;
    }

    public boolean hasSubDirs() {
        File[] files = listFiles();
        if (files == null) {
            return false;
        }

        for (int k = 0; k < files.length; k++) {
            if (files[k].isDirectory()) {
                return true;
            }
        }
        return false;
    }

    public int compareTo(FileNode toCompare) {
        return m_file.getName().compareToIgnoreCase(toCompare.m_file.getName());
    }

    protected File[] listFiles() {
        if (!m_file.isDirectory())
            return null;
        try {
            return m_file.listFiles();
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(null, "Error reading directory " + m_file.getAbsolutePath(), "Warning", JOptionPane.WARNING_MESSAGE);
            return null;
        }
    }
}

How can I update the folders with System Look and Feel ? 如何使用“ System Look and Feel更新文件夹?

Although for your application, a folder should be displayed as a folder icon, the JTree sees an empty folder as a leaf, so it will use the leaf icon always. 尽管对于您的应用程序,文件夹应显示为文件夹图标,但JTree会将空文件夹视为叶子,因此它将始终使用叶子图标。

To change that you should provide a custom cell renderer, so that folders are shown as folders and files as sheets, or whatever. 要进行更改,您应该提供一个自定义单元格渲染器,以便将文件夹显示为文件夹,将文件显示为工作表或其他。

There's a example in the Java tutorials. Java教程中有一个示例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM