2015-09-15 22 views
0

我正在使用Java Swing開發文件資源管理器,我需要使用相同圖標(文件夾圖標)設置所有葉子。以下是我在運行時未更新的內容Look and Feelenter image description here當使用系統外觀時,UIManager未更新圖標

請注意,「系統卷信息」是一個文件夾,但具有文件圖標。爲了解決這個問題,我使用這條線之前顯示我的JFrameUIManager.put("Tree.leafIcon", UIManager.getIcon("FileView.directoryIcon"));

的問題是,我想用System Look and FeelUIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());,但最後葉(沒有內部的任何文件夾中的文件夾)沒有更新:

enter image description here

這裏是我的代碼(除去進口以提高可讀性):

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; 
     } 
    } 
} 

我怎麼能與System Look and Feel更新的文件夾?

+0

爲了儘快提供更好的幫助,請發佈[MCVE]或[簡短,獨立,正確的示例](http://www.sscce.org/)。 –

+0

順便說一句 - 一定要調用[''SwingUtilities.updateComponentTreeUI(Component)'](http://docs.oracle.com/javase/8/docs/api/javax/swing/SwingUtilities.html#updateComponentTreeUI-java.awt。組件 - ).. –

+0

@AndrewThompson更新了我的問題,其代碼爲 – lucasdc

回答

0

儘管對於您的應用程序,文件夾應顯示爲文件夾圖標,JTree將空文件夾看作是一個葉子,因此它始終會使用葉子圖標。

要改變你應該提供一個自定義單元格渲染器,以便文件夾顯示爲文件夾和文件作爲工作表或任何。在教程中有example

+0

「JTree將空文件夾視爲一片葉子,所以它會始終使用葉子圖標」。我看,這就是爲什麼我使用這一行:'UIManager.put(「Tree.leafIcon」,UIManager.getIcon(「FileView.directoryIcon」));'。有了這個,空文件夾圖標被更新爲一個文件夾圖標,但問題是它使用Java外觀和感覺,我願意使用系統外觀和感覺。 – lucasdc

+0

哦,你說得對。你是否設置了'UIManager.put(「Tree.leafIcon」,UIManager.getIcon(「FileView.directoryIcon」));'在更改L&F之後? – Farrandu

+0

其實我試過之後,之前和之後都是大聲笑。雖然沒有成功。 – lucasdc