2015-05-12 3 views
4

Я хочу отобразить отдельный значок для сгруппированных и негруппированных узлов. Я создал выборочные коды customTreeCellRender.My, приведенные ниже. Внутри цикла нечетные одни узлы имеют один значок, а evens имеют другой. Но не меняют значок узлов. В моем приложении заполнение узлов дерева из db и группировка основаны на некоторых условиях. Это примерный исполняемый код.Как установить значок узла Jtree динамически

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Component; 
import java.net.MalformedURLException; 
import java.net.URL; 

import javax.swing.ImageIcon; 
import javax.swing.JDialog; 
import javax.swing.JTree; 
import javax.swing.tree.DefaultMutableTreeNode; 
import javax.swing.tree.DefaultTreeCellRenderer; 
import javax.swing.tree.DefaultTreeModel; 

public class TestTree extends JDialog { 

    JTree tree; 

    DefaultTreeModel treeModel; 

    public TestTree() { 
     setSize(300, 800); 
     setDefaultCloseOperation(DISPOSE_ON_CLOSE); 
     System.out.println(getContentPane().getBackground()); 
    } 

    protected static ImageIcon createImageIcon(String path) throws MalformedURLException { 
     java.net.URL imgURL = new URL(path); 
     if (imgURL != null) { 
      return new ImageIcon(imgURL); 
     } else { 
      System.err.println("Couldn't find file: " + path); 
      return null; 
     } 
    } 

    public void init() throws MalformedURLException { 
     DefaultMutableTreeNode root = new DefaultMutableTreeNode("Numbers"); 
     treeModel = new DefaultTreeModel(root); 
     tree = new JTree(treeModel); 
     tree.setBackground(new Color(238, 238, 244)); 
     tree.setOpaque(true); 

     CustomIconRenderer customIconRenderer = new CustomIconRenderer(true); 
     customIconRenderer.setTextSelectionColor(Color.white); 
     customIconRenderer.setBackgroundSelectionColor(Color.blue); 
     customIconRenderer.setBorderSelectionColor(Color.black); 
     customIconRenderer.setBackgroundNonSelectionColor(new Color(238, 238, 
       244)); 
     ImageIcon icon = createImageIcon("http://i.stack.imgur.com/wCF8S.png"); 
     customIconRenderer.setLeafIcon(icon); 


     for (int i = 0; i < 10; i++) { 
      if (i % 2 == 0) { 
       DefaultMutableTreeNode subroot = new DefaultMutableTreeNode(
         "node_" + i); 
       root.add(subroot); 

        tree.setCellRenderer(new CustomIconRenderer(false)); 

       if (i % 3 == 0) { 
        for (int j = 10; j < 15; j++) { 
         DefaultMutableTreeNode leaf = new DefaultMutableTreeNode(
           "node_" + j); 
         subroot.add(leaf); 
        } 
       } 

      } else { 
       DefaultMutableTreeNode subroot = new DefaultMutableTreeNode(
         "node_" + i); 
       root.add(subroot); 
       tree.setCellRenderer(new CustomIconRenderer(true)); 
       if (i % 4 == 0) { 
        for (int j = 15; j < 20; j++) { 
         DefaultMutableTreeNode leaf = new DefaultMutableTreeNode(
           "node_" + j); 
         subroot.add(leaf); 
        } 

       } 

      } 
     } 

     for (int i = 0; i < tree.getRowCount(); i++) { 
      tree.expandRow(i); 
     } 

     tree.setCellRenderer(customIconRenderer); 

     getContentPane().add(tree, BorderLayout.CENTER); 
    } 

    public static void main(String args[]) throws MalformedURLException { 
     TestTree tt = new TestTree(); 
     tt.init(); 
     tt.setVisible(true); 
    } 
} 
class CustomIconRenderer extends DefaultTreeCellRenderer { 
    /** 
    * 
    */ 
    private static final long serialVersionUID = 967937360839244309L; 
    ImageIcon groupedIcon; 
    ImageIcon unGroupedIcon; 
    boolean grouped; 

    public CustomIconRenderer() { 

    } 

