MyBookshelf.java

/*
 * @author Hermann Wöhrmann
 *
 * Description:
 *
 * Version Date       Comments
 * 1.01.01 03.11.2004 created
 *
 */

import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;

import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.awt.event.*;
import javax.swing.tree.*;
import javax.swing.event.*;

class MyBookshelfGUI extends GUIObject
{
  protected MyBookshelfGUI()
  { JFrame myBookshelf = new JFrame();
    myBookshelf.setBounds(80, 60, 640, 480);
    myBookshelf.getContentPane().setLayout(new BorderLayout());
    myBookshelf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    myBookshelf.setTitle("JTree Example - My Bookshelf");
    myBookshelf.setResizable(true);
    { JMenuBar menuBar = new JMenuBar();
      { JMenu fileMenu = new JMenu();
        fileMenu.setText("File");
        { JMenuItem exitMenuItem = new JMenuItem();
          exitMenuItem.setText("Exit");
          exitMenuItem.setName("exitMenuItem");
          super.add(exitMenuItem);
          fileMenu.add(exitMenuItem);
        }
        fileMenu.setName("fileMenu");
        super.add(fileMenu);
        menuBar.add(fileMenu);
      }
      menuBar.setName("menuBar");
      super.add(menuBar);
      myBookshelf.setJMenuBar(menuBar);
    }
    { JSplitPane centerSplitPane = new JSplitPane();
      centerSplitPane.setOneTouchExpandable(true);
      { JPanel selectionPanel = new JPanel()
        { public Dimension getPreferredSize()
          { Dimension preferred = super.getPreferredSize();
            return GUIObject.getPreferredSize(preferred, getParent(), "4", null, null, null, null, null);
          }
        };
        selectionPanel.setLayout(new BoxLayout(selectionPanel, BoxLayout.PAGE_AXIS));
        selectionPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.WHITE, Color.BLUE), "Selection", TitledBorder.LEFT, TitledBorder.BELOW_TOP, new Font("Dialog", Font.PLAIN, 12), Color.BLUE));
        { JTree bookshelfTree = new JTree();
          bookshelfTree.setName("bookshelfTree");
          super.add(bookshelfTree);
          JScrollPane treeScrollPane = new JScrollPane(bookshelfTree);
          treeScrollPane.setName("treeScrollPane");
          super.add(treeScrollPane);
          selectionPanel.add(treeScrollPane);
        }
        selectionPanel.setName("selectionPanel");
        super.add(selectionPanel);
        centerSplitPane.setLeftComponent(selectionPanel);
      }
      { JSplitPane rightSplitPane = new JSplitPane();
        rightSplitPane.setOneTouchExpandable(true);
        rightSplitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
        { JPanel presentationPanel = new JPanel()
          { public Dimension getPreferredSize()
            { Dimension preferred = super.getPreferredSize();
              return GUIObject.getPreferredSize(preferred, getParent(), "4", null, "3", null, null, null);
            }
          };
          presentationPanel.setLayout(new BoxLayout(presentationPanel, BoxLayout.Y_AXIS));
          presentationPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.WHITE, Color.BLUE), "XML Representation", TitledBorder.RIGHT, TitledBorder.BELOW_TOP, new Font("Dialog", Font.PLAIN, 12), Color.BLUE));
          { JTextArea xmlTextArea = new JTextArea();
            xmlTextArea.setFont(new Font("Monospaced", Font.PLAIN, 12));
            xmlTextArea.setEditable(false);
            xmlTextArea.setColumns(1);
            xmlTextArea.setRows(1);
            xmlTextArea.setName("xmlTextArea");
            super.add(xmlTextArea);
            JScrollPane scrollPane = new JScrollPane(xmlTextArea);
            scrollPane.setName("scrollPane");
            super.add(scrollPane);
            presentationPanel.add(scrollPane);
          }
          presentationPanel.setName("presentationPanel");
          super.add(presentationPanel);
          rightSplitPane.setLeftComponent(presentationPanel);
        }
        { JPanel editPanel = new JPanel()
          { public Dimension getPreferredSize()
            { Dimension preferred = super.getPreferredSize();
              return GUIObject.getPreferredSize(preferred, getParent(), "4", null, "3", null, null, null);
            }
          };
          editPanel.setLayout(new BorderLayout());
          editPanel.setBorder(BorderFactory.createCompoundBorder(new BevelBorder(BevelBorder.RAISED, Color.WHITE, Color.LIGHT_GRAY, Color.BLACK, Color.LIGHT_GRAY), BorderFactory.createCompoundBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.WHITE, Color.BLUE), BorderFactory.createEmptyBorder(2, 2, 2, 2))));
          { JPanel epTitlePrice = new JPanel();
            epTitlePrice.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
            { JLabel lbTitle = new JLabel()
              { public Dimension getPreferredSize()
                { Dimension preferred = super.getPreferredSize();
                  return GUIObject.getPreferredSize(preferred, getParent(), "6", null, null, null, null, null);
                }
              };
              lbTitle.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 0));
              lbTitle.setText("Title");
              lbTitle.setName("lbTitle");
              super.add(lbTitle);
              epTitlePrice.add(lbTitle);
            }
            { JTextField tfTitle = new JTextField()
              { public Dimension getPreferredSize()
                { Dimension preferred = super.getPreferredSize();
                  return GUIObject.getPreferredSize(preferred, getParent(), "2", null, null, null, null, null);
                }
              };
              tfTitle.setName("tfTitle");
              super.add(tfTitle);
              epTitlePrice.add(tfTitle);
            }
            { JLabel lbPrice = new JLabel()
              { public Dimension getPreferredSize()
                { Dimension preferred = super.getPreferredSize();
                  return GUIObject.getPreferredSize(preferred, getParent(), "6", null, null, null, null, null);
                }
              };
              lbPrice.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 0));
              lbPrice.setText("Price");
              lbPrice.setName("lbPrice");
              super.add(lbPrice);
              epTitlePrice.add(lbPrice);
            }
            { JTextField tfPrice = new JTextField()
              { public Dimension getPreferredSize()
                { Dimension preferred = super.getPreferredSize();
                  return GUIObject.getPreferredSize(preferred, getParent(), "6", null, null, null, null, null);
                }
              };
              tfPrice.setName("tfPrice");
              super.add(tfPrice);
              epTitlePrice.add(tfPrice);
            }
            epTitlePrice.setName("epTitlePrice");
            super.add(epTitlePrice);
            editPanel.add(epTitlePrice, BorderLayout.NORTH);
          }
          { JPanel epDescription = new JPanel();
            epDescription.setLayout(new BorderLayout());
            { JLabel lbDescription = new JLabel()
              { public Dimension getPreferredSize()
                { Dimension preferred = super.getPreferredSize();
                  return GUIObject.getPreferredSize(preferred, getParent(), "6", null, null, null, null, null);
                }
              };
              lbDescription.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 0));
              lbDescription.setText("Descr.");
              lbDescription.setVerticalAlignment(SwingConstants.TOP);
              lbDescription.setName("lbDescription");
              super.add(lbDescription);
              epDescription.add(lbDescription, BorderLayout.WEST);
            }
            { JTextArea taDescription = new JTextArea();
              taDescription.setName("taDescription");
              super.add(taDescription);
              JScrollPane spDescription = new JScrollPane(taDescription);
              spDescription.setName("spDescription");
              super.add(spDescription);
              epDescription.add(spDescription, BorderLayout.CENTER);
            }
            epDescription.setName("epDescription");
            super.add(epDescription);
            editPanel.add(epDescription, BorderLayout.CENTER);
          }
          { JPanel epBtn = new JPanel();
            epBtn.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
            { JLabel epBtnFiller = new JLabel()
              { public Dimension getPreferredSize()
                { Dimension preferred = super.getPreferredSize();
                  return GUIObject.getPreferredSize(preferred, getParent(), "6", null, null, null, null, null);
                }
              };
              epBtnFiller.setName("epBtnFiller");
              super.add(epBtnFiller);
              epBtn.add(epBtnFiller);
            }
            { JButton btnAdd = new JButton()
              { public Dimension getPreferredSize()
                { Dimension preferred = super.getPreferredSize();
                  return GUIObject.getPreferredSize(preferred, getParent(), "4", null, null, null, null, null);
                }
              };
              btnAdd.setEnabled(false);
              btnAdd.setText("Add");
              btnAdd.setName("btnAdd");
              super.add(btnAdd);
              epBtn.add(btnAdd);
            }
            { JButton btnChange = new JButton()
              { public Dimension getPreferredSize()
                { Dimension preferred = super.getPreferredSize();
                  return GUIObject.getPreferredSize(preferred, getParent(), "4", null, null, null, null, null);
                }
              };
              btnChange.setEnabled(false);
              btnChange.setText("Change");
              btnChange.setName("btnChange");
              super.add(btnChange);
              epBtn.add(btnChange);
            }
            { JButton btnRemove = new JButton()
              { public Dimension getPreferredSize()
                { Dimension preferred = super.getPreferredSize();
                  return GUIObject.getPreferredSize(preferred, getParent(), "4", null, null, null, null, null);
                }
              };
              btnRemove.setEnabled(false);
              btnRemove.setText("Remove");
              btnRemove.setName("btnRemove");
              super.add(btnRemove);
              epBtn.add(btnRemove);
            }
            epBtn.setName("epBtn");
            super.add(epBtn);
            editPanel.add(epBtn, BorderLayout.SOUTH);
          }
          editPanel.setName("editPanel");
          super.add(editPanel);
          rightSplitPane.setRightComponent(editPanel);
        }
        rightSplitPane.setDividerLocation(250);
        rightSplitPane.setResizeWeight(0.6);
        rightSplitPane.setName("rightSplitPane");
        super.add(rightSplitPane);
        centerSplitPane.setRightComponent(rightSplitPane);
      }
      centerSplitPane.setDividerLocation(205);
      centerSplitPane.setResizeWeight(0.35);
      centerSplitPane.setName("centerSplitPane");
      super.add(centerSplitPane);
      myBookshelf.getContentPane().add(centerSplitPane, BorderLayout.CENTER);
    }
    myBookshelf.setName("myBookshelf");
    super.add(myBookshelf);
  }
}

