2015-09-15 2 views
0

Я разрабатываю файловый проводник с помощью Java Swing, и мне нужно установить все листья с тем же значком (значок папки). Вот что я имею при работе без обновления Look and Feel: enter image description hereUIManager не обновляет значок при использовании System Look and Feel

Обратите внимание, что «Информация о системном томе» - это папка, но есть значок файла. Чтобы решить эту проблему, я использую эту строку, прежде чем показывать свои JFrame: UIManager.put("Tree.leafIcon", UIManager.getIcon("FileView.directoryIcon"));.

Проблема заключается в том, что я хочу использовать System Look and Feel: UIManager.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] или [Short, Self Contained, Correct Example] (http://www.sscce.org/). –

+0

BTW - обязательно вызовите ['SwingUtilities.updateComponentTreeUI (Component)'] (http://docs.oracle.com/javase/8/docs/api/javax/swing/SwingUtilities.html#updateComponentTreeUI-java.awt. Component-) .. –

+0

@AndrewThompson обновил мой вопрос с помощью кода – lucasdc

ответ

0

Хотя для вашего приложения папка должна отображаться как значок папки, JTree видит пустую папку в виде листа, поэтому она всегда будет использовать значок листа.

Чтобы изменить это, вы должны предоставить собственный рендеринг ячеек, чтобы папки отображались как папки и файлы в виде листов или что-то еще.

В учебниках Java есть example.

+0

«JTree видит пустую папку как лист, поэтому она всегда будет использовать значок листа». Понятно, именно поэтому я использую эту строку: 'UIManager.put (« Tree.leafIcon », UIManager.getIcon (« FileView.directoryIcon »));'. При этом значок пустой папки обновляется до значка папки, но проблема в том, что он использует Java Look и Feel, и я готов использовать System Look и Feel. – lucasdc

+0

Оооопс, ты прав. Вы устанавливаете 'UIManager.put (« Tree.leafIcon », UIManager.getIcon (« FileView.directoryIcon »)),' после изменения L & F? – Farrandu

+0

На самом деле я пробовал после, до и после и после lol. Однако успеха нет. – lucasdc

Смежные вопросы