    public CustomIconRenderer(boolean grouped) throws MalformedURLException { 
     this.grouped = grouped; 
     URL url=new URL("http://i.stack.imgur.com/wCF8S.png"); 
     URL url1=new URL("http://i.stack.imgur.com/T5uTa.png"); 
     groupedIcon = new ImageIcon(url1 
       ); 
     unGroupedIcon = new ImageIcon(url 
       ); 
    } 
@Override 
    public Component getTreeCellRendererComponent(JTree tree, Object value, 
      boolean sel, boolean expanded, boolean leaf, int row, 
      boolean hasFocus) { 

     super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, 
       row, hasFocus); 

     Object nodeObj = ((DefaultMutableTreeNode) value).getUserObject(); 
     // check whatever you need to on the node user object 
     if (grouped) { 
      setIcon(unGroupedIcon); 
     } else { 
      System.out.println("reached"); 
      setIcon(groupedIcon); 
     } 
     return this; 
    } 
} 
+0

добавлен работоспособный правильный пример – User123

+0

1) MCVE должен быть один исходный файл (который может содержать более одного непубличного класса) и включает импорт. 2) Мы не можем запустить его и увидеть проблему без файлов изображений, которые находятся на вашем ПК! Одним из способов получения изображения (ов) для примера является ** горячая ссылка ** на изображения, видимые в [этот вопрос и ответы] (http://stackoverflow.com/q/19209650/418556). –

+1

Плюс один для добавления MCVE. Я пытаюсь вернуть это снова, но все еще нужно еще два открытых голоса. В то же время, измените 'public Component getTreeCellRendererComponent (..' на '@Override public Component getTreeCellRendererComponent (..' для раскрытия сообщения компилятора. –

ответ

3

Существовало несколько ошибок в исходном коде, большинство из них не ably:

  • Установка средства визуализации ячеек при каждом добавлении узла (дерево может содержать только один обработчик ячейки, поэтому выигрыш «последний добавлен»).
  • Ожидается, что измененный метод, который вы закодировали для получения рендеринга ячеек дерева, будет вызван. (Вы делал этот эксперимент я предложил в комментариях, не так ли?)

Я думаю, что это больше вдоль линий требования. Обратите внимание, что я пытался как можно ближе придерживаться исходного кода. Я бы поступил иначе, как это видно здесь.

  • Этот пример: Рассматривает значение value передается методу, чтобы получить средства визуализации клеток, чтобы увидеть, если он содержит _ характер String, затем разбивает строку и разбирает последнюю часть обратно в целое число ,
  • Как это должно быть сделано: Pass Integer объекты для листьев дерева. При проверке визуализации ячейки значения является экземпляром Integer и если да, то префикс номер с node_ ..

enter image description here

import java.awt.*; 
import java.net.*; 
import javax.swing.*; 
import javax.swing.tree.*; 

public class TestTree extends JDialog { 

    JTree tree; 

    DefaultTreeModel treeModel; 

    public TestTree() { 
     setSize(300, 800); 
     setDefaultCloseOperation(DISPOSE_ON_CLOSE); 
     System.out.println(getContentPane().getBackground()); 
    } 

    protected static ImageIcon createImageIcon(String path) throws MalformedURLException { 
     java.net.URL imgURL = new URL(path); 
     if (imgURL != null) { 
      return new ImageIcon(imgURL); 
     } else { 
      System.err.println("Couldn't find file: " + path); 
      return null; 
     } 
    } 

    public void init() throws MalformedURLException { 
     DefaultMutableTreeNode root = new DefaultMutableTreeNode("Numbers"); 
     treeModel = new DefaultTreeModel(root); 
     tree = new JTree(treeModel); 
     tree.setBackground(new Color(238, 238, 244)); 
     tree.setOpaque(true); 

     CustomIconRenderer customIconRenderer = new CustomIconRenderer(); 
     customIconRenderer.setTextSelectionColor(Color.white); 
     customIconRenderer.setBackgroundSelectionColor(Color.blue); 
     customIconRenderer.setBorderSelectionColor(Color.black); 
     customIconRenderer.setBackgroundNonSelectionColor(new Color(238, 238, 
       244)); 
     ImageIcon icon = createImageIcon("http://i.stack.imgur.com/wCF8S.png"); 
     customIconRenderer.setLeafIcon(icon); 
     tree.setCellRenderer(new CustomIconRenderer()); 

     for (int i = 0; i < 10; i++) { 
      if (i % 2 == 0) { 
       DefaultMutableTreeNode subroot = new DefaultMutableTreeNode(
         "node_" + i); 
       root.add(subroot); 

       if (i % 3 == 0) { 
        for (int j = 10; j < 15; j++) { 
         DefaultMutableTreeNode leaf = new DefaultMutableTreeNode(
           "node_" + j); 
         subroot.add(leaf); 
        } 
       } 
      } else { 
       DefaultMutableTreeNode subroot = new DefaultMutableTreeNode(
         "node_" + i); 
       root.add(subroot); 
       if (i % 4 == 0) { 
        for (int j = 15; j < 20; j++) { 
         DefaultMutableTreeNode leaf = new DefaultMutableTreeNode(
           "node_" + j); 
         subroot.add(leaf); 
        } 
       } 
      } 
     } 

     for (int i = 0; i < tree.getRowCount(); i++) { 
      tree.expandRow(i); 
     } 

     tree.setCellRenderer(customIconRenderer); 

     getContentPane().add(tree, BorderLayout.CENTER); 
    } 

    public static void main(String args[]) throws MalformedURLException { 
     TestTree tt = new TestTree(); 
     tt.init(); 
     tt.setVisible(true); 
    } 
} 

class CustomIconRenderer extends DefaultTreeCellRenderer { 

    /** 
    * 
    */ 
    private static final long serialVersionUID = 967937360839244309L; 
    ImageIcon groupedIcon; 
    ImageIcon unGroupedIcon; 

    public CustomIconRenderer() throws MalformedURLException { 
     URL url = new URL("http://i.stack.imgur.com/wCF8S.png"); 
     URL url1 = new URL("http://i.stack.imgur.com/T5uTa.png"); 
     groupedIcon = new ImageIcon(url1); 
     unGroupedIcon = new ImageIcon(url); 
    } 

    @Override 
    public Component getTreeCellRendererComponent(JTree tree, Object value, 
      boolean sel, boolean expanded, boolean leaf, int row, 
      boolean hasFocus) { 

     super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, 
       row, hasFocus); 

     Object nodeObj = ((DefaultMutableTreeNode) value).getUserObject(); 
     String s = nodeObj.toString(); 
     System.out.println("s: " + s); 
     boolean includesUnderscore = s.indexOf("_") > 0; 
     if (includesUnderscore) { 
      String lastPart = s.split("_")[1]; 
      int num = Integer.parseInt(lastPart); 
      // check whatever you need to on the node user object 
      if (num % 2 == 0) { 
       setIcon(unGroupedIcon); 
      } else { 
       System.out.println("reached"); 
       setIcon(groupedIcon); 
      } 
     } 
     return this; 
    } 
} 
+0