public class MyBookshelf extends MyBookshelfController
{ XmlTreeModel xmlTreeModel;
  Document xmlDocument;

  public MyBookshelf()
  { super(new MyBookshelfGUI());
    myBookshelf.show();
  }

//==============================================================================
// XML Tree Rendering ...
//------------------------------------------------------------------------------
  class XmlTreeCellRenderer
  extends DefaultTreeCellRenderer implements XmlTreeNodeFilter
  { private ImageIcon[] XMLTreeIcons =
    { new ImageIcon(Toolkit.getDefaultToolkit().getImage("BookShelf18.gif")),
      new ImageIcon(Toolkit.getDefaultToolkit().getImage("Book18.gif"))
    };

    // implementing the XMLTreeNodeFilter interface
    public boolean isVisibleXmlTreeNode(Node node)
    { if (node instanceof Element)
      { String name = node.getNodeName();
        return (name.equals("Bookshelf") || name.equals("Book"));
      }
      return false;
    }

    // rendering the tree
    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);
      String name = ((Node)value).getNodeName();
      if (name.equals("Bookshelf"))
      { setText(name);
        setIcon(XMLTreeIcons[0]);
      }
      else if (name.equals("Book"))
      { NodeList nodeList = ((Node)value).getChildNodes();
        for (int i = 0, n = nodeList.getLength(); i < n; i++)
        { Node childNode = nodeList.item(i);
          if (childNode.getNodeName().equals("Title"))
          { setText(childNode.getFirstChild().getNodeValue());
            break;
          }
        }
        setIcon(XMLTreeIcons[1]);
      }
      return this;
    }
  }

