Search code examples
javaxmltreejframejtree

Implementing JTree where the DefaultMutableTreeNode is read from xml file


Is it possible to create at JTree without hardcoding every tree node but rather reading in from a xml file and getting the same output as following code will give:

import javax.swing.JFrame;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;

public class test {

test() {
    JFrame f = new JFrame("Swing");
    DefaultMutableTreeNode life = new DefaultMutableTreeNode("Life");
    DefaultMutableTreeNode plants = new DefaultMutableTreeNode("Plants");
    DefaultMutableTreeNode animals = new DefaultMutableTreeNode("Animals");
    DefaultMutableTreeNode cryptogamers = new DefaultMutableTreeNode("Cryptogamers");
    DefaultMutableTreeNode mammals = new DefaultMutableTreeNode("Mammals");
    JTree root = new JTree(life);

    life.add(plants);
    life.add(animals);

    plants.add(cryptogamers);
    animals.add(mammals);

    f.setSize(200, 200);
    f.add(root);
    f.setVisible(true);

    }

public static void main(String[] args) {
    new test();
    }

}

I want to produce the same result but without hardcoding every node by using this XML file I created:

<Biosphere name="Life"> 
<Kingdom name="Plants"> 
<Division name="Cryptogamers"> 
</Division>
</Kingdom>
<Kingdom name="Animals"> 
<Division name="Mammals"> 
</Division>
</Kingdom>
</Biosphere>

Solution

  • If you serialize the tree with XMLEncoder you can produce something like the below. By extension, you can edit it and then deserialize it. That can of course compress well as there's a lot of redundancy. Serialization would look like:

    public void serialize(TreeModel model) {
        try (XMLEncoder enc = new XMLEncoder(Files.newOutputStream(Path.of("tree.xml")))) {
            enc.writeObject(model);
        }
        catch(IOException e) {
            e.printStackTrace();    
        }
    }
    

    Producing:

    <java version="18.0.2.1" class="java.beans.XMLDecoder">
     <object class="javax.swing.tree.DefaultTreeModel">
      <object class="javax.swing.tree.DefaultMutableTreeNode">
       <void property="userObject">
        <string>Life</string>
       </void>
       <void method="add">
        <object class="javax.swing.tree.DefaultMutableTreeNode">
         <void property="userObject">
          <string>Plants</string>
         </void>
         <void method="add">
          <object class="javax.swing.tree.DefaultMutableTreeNode">
           <void property="userObject">
            <string>Cryptogamers</string>
           </void>
          </object>
         </void>
        </object>
       </void>
       <void method="add">
        <object class="javax.swing.tree.DefaultMutableTreeNode">
         <void property="userObject">
          <string>Animals</string>
         </void>
         <void method="add">
          <object class="javax.swing.tree.DefaultMutableTreeNode">
           <void property="userObject">
            <string>Mammals</string>
           </void>
          </object>
         </void>
        </object>
       </void>
      </object>
     </object>
    </java>