В моем приложении для каждого уровня узлов нужно заполнить узлы дерева из db и значка набора в зависимости от разных условий. В этом случае я хочу передать один флаг в класс CustomRenderer. я могу определить другую функцию в классе рендеринга и установить значение глобальной переменной. – User123

+1

* «Я могу определить другую функцию в классе рендеринга и установить значение глобальной переменной». * Я действительно не думаю, что вы понимаете, что существует только *** когда-либо *** один обработчик ячеек, независимо от того, сколько узлов дерева существует , Вы это понимаете? BTW - для меня «глобальный» означает одно и то же значение для всех обработчиков ячеек (независимо от того, сколько их есть), поэтому на самом деле не имеет смысла пытаться использовать глобальную переменную, чтобы разные листья отображались по-разному. Один из нас очень смущен, мне хотелось бы знать, какой! –

+0

Спасибо, Андрей. Приложил к моему приложению и получил его. – User123

1

Я создал customTreeCellRender.But не меняя иконку

Вам не нужно звонить getTreeCellRendererComponent напрямую, а пусть JTree обрабатывать его явно устанавливая TreeCellRenderer для JTree, как описано в Oracle tutorial

tree.setCellRenderer(customIconRenderer); 
+0

над надстроенным учебником, устанавливает одинаковый значок для всех узлов.Но я хочу установить разные значки для каждого узла. Я напрямую не вызываю getTreeCellRendererComponent, его один из методов в классе CustomRender. Вместо вызова конструктора я использовал этот метод. Обратите внимание на количество параметров, переданных во время вызова метода. – User123

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