//==============================================================================
// Tree Support ...
//------------------------------------------------------------------------------

  Node getSelectedTreeNode()
  { TreePath selectionPath = bookshelfTree.getSelectionPath();
    if (selectionPath != null)
    { Object[] path = selectionPath.getPath();
      if (path.length > 0)
      { return (Node)path[path.length - 1]; // last node ...
      }
    }
    return null;
  }

  void setSelectedTreeNode(Node node)
  { TreePath treePath = new TreePath(xmlTreeModel.getPathToRoot(node));
    bookshelfTree.setSelectionPath(treePath);
    bookshelfTree.scrollPathToVisible(treePath);
  }

  void showNodeContent(Node nodeElement)
  { xmlTextArea.setText(nodeElement.toString());
    xmlTextArea.setCaretPosition(0);
    String xmlNodeName = nodeElement.getNodeName();
    btnAdd.setEnabled(xmlNodeName.equals("Bookshelf"));
    btnChange.setEnabled(xmlNodeName.equals("Book"));
    btnRemove.setEnabled(xmlNodeName.equals("Book"));
    if (xmlNodeName.equals("Book"))
    { tfPrice.setText(((Element)nodeElement).getAttribute("Price"));
      NodeList nodeList = nodeElement.getChildNodes();
      for (int i = 0, n = nodeList.getLength(); i < n; i++)
      { Node childNode = nodeList.item(i);
        if (childNode.getNodeName().equals("Description"))
        { taDescription.setText(childNode.getFirstChild().getNodeValue());
        }
        else if (childNode.getNodeName().equals("Title"))
        { tfTitle.setText(childNode.getFirstChild().getNodeValue());
        }
      }
    }
    else
    { tfTitle.setText(null);
      tfPrice.setText(null);
      taDescription.setText(null);
    }
  }

