2013-04-14 51 views
0

我想解析下面的XML文件,並創建一個基於它自定義圖標的JTree。Jtree渲染器設置自定義圖標不工作

<OBJECTS> 
    <WINDOW NAME = "WINDOW 01" URL = "URL 01"> 
     <PAGE NAME = "PAGE 01" URL = "PAGE URL 01"> 
     </PAGE> 
    </WINDOW> 
</OBJECTS> 

的用戶定義的節點類,如下所示:

public class DataNode extends DefaultMutableTreeNode {  
    private static final long serialVersionUID = 1L; 
    public String ObjectType, ObjectName, URL, ElementType; 
    public DefaultMutableTreeNode node; 

    public DataNode(DefaultMutableTreeNode node, Element element) { 
     this.node = node; 
     this.ObjectType = element.getTagName(); 
     this.ObjectName = element.getAttribute("NAME"); 
     this.URL = element.getAttribute("URL"); 
     this.ElementType = element.getAttribute("TYPE"); 
    } 

    public DataNode(Element element) { 
     this.node = new DefaultMutableTreeNode("OBJECT"); 
     this.ObjectType = element.getTagName(); 
     this.ObjectName = "Object List"; 
     this.URL = ""; 
     this.ElementType = ""; 
    } 

    @Override 
    public String toString() { 
     return this.ObjectName; 
    } 
} 

這是主要的類:

public class MyOwn { 
    private JFrame contentsFrame; 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       try { 
        MyOwn window = new MyOwn(); 
        window.contentsFrame.setVisible(true); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    public MyOwn() { 
     contentsFrame = new JFrame(); 
     contentsFrame.setTitle("My JTree"); 
     contentsFrame.setBounds(100, 100, 549, 738); 
     contentsFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     JTree objectListTree = new JTree(convertXMLtoTree("G:/Collection.xml")); 
     objectListTree.setAlignmentY(Component.TOP_ALIGNMENT); 
     objectListTree.setAlignmentX(Component.LEFT_ALIGNMENT); 

     contentsFrame.getContentPane().add(new JScrollPane(objectListTree)); 
    } 

    private DefaultMutableTreeNode convertXMLtoTree(String Path) { 
     NodeList nWindow, nPage; 
     DefaultMutableTreeNode dRoot, dWindow, dPage; 
     DataNode xRoot, xWindow, xPage; 

     try { 
      File fXmlFile = new File(Path); 
      DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); 
      DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); 
      Document doc = dBuilder.parse(fXmlFile); 

      doc.getDocumentElement().normalize(); 
      xRoot = new DataNode(doc.getDocumentElement()); 
      dRoot = new DefaultMutableTreeNode(xRoot); 
      nWindow = doc.getDocumentElement().getElementsByTagName("WINDOW"); 

      for (int i = 0; i < nWindow.getLength(); i++) { 
       dWindow = new DefaultMutableTreeNode(((Element)(nWindow.item(i))).getAttribute("NAME")); 
       xWindow = new DataNode(dWindow, (Element)(nWindow.item(i))); 
       dRoot.add(xWindow); 
       nPage = ((Element)(nWindow.item(i))).getElementsByTagName("PAGE"); 
       for (int j = 0; j < nPage.getLength(); j++) { 
        dPage = new DefaultMutableTreeNode(((Element)(nPage.item(j))).getAttribute("NAME")); 
        xPage = new DataNode(dPage, (Element)(nPage.item(j))); 
        xWindow.add(xPage); 
       } 
      } 
      return dRoot; 
     } catch (Exception e) { 
      return null; 
     } 
    } 
} 

渲染器類在下面給出:(該生產線在其中拋出NullPointerException異常)

class MyRenderer extends DefaultTreeCellRenderer { 

    private static final long serialVersionUID = 1L; 

    public MyRenderer() { } 

    public String toString() { 
     return "NODE NAME"; 
    } 

    public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) 
    { 
     ImageIcon ObjectsIcon = createImageIcon("images/Element.JPG"); 
     ImageIcon WindowIcon = createImageIcon("images/fig7.jpg"); 
     ImageIcon PageIcon = createImageIcon("images/message_icon.gif"); 
     ImageIcon UnknownIcon = createImageIcon("images/phone_icon.gif"); 

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

     switch (ObjectType(value)) { 
      case 1: setIcon(ObjectsIcon); 
        break; 
      case 2: setIcon(WindowIcon); 
        break; 
      case 3: setIcon(PageIcon); 
        break; 
      case 0: setIcon(UnknownIcon); 
        break; 
     } 

     return this; 
    } 

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

    private int ObjectType(Object value) { 
     DefaultMutableTreeNode node = (DefaultMutableTreeNode)value; 
     DataNode nodeInfo = (DataNode) node.getUserObject(); //This is where the NullPointerException occurs 
     String title = nodeInfo.ObjectType; 

     if (title.equalsIgnoreCase("OBJECT")) 
      return 1; 
     else if (title.equalsIgnoreCase("WINDOW")) 
      return 2; 
     else if (title.equalsIgnoreCase("PAGE")) 
      return 3; 
     else 
      return 0; 
    } 
} 

請讓我知道爲什麼nodeInfo對象是空的?感謝您的幫助...

+0

要麼調試代碼來檢查節點的狀態,要麼放在System.out.println – MadProgrammer

+0

爲了更好地提供幫助,請發佈[SSCCE](http://sscce.org/)。 –

回答

2

節點對象是null因爲您沒有爲您的自定義設置用戶對象DefaultMutableTreeNodeDataNode。既然你願意,你可以使用節點文本匹配:

public DataNode(DefaultMutableTreeNode node, Element element) { 
    super(element.getTagName()); 
     ... 
} 

然後,在MyRenderer

if (value instanceof DataNode) { // added check for class type 
    String title = (String) node.getUserObject(); 
    ... 

順便說一句,在DataNode使用DefaultMutableTreeNode作爲類的成員變量是不必要的。它已經是DefaultMutableTreeNode並且任何可能的節點操作都可以使用超類的繼承方法來處理。

+0

再次真棒反應....它工作....非常感謝.... –

相關問題