//Titel:        JTree
//Version:       1.0
//Copyright:     Copyright (c) 2003, 06
//Autor:         Dipl.-Inf., Dipl.-Ing. (FH) Michael Wilhelm
//Organisation:  HS Harz
//Beschreibung:  Einführung in JTree


// Einfaches Beispiel mit DefaultMutableTreeNode
// CTreeNodeRec liefert Zusatzinformationen, mit toString
// Klick Ereignis und Change im Editor

// Mouse Klick

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

import java.awt.event.*;

import javax.swing.tree.DefaultMutableTreeNode;

import javax.swing.tree.*;

import javax.swing.event.*;

import java.io.*;

import java.util.Vector;

public class Tree09 extends JFrame {

  JTree _Tree;


  DefaultMutableTreeNode rootNode;


  DefaultTreeModel treeModel;
  TreePath RootPath;

  private JSplitPane _SplitPane;
  MyEditor _editor;

  private int _NewIndex=0;

   // wird vom Tree aufgerufen,
    // hier muesste man weitere Dialogfenster aufrufen
   public void CreateAktionFromTreeNode( int i ) {
     _editor.setContent(i);
    System.out.println("in Methode CreateAktionFromTreeNode, ID: "+i);
   }

  public Tree09() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setLocation(50,50);
    setTitle("JTree mit Editor, kompexeres Beispiel");
    setSize(700, 600);
    setGUI();
  }



  private void setGUI() {
    JPanel panel = new JPanel();
    JButton BnExpand = new JButton("Expand"); // Add
    JButton BnRemove = new JButton("Remove");
    JButton BnAddNode = new JButton("Add Node");
    JButton BnClear = new JButton("Clear");

    this.getContentPane().setLayout( new BorderLayout() );

    panel.setLayout( new FlowLayout() );

    // ------------------

    BnExpand.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        BnExpand_click();
      }
    });
    panel.add(BnExpand);
    BnExpand.setFont( new Font("Arial", Font.BOLD,22)  );

    BnRemove.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        BnRemove_click();
      }
    });
    panel.add(BnRemove);
     BnRemove.setFont( new Font("Arial", Font.BOLD,22)  );

    BnAddNode.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        BnAddNode_click();
      }
    });
    panel.add(BnAddNode);
    BnAddNode.setFont( new Font("Arial", Font.BOLD,22)  );


    BnClear.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        BnClear_click();
      }
    });
    panel.add(BnClear);
    BnClear.setFont( new Font("Arial", Font.BOLD,22)  );


    BnClear = new JButton("Clear");
    BnClear.setFont( new Font("Arial", Font.BOLD,22)  );

    //---------------------------------------
    rootNode = BuildTree();

    treeModel = new DefaultTreeModel(rootNode);
    _Tree = new javax.swing.JTree(treeModel);  //  kein Root !!!
    _Tree.setFont( new Font("Arial", Font.BOLD,22)  );

    RootPath = _Tree.getSelectionPath();

     // import javax.swing.tree.*;
    _Tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
    // _Tree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
    //  SINGLE_TREE_SELECTION,
    // CONTIGUOUS_TREE_SELECTION
    // DISCONTIGUOUS_TREE_SELECTION.


    _Tree.addMouseListener(
          new java.awt.event.MouseAdapter() {
      public void mouseClicked(MouseEvent e) {
        _Tree_mouseClicked(e);
      }
    });


    _Tree.setBorder(BorderFactory.createLineBorder(Color.black));
    _Tree.setToolTipText("ToolTipp");
    _Tree.setShowsRootHandles(true);

      // Horizontale Linien
    _Tree.putClientProperty("JTree.lineStyle","Horizontal");
      // Mit Linien zwischen den Knoten
    _Tree.putClientProperty("JTree.lineStyle","Angled");

    this.getContentPane().add(panel, BorderLayout.NORTH);

    _editor = new MyEditor();
    _SplitPane = new JSplitPane();
    this.getContentPane().add(_SplitPane, BorderLayout.CENTER);
    _SplitPane.add( new JScrollPane(_Tree), JSplitPane.LEFT);
    _SplitPane.add(_editor.getEditor(), JSplitPane.RIGHT);
    _SplitPane.setDividerLocation(200);

  }  // setGUI



  void _Tree_mouseClicked(MouseEvent e) {
     if(e.getClickCount() == 1) {
        DefaultMutableTreeNode node;
        CTreeNodeRec CNode;
        node = (DefaultMutableTreeNode) _Tree.getLastSelectedPathComponent();
        if (node == null) {
           return;
        }
        else {
          CNode = (CTreeNodeRec) node.getUserObject();
          System.out.println("CSingleClick: "+node.toString()+" \n" +CNode.getData() );
          if ( CNode.getData()>2 ) {
            // Aufruf und Erzeugen eines Dialogfensters
             CreateAktionFromTreeNode( CNode.getData() );
             setTitle("Tree09.java, Data > 2");
          }
          else {
            setTitle("Tree09.java, getData <= 2");
          }
        }
     }

  }



  // ----------------------------
  DefaultMutableTreeNode BuildTree() {
    DefaultMutableTreeNode root;
    DefaultMutableTreeNode[]  Knoten = new DefaultMutableTreeNode[3];

    root = createCNode(  0,"root");  // new DefaultMutableTreeNode("root");

      // liefert einen DefaultMutableTreeNode
    Knoten[0] = createCNode(  1,"1. Stufe (1)");
    root.add( Knoten[0] );

    Knoten[1] = createCNode(  2,"AAA");
    Knoten[0].add( Knoten[1] );  // Parameter Vater
    Knoten[1] = createCNode(  3,"BBB");
    Knoten[0].add( Knoten[1] );  // Parameter Vater


    // ---------

    Knoten[0] = createCNode(  2,"1. Stufe (2)");
    root.add( Knoten[0] );

    Knoten[1] = createCNode(  6,"CCC");
    Knoten[0].add( Knoten[1] );  // Parameter Vater
    Knoten[1] = createCNode(  2,"DDDD");
    Knoten[0].add( Knoten[1] );  // Parameter Vater


    Knoten[0] = createCNode(  3,"1. Stufe (3)");
    root.add( Knoten[0] );

    Knoten[1] = createCNode(  6,"EEE");
    Knoten[0].add( Knoten[1] );  // Parameter Vater

      Knoten[2] = createCNode(  7,"E1E1E1");
      Knoten[1].add( Knoten[2] );  // Parameter Vater
      Knoten[2] = createCNode(  2,"E2E2E2");
      Knoten[1].add( Knoten[2] );  // Parameter Vater

    Knoten[1] = createCNode(  11,"FFF");
    Knoten[0].add( Knoten[1] );  // Parameter Vater
      Knoten[2] = createCNode(  2,"F1F1F1");
      Knoten[1].add( Knoten[2] );  // Parameter Vater
      Knoten[2] = createCNode(  4,"F2F2F2");
      Knoten[1].add( Knoten[2] );  // Parameter Vater

    return root;
  }  // BuildTree


 DefaultMutableTreeNode createCNode(int CData,  String nodeString) {
    CTreeNodeRec CNode;
    DefaultMutableTreeNode Node;

    CNode = new  CTreeNodeRec(CData, nodeString);
    Node = new DefaultMutableTreeNode(CNode);
    // Node = new DefaultMutableTreeNode(nodeString);
    //Node.setUserObject(CNode);
    return Node;
 }


   // einfügen eines Knotens
  void BnExpand_click() {
     // addNodes();
     //_Tree.expandPath( RootPath );  // funktionirt nicht ganz
     //_Tree.expandRow(0);
      // Alle Knoten öffnen
    for (int i=0; i<_Tree.getRowCount(); i++) {
      _Tree.expandRow(i);
    }
  }

   // einfügen eines Knoten am aktuellen Knoten
  void  BnAddNode_click() {
    TreePath currentSelection = _Tree.getSelectionPath();
    DefaultMutableTreeNode  Kn0;
    if (currentSelection != null) {
       DefaultMutableTreeNode currentNode = (DefaultMutableTreeNode)
                       (currentSelection.getLastPathComponent());
       DefaultMutableTreeNode parent = (DefaultMutableTreeNode)(currentNode.getParent());
       if (parent != null) {
         _NewIndex++;
         Kn0 = createCNode( _NewIndex,"Neuer Knoten "+ Integer.toString(_NewIndex));
         parent.add( Kn0 );
         _Tree.updateUI();
       }
       else  System.out.println("parent null");
      }
    else  System.out.println("curentselection == null");
  }  // BnAddNode_Click
  void BnRemove_click() {
    removeCurrentNode();
  }

  public void removeCurrentNode() {
      Toolkit toolkit = Toolkit.getDefaultToolkit();
      TreePath currentSelection = _Tree.getSelectionPath();
        toolkit.beep();
      if (currentSelection != null) {
          DefaultMutableTreeNode currentNode = (DefaultMutableTreeNode)
                       (currentSelection.getLastPathComponent());
          MutableTreeNode parent = (MutableTreeNode)(currentNode.getParent());
          if (parent != null) {
              treeModel.removeNodeFromParent(currentNode);
              return;
          }
      }

      // Either there was no selection, or the root was selected.
      toolkit.beep();
  }


  void BnClear_click() {
     rootNode.removeAllChildren();
     treeModel.reload();
  }


  public static void main(String[] args) {
    Tree09 frame = new Tree09();
    frame.setVisible(true);
 }


}  // Tree09




// Einfache Klasse für jeden Knoten
class CTreeNodeRec  {
  public static long nr=0;

    private long _id = 0; // Id des Knotens  z.B. als ID

    private int _CData;     // eigentliche Daten

    public String _nodeString;  // wie wird der Knoten dargestellt


   public CTreeNodeRec(int CData,  String nodeString) {
      _CData = CData;
      _nodeString = nodeString;  // für JTree;
      nr++;
      _id = nr;  // setzt eindeutige Nummer
   }


   public long getID() {
     return _id;
   }


   public int getData() {
     return _CData;
   }

   public void setData(int CData) {
     _CData = CData;
   }
   
   // sehr wichtig
   public String toString() {
     return _nodeString;
   }
}  // CTreeNodeRec





class MyEditor {

 private JTextArea _editor;
  public MyEditor() {
    _editor = new JTextArea("text\n2. Zeile");
    _editor.setFont( new Font("Arial", Font.BOLD,22)  );
 }

  public JTextArea getEditor() {
    return _editor;
  }


  public void setContent(int i) {
    _editor.setText( "Folgende Nummer wurde übergeben: "+i );
  }

}