//==============================================================================
// Overwritten MyBookshelfController methods ...
//------------------------------------------------------------------------------

  void initialize()
  { try
    { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      DocumentBuilder builder = factory.newDocumentBuilder();
      DOMImplementation impl = builder.getDOMImplementation();
      xmlDocument = impl.createDocument(null, "Bookshelf", null);
      xmlTreeModel = new XmlTreeModel(xmlDocument.getDocumentElement());
      XmlTreeCellRenderer filterAndRenderer = new XmlTreeCellRenderer();
      xmlTreeModel.setTreeNodeFilter(filterAndRenderer);
      bookshelfTree.setModel(xmlTreeModel);
      bookshelfTree.setCellRenderer(filterAndRenderer);
    }
    catch (ParserConfigurationException ex)
    { throw new RuntimeException(ex.getMessage());
    }
  }

//==============================================================================
// ActionListener event handling ...
//------------------------------------------------------------------------------

  void handleBtnAddActionPerformedEvent(ActionEvent e) throws Exception
  { Node currentSelection = getSelectedTreeNode();
    if (currentSelection != null)
    { Element newBookElement = xmlDocument.createElement("Book");
      newBookElement.setAttribute("Price", tfPrice.getText());
      Element childElement = xmlDocument.createElement("Title");
      childElement.appendChild(
        xmlDocument.createTextNode(tfTitle.getText()));
      newBookElement.appendChild(childElement);
      childElement = xmlDocument.createElement("Description");
      childElement.appendChild(
        xmlDocument.createTextNode(taDescription.getText()));
      newBookElement.appendChild(childElement);
      xmlTreeModel.addXmlTreeNode(currentSelection, newBookElement);
      setSelectedTreeNode(newBookElement);
    }
  }

  void handleBtnChangeActionPerformedEvent(ActionEvent e) throws Exception
  { Node currentSelection = getSelectedTreeNode();
    if (currentSelection != null)
    { Element bookElement = (Element)currentSelection;
      bookElement.setAttribute("Price", tfPrice.getText());
      bookElement.getElementsByTagName("Title")
                 .item(0).getFirstChild()
                 .setNodeValue(tfTitle.getText());
      bookElement.getElementsByTagName("Description")
                 .item(0).getFirstChild()
                 .setNodeValue(taDescription.getText());
      xmlTreeModel.fireTreeNodeChanged(currentSelection);
      showNodeContent(currentSelection);
    }
  }

  void handleBtnRemoveActionPerformedEvent(ActionEvent e) throws Exception
  { xmlTreeModel.removeXmlTreeNode(getSelectedTreeNode());
    setSelectedTreeNode((Node)xmlTreeModel.getRoot());
  }

  void handleExitMenuItemActionPerformedEvent(ActionEvent e) throws Exception
  { System.exit(0);
  }

//==============================================================================
// TreeSelectionListener event handling ...
//------------------------------------------------------------------------------

  void handleBookshelfTreeValueChangedEvent(TreeSelectionEvent e) throws Exception
  { Object[] path = e.getPath().getPath();
    if (path.length > 0)
    { showNodeContent((Node)path[path.length - 1]);
    }
  }

//==============================================================================
// Execute this MyBookshelf Program ...
//------------------------------------------------------------------------------

  public static void main(String[] args)
  { MyBookshelf myBookshelf = new MyBookshelf();
  }

}