Attaching an event to a tree node

Hi there, hope to trigger a simple event when a tree node is click such as
<?xml version="1.0" encoding="utf-8"?>
<mx:Application 
xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:XML id="treeData" xmlns="">
<root>
<node label="Section 1" >
<node label="Section 1-1" >
<node label="Section 1-1-1" click="lbl1.text='section 1-1-1';" />
<node label="Section 1-1-2" click="lbl1.text='section 1-1-2';"/>
<node label="Section 1-1-3">
<node label="Section 1-1-3-1" />
<node label="Section 1-1-3-2" />
</node>
<node label="Section 1-1-4" />
</node>
<node label="Section 1-2" >
<node label="Section 1-2-1" />
<node label="Section 1-2-2" />
</node>
</node>
<node label="Section 2" >
<node label="Section 2-1" >
<node label="Section 2-1" />
</node>
</node>
</root>
</mx:XML> 
<mx:Tree width="246" left="10" top="10" id="tree" labelField="@label" dataProvider="{treeData.node}" height="540"/>
<mx:Label id="lbl1" x="395" y="155" text="Label1" width="151" />
</mx:Application>
The tree and its children were rendered properly on screen but clicking the relevant nodes didn't trigger the event. Please advise.
Regards
I F

I didn't see a click handler in your code either.  Try adding itemClick
though so you don't see clicks on scrollbars.
<mx:Tree width="246" left="10" top="10" id="tree" labelField="@label"
dataProvider="{treeData.node}" height="540" itemClick="trace(event)" /

Similar Messages

  • Action Event Handler on Tree nodes

    I have an actionListener event handler registered on a tree node as follows:
    <af:tree value="#{bindings.SomeViewObj1.treeModel}" var="node" rowSelection="none" id="t1"
    binding="#{EditFormBean.tree1}" displayRow="selected" summary="Tree"
    partialTriggers=":::cb1 :::cb2">
    <f:facet name="nodeStamp">
    <af:panelGroupLayout id="pgl3">
    <af:outputText value="#{node}" id="ot1"/>
    <af:commandImageLink text="E" id="cil3" partialSubmit="true"
    *actionListener="#{EditFormBean.onEdit}"* binding="#{EditFormBean.cmdImageLink}">
    <af:setPropertyListener from="#{node.hiertType.structureDefName}" type="action"
    to="#{viewScope.formView}"/>
    <f:attribute name="node" value="#{node}"/>
    </af:commandImageLink>
    <af:commandImageLink text="A" id="cil1"/>
    <af:commandImageLink text="D" id="cil2"/>
    </af:panelGroupLayout>
    </f:facet>
    </af:tree>
    I have at each node stamp facet a panelGroup Layout that contains the node value and a command Image link. The tree has two hierarchical levels. When I press the command Image link on the first tree noe level, the actioListener method in teh managed bean (EditFormBean.onEdit) gets called. When I press the same commandImage link on the second tree level, the same action listener does not get called. I need to get past this problem before I code the actionListener which needs to set the current row in the iterator based on the key selected on the tree node. I simply have a print statement in the action listener method which shows something when the first level command image link is clicked but does not print anything when the second level command image link is clicked.
    I am using JDeveloper 11.1.2.1.0
    There is also adf faces code around this snippet that uses an af:switcher facea component to display the appropriate form based on the nodee level in which the comman d image link is clicled but it is irrelevant to the problem I am getting.
    Any help on that would be appreciated

    Hi,
    hard to say . Didn't see this before. Can yoiu remove "binding="#{EditFormBean.cmdImageLink}"" from the command link. The tree stamps its children so that it doesn't make sense to keep a handle to the component instance
    Frank

  • How to run a form using tree node selection??

    hi...
    i have populated a tree with all the form name.There is a particular id for every form.i want to show a form using tree node selection.What i did...i write a trigger in button's click event when the tree node is selected then i get a id.if id=1 then open_form('test.fmx').when i want to execute this code then it is showing the same form 2 times.Can anyone help me to solve my problem?If so plz tell me what code i have to write to show a form using node selection?.

    I've done the same thing, and i think it works fine.
    Check this code (Sorry for the long post, but i cannot find how to attach files.
    PACKAGE menu_pk IS
    --Initialization of the menu.
    procedure Init;
    --Called from WHEN-TREE-NODE-EXPANDED
    procedure Expanded;
    --Called from WHEN-TREE-NODE-ACTIVATED
    procedure ExecuteCommand;
    END;
    PACKAGE BODY menu_pk IS
    MENU_NAME constant varchar2(30) := 'menu.menu';
    cursor c_menu(pRoot in varchar2) is
    select apm_code, apm_parcode, apm_descr, decode(apm_type, 0, Ftree.EXPANDED_NODE, Ftree.LEAF_NODE) apm_type,
    decode(apm_type, 0, 'menu', 1, 'form', 2, 'report') || '.ico' apm_icon
    from app_menu
    where apm_parcode = pRoot
    order by apm_code asc;
    procedure Init is
         new_node ftree.node;
    begin
         for i in c_menu('root')
         loop
    new_node := Ftree.add_tree_node(MENU_NAME, FTree.ROOT_NODE,
    Ftree.PARENT_OFFSET, Ftree.LAST_CHILD,
    i.apm_type, i.apm_descr, i.apm_icon, i.apm_code);
         end loop;
    end;
    procedure FillNode(pNode in FTree.Node) is
         new_node ftree.node;
    begin
         for i in c_menu(FTree.get_tree_node_property(MENU_NAME, pNode, FTree.NODE_VALUE))
         loop
    new_node := Ftree.add_tree_node(MENU_NAME, pNode,
    Ftree.PARENT_OFFSET, Ftree.LAST_CHILD,
    i.apm_type, i.apm_descr, i.apm_icon, i.apm_code);
         end loop;
    end;
    procedure DeleteNodeChilds is
    node FTree.NODE;
    begin
         loop
    node := FTree.Find_Tree_Node(MENU_NAME, '',
         FTree.FIND_NEXT_CHILD, FTree.NODE_VALUE,
         name_in('system.trigger_node'), name_in('system.trigger_node'));
              exit when Ftree.ID_NULL(node);
              FTree.delete_tree_node(MENU_NAME, node);
         end loop;
    end;
    procedure Expanded is
    begin
         if (FTree.GET_TREE_NODE_PROPERTY(MENU_NAME, :system.trigger_node, FTree.Node_State) = FTree.EXPANDED_NODE) then
         menu_pk.FillNode(name_in('system.trigger_node'));
         else
              menu_pk.DeleteNodeChilds;
         end if;
    end;
    procedure ExecuteCommand is
    cursor c_command(pCode in varchar2) is
    select apm_form, apm_type
    from app_menu
    where apm_code = pCode;
    fCommand c_command%rowtype;
    fMenuCode varchar2(20);
    begin
         -- if it is as menu node then exit.
    if (not FTree.Get_Tree_Node_Property(MENU_NAME, :system.trigger_node, FTree.NODE_STATE) = FTree.LEAF_NODE) then
         return;
    end if;
    fMenuCode := FTree.Get_Tree_Node_Property(MENU_NAME, :system.trigger_node, FTree.NODE_VALUE);
         open c_command(fMenuCode);
         fetch c_command into fCommand;
         close c_command;
         if (fCommand.apm_type = 1) and (fCommand.apm_form is not null) then
              globals.Set_MenuChoice(fMenuCode);
              OPEN_FORM(fCommand.apm_form);--, ACTIVATE, SESSION);
         end if;
    end;
    END;
    The menu table definition follows.
    create table APP_MENU
    APM_CODE VARCHAR2(10) not null,
    APM_PARCODE VARCHAR2(10) not null,
    APM_DESCR VARCHAR2(40) not null,
    APM_TYPE NUMBER(1) not null,
    APM_FORM VARCHAR2(50)
    alter table APP_MENU
    add constraint APP_MENU_PRI primary key (APM_CODE);
    Hope this helps

  • Tree and Tree Node Components - Threadinar7

    Hi All,
    This is the seventh in the "Threadinar" series , please see Threadinar6 at
    http://forum.sun.com/jive/thread.jspa?threadID=100601 for details
    In this Threadinar we will focus on the
    "Tree" and "Tree Node" Components
    Let us begin our discussion with the Tree Component.
    Tree Component
    You can drag the Tree component from the Palette's Basic category to the Visual Designer to create a hierarchical tree structure with nodes that can be expanded and collapsed, like the nodes in the Outline window. When the user clicks a node, the row will be highlighted. A tree is often used as a navigation mechanism.
    A tree contains Tree Node components, which act like hyperlinks. You can use a Tree Node to navigate to another page by setting its url property. You can also use a Tree Node to submit the current page. If the the Tree Node's action property is bound to an action event handler, selecting the node automatically submits the page. If the Tree Node's actionListener property is bound to an action listener, opening or closing the node automatically submits the page. You set Tree Node properties in the Tree Node Component Properties window.
    * If you use this component to navigate between pages of a portlet, do not use the url property to link to a page. Instead, use the Navigation editor to set up your links to pages.
    * Events related to tree node selection do not work correctly in portlets because the component uses cookies to pass the selected node id back and forth, and cookies are not correctly handled by the portlet container. You cannot handle tree node selection events in portlet projects.
    Initially when you drop a tree on a page, it has one root node labeled Tree and one subnode labeled Tree Node 1. You can add more nodes by dragging them to the tree and dropping them either on the root node to create top level nodes or on existing nodes to create subnodes of those nodes. You can also right-click the Tree or any Tree Node and choose Add Tree Node to add a subnode to the node.
    Additionally, you can work with the component in the Outline window, where the component and its child components are available as nodes. You can move a node from level to level easily in the Outline window, so you might want to work there if you are rearranging nodes. You can also add and delete tree nodes in the Outline window, just as in the Visual Designer.
    The Tree component has properties that, among other things, enable you change the root node's displayed text, change the appearance of the text, specify if expanding or collapsing a node requires a trip to the server, and specify whether node selection should automatically open or close the tree. To set the Tree's properties, select the Tree component in your page and use the Tree Component Properties window.
    The following Tutorial ("Using Tree Component") is very useful to learn using Tree components
    http://developers.sun.com/prodtech/javatools/jscreator/learning/tutorials/2/sitemaptree.html
    See Also the Technical Article - "Working with the Tree Component and Tree Node Actions"
    http://developers.sun.com/prodtech/javatools/jscreator/reference/techart/2/tree_component.html
    Tree Node Component
    You can drag the Tree Node component from the Palette's Basic category to a Tree component or another tree node in the Visual Designer to create a node in a hierarchical tree structure, similar to the tree you see in the Outline window.
    The tree node is created as a subnode of the node on which you drop it. If you drop the node on the tree component itself, a new node is created as a child of the root node. You can see the hierarchical structure clearly in the Outline window, where you can also easily move nodes around and reparent them.
    You can also add a tree node either to a Tree component or to a Tree Node component by right-clicking the component and choosing Add Tree Node.
    A Tree Node component by default is a container for an image and can be used to navigate to another page, submit the current page, or simply open or close the node if the node has child nodes.
    * If you select the Tree Node component's node Tree Node icon in the Outline window, you can edit its properties in the Tree Node Properties window. You can set things like whether or not the Tree Node is expanded by default, the tooltip for the Tree Node, the label for the tree node, and the Tree Node's identifier in your web application.
    * You can use a Tree Node to navigate to another page by setting its url property. You can also use a Tree Node to submit the current page. If the the Tree Node's action property is bound to an action event handler, selecting the node automatically submits the page. If the Tree Node's actionListener property is bound to an action listener, opening or closing the node automatically submits the page.
    - Note: If you use this component to navigate between pages of a portlet, do not use the url property to link to a page. Instead, use the Navigation editor to set up your links to pages. In addition, events related to tree node selection do not work correctly in portlets because the component uses cookies to pass the selected node id back and forth, and cookies are not correctly handled by the portlet container. You cannot handle tree node selection events in portlet projects.
    * If you select the image in the Tree Node, you can see that its icon property is set to TREE_DOCUMENT. If you right-click the image on the page and choose Set Image, you can either change the icon to another one or choose your own image in the Image Customizer dialog box. For more information on working with an image in a tree node, see Image component.
    - Note: The image used in a tree node works best if it is 16x16 or smaller. Larger images can work, but might appear overlapped in the Visual Designer. You can right-click the component and choose Preview in Browser feature to check the appearance of the images.
    Please share your comments, experiences, additional information, questions, feedback, etc. on these components.
    ------------------------------------------------------------------------------- --------------------

    One challenge I had experience was to make the tree
    always expanded on all pages (I placed my tree menu
    in a page fragment so I can just import it in my
    pages).Did you solve this problem. It would be interesting to know what you did.
    To expand a node you call setExpanded on the node. Here is some code from a tutorial that a coworker of mine is working on.
    In the prerender method:
           Integer expandedPersonId = getRequestBean1().getPersonId();
             // If expandedPersonId is null, then we are not coming back
            // from the Trip page. In that case we do not want any trip
            // nodes to be pre-selected (highlighted) due to browser cookies.
            if (expandedPersonId==null) {
                try {
                    HttpServletRequest req =(HttpServletRequest)
                    getExternalContext().getRequest();
                    Cookie[] cookies = req.getCookies();
                    //Check if cookies are set
                    if (cookies != null) {
                        for (int loop =0; loop < cookies.length; loop++) {
                            if (cookies[loop].getName().equals
                                    ("form1:displayTree-hi")) {
                                cookies[loop].setMaxAge(0);
                                HttpServletResponse response =(HttpServletResponse)
                                getExternalContext().getResponse();
                                response.addCookie(cookies[loop]);
                } catch (Exception e) {
                    error("Failure trying to clear highlighting of selected node:" +
                            e.getMessage());
            }                  ... (in a loop for tree nodes)...
                      personNode.setExpanded(newPersonId.equals
                                    (expandedPersonId));In the action method for the nodes:
           // Get the client id of the currently selected tree node
            String clientId = displayTree.getCookieSelectedTreeNode();
            // Extract component id from the client id
            String nodeId = clientId.substring(clientId.lastIndexOf(":")+1);
            // Find the tree node component with the given id
            TreeNode selectedNode =
                    (TreeNode) this.getForm1().findComponentById(nodeId);
            try {
                // Node's id property is composed of "trip" plus the trip id
                // Extract the trip id and save it for the next page
                Integer tripId = Integer.valueOf(selectedNode.getId().substring(4));
                getRequestBean1().setTripId(tripId);
            } catch (Exception e) {
                error("Can't convert node id to Integer: " +
                        selectedNode.getId().substring(4));
                return null;
    It would also be great if I can set the tree
    readonly where the user cannot toggle the expand
    property of the tree (hope this can be added to the
    tree functionality).

  • Checking if user has selected or deselected a tree node

    Hello,
    In the event handler of the On Action event of a tree node, I need to decide whether the user has selected the element or deselected it.
    I thought to use the following:
    data:  lo_node type ref to if_wd_context_node,
             lo_element type ref to if_wd_context_element,
             l_element_selected type abap_bool.
    first I tried
    * need to find out if this element was selected or deselected!
      l_element_selected = context_element->is_selected( ).
    but it didn't work - so I tried
    lo_node = context_element->get_node( ).
      lo_element = lo_node->get_lead_selection( ).
      if lo_element = context_element.
        l_element_selected = abap_true.
      else.
        l_element_selected = abap_false.
      endif.
    This did work.
    I'm slightly confused as to why the two did not give the same result?
    I can see in the implementation why - gotta love being able to see how the engine works - but why is the node selection table not set? For future reference, is there some flow that has to happen before the selection gets set but after the lead selection is made? Or is this just an error in the handling of the tree node element?
    Cheers,
    Chris

    One would wonder why there is no is_Lead_Selected method. Having just the is _ Multi_  Selected method is quite confusing. Especially when the method description is "True, if element is selected in the node". One would assume that this would include lead selection.
    Then again - when you consider the mismatch between methods that return values and methods that export values, this lack of a is_Lead_Selected method would be low down on my list of things to fix to make WDA more consistent.
    Having Get_Static_Attributes return the data rather than export it would be much higher on my list - ( get_static_attributes_ref does actually return the reference to the data - talk about inconsistent! )

  • Confirmation Dialog when clicking on Tree Node.

    I am working on Oracle Apex 4.2.0.00.27 and I have the following problem:
    The code below shows the definition of a tree. The tree displays records from the table ACTIVITIES in hierarchical structure.
    When user clicks on a leaf/node of the tree he will be redirected to another page where the details of each Activity/leaf/node are displayed.
    The tree is part of a page where I have established a functionality to check for changes on the input fields of the page and inform the user when he tries to redirect without first saving the changes he made.
    What I want to do is:
    WHEN user clicks on a node of the tree AND he hasn't saved any changes he made
    THEN
    trigger a confirmation dialog.
    IF
    he clicks OK he is redirected to the node details page as defined on the tree definition:
    f?p=&APP_ID.:10:'||:APP_SESSION||'::::P10_ID:'||"ID"
    ELSE if he clicks CANCEL
    he stays on the same page.
    The condition to trigger the confirmation box is:
    if (document.getElementById('P0_CHANGES_DETECTED').value == 1)
    where P0_CHANGES_DETECTED is a universal hidden text field that is set to +'1'+ every time a change is made.
    and here is the tree definition:
    select case when connect_by_isleaf = 1 then 0
    when level = 1             then 1
    else                           -1
    end as status,
    level,
    +"NAME" as title,+
    null as icon,
    +"ID" as value,+
    null as tooltip,
    decode(PARENT_ID,null,null, 'f?p=&APP_ID.:10:'||:APP_SESSION||'::::P10_ID:'||"ID") as link
    from "#OWNER#"."ACTIVITIES"
    where GROUP_ID = :P20_GROUP_ID
    start with "ID" in (select ID from "#OWNER#"."ACTIVITIES" where GROUP_ID = :P20_GROUP_ID and PARENT_ID is null)
    connect by prior "ID" = "PARENT_ID"
    order siblings by "ID"
    I hope it is clear what I want to achieve. Thanks in advance.

    So you'll want to bind an event to all tree nodes that checks for the value and then fires the confirmation if there value is 1.
    Try something like this:
    - first, give your static ID attribute in your tree the value of tree_static_id (or whatever you want. just replace the id selector below with what you choose).
    - In your Page Function and Variable Declaration Javascript:
    function confirmSave() {
    var changeDetected = jQuery('#P0_CHANGES_DETECTED').val();
    if(changeDetected == 1) {
    //only do this if change is detected
    if(confirm('You have unsaved changes. Do you want to leave this page?')) {
    window.location('[your url here]');
    jQuery(document).ready(function() {
    //bind function to the click event
    $('#tree_static_id').find('li a').bind('click', function() { confirmSave(); } });
    });Hope this helps

  • WebDynpro ABAP tree node collapse trigger event of row selection

    Hello expert,
    I have a table in my WD abap view, I use MasterColumn to display the tree structure, everything works just fine.
    However I encounter one problem:
    If I open the tree structure and select one node (table row selection), the event onLeadSelectis triggered, this is correct. However if I collapse any  parent nodes (along the tree path) of the selected node, WD puts the selection on the clicked parent and thus the event onLeadSelect is triggered for the parent. This is a strange behavior, because when I collapse a node, I certainly don't want to trigger the onLeadSelect event for the node, becaseu this would invoke the function linked to the event which is only supposed to be triggered when you explicitly select the table row.  (BTW, if you don't select any child nodes, then collapse the parent, it does NOT trigger the event).
    I've looked into the wdevent data to see if I can differentiate between the event of node collapsing and row selecting, event data is exact same for both cases, thus I have no way to stop the event handler in case of node collapsing.
    Anyone had this issue and a solution for this?
    Thanks
    Jayson

    Hi Jayson,
    Its the behavior of the tree element, the lead selection of child is carried over to the parent.
    Whenever there is lead selection set and on toggling of tree node, first OnToggle event triggers and then OnLeadSelect triggers. So you can control the execution of onLeadSelect by using EXPANDED parameter of event OnToggle.
    Please refer the below steps:
    Create an action ON_TOGGLE for the vent OnToggle of tree element and it will be having parameter EXPANDED
    Create an attribute in view-->attributes tab GV_EXPANDED
    Collect the parameter EXPANDED into gv_expanded
              wd_this->gv_expanded = expanded.
    Now, you can use wd_this->gv_expanded to control the execution of LEADSELECT logic
    Hope this helps you.
    Regards,
    Rama

  • How to trigger event when double click on a tree node

    I have this code which creates new tab in a remote Java Class.
    treeView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<TreeItem<String>>()
       @Override
       public void changed(ObservableValue<? extends TreeItem<String>> observable, TreeItem<String> oldValue, TreeItem<String> newValue)
       System.out.println("Selected Text : " + newValue.getValue());
       // Create New Tab
       Tab tabdata = new Tab();
       Label tabALabel = new Label("Test");
      tabdata.setGraphic(tabALabel);
       DataStage.addNewTab(tabdata);
    Can you tell me how I can modify the code to open new tab when I double click on a tree node. In my code the tab is opened when I click once. What event handler do I need?

    import java.util.Arrays;
    import javafx.application.Application;
    import javafx.event.EventHandler;
    import javafx.stage.Stage;
    import javafx.scene.Scene;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.layout.StackPane;
    import javafx.scene.control.TreeCell;
    import javafx.scene.control.TreeView;
    import javafx.scene.control.TreeItem;
    import javafx.scene.control.SelectionMode;
    import javafx.util.Callback;
    public class TreeTest extends Application {
      public static void main(String[] args) {
        launch(args);
      @Override
      public void start(Stage primaryStage) throws Exception {
        primaryStage.setTitle("TreeView Test");
        primaryStage.setScene(createScene());
        primaryStage.show();
      private Scene createScene() {
        final StackPane stackPane = new StackPane();
        final TreeView<String> treeView = new TreeView<String>();
        treeView.setRoot(createModel());
        treeView.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
        treeView.setCellFactory(new Callback<TreeView<String>, TreeCell<String>>() {
          @Override
          public TreeCell<String> call(TreeView<String> treeView) {
            return new ClickableTreeCell();
        stackPane.getChildren().add(treeView);
        return new Scene(stackPane);
      private TreeItem<String> createModel() {
        TreeItem<String> root = new TreeItem<String>("RootNode");
        TreeItem<String> packageA = new TreeItem<String>("package A");
        packageA.getChildren().addAll(
            Arrays.asList(new TreeItem<String>("A1"), new TreeItem<String>("A2"), new TreeItem<String>("A3"))
        TreeItem<String> packageB = new TreeItem<String>("package B");
        packageB.getChildren().addAll(
            Arrays.asList(new TreeItem<String>("B1"), new TreeItem<String>("B2"), new TreeItem<String>("B3"))
        root.getChildren().addAll(Arrays.asList(packageA, packageB));
        return root;
      private class ClickableTreeCell extends TreeCell<String> {
        ClickableTreeCell() {
          setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
              // Handle double-clicks on non-empty cells:
              if (event.getClickCount()==2 && ! isEmpty()) {
                System.out.println("Mouse double-clicked on: " + getItem());
        @Override
        protected void updateItem(String item, boolean empty) {
          super.updateItem(item, empty);
          if (empty) {
            setText(null);
          } else {
            setText(item);

  • Getting text of tree node

    Hi all,
    When I click on any tree node I need to save the node text at the corresponding node in a variable.Can this be done with onTreeClick?How?

    use onNodeClick of treeNode
    capture the event in oninputprocessing to get the id of the node clicked and read the itab (passed to tree) to get the text of the node.
    Regards
    Raja
    close your previous thread
    where is an attachment saved ?

  • How to resize a custom tree node like you would a JFrame window?

    Hello,
    I am trying to resize a custom tree node like you would a JFrame window.
    As with a JFrame, when your mouse crosses the Border, the cursor should change and you are able to drag the edge to resize the node.
    However, I am faced with a problem. Border cannot detect this and I dont want to use a mouse motion listener (with a large number of nodes, I fear it will be inefficient, calculating every node's position constantly).
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Component;
    import java.awt.Dimension;
    import java.awt.Insets;
    import java.util.EventObject;
    import javax.swing.BorderFactory;
    import javax.swing.Box;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    import javax.swing.JTree;
    import javax.swing.tree.DefaultMutableTreeNode;
    import javax.swing.tree.DefaultTreeCellEditor;
    import javax.swing.tree.DefaultTreeCellRenderer;
    import javax.swing.tree.DefaultTreeModel;
    import javax.swing.tree.TreeSelectionModel;
    public class ResizeNode extends JPanel {
           AnilTreeCellRenderer2 atcr;
           AnilTreeCellEditor2 atce;
           DefaultTreeModel treeModel;
           JTree tree;
           DefaultMutableTreeNode markedNode = null;
         public ResizeNode() {
                super(new BorderLayout());
                   treeModel = new DefaultTreeModel(null);
                   tree = new JTree(treeModel);          
                  tree.setEditable(true);
                   tree.getSelectionModel().setSelectionMode(
                             TreeSelectionModel.SINGLE_TREE_SELECTION);
                   tree.setShowsRootHandles(true);
                  tree.setCellRenderer(atcr = new AnilTreeCellRenderer2());
                  tree.setCellEditor(atce = new AnilTreeCellEditor2(tree, atcr));
                   JScrollPane scrollPane = new JScrollPane(tree);
                   add(scrollPane,BorderLayout.CENTER);
         public void setRootNode(DefaultMutableTreeNode node) {
              treeModel.setRoot(node);
              treeModel.reload();
           public static void main(String[] args){
                ResizeNode tb = new ResizeNode();
                tb.setPreferredSize(new Dimension(400,200));
                  JFrame frame = new JFrame("ResizeNode");
                  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  frame.setContentPane(tb);
                  frame.setSize(400, 200);
                  frame.pack();
                  frame.setVisible(true);
                  tb.populate();
         private void populate() {
              TextAreaNode2 r = new TextAreaNode2(this);
               setRootNode(r);
               TextAreaNode2 a = new TextAreaNode2(this);
               treeModel.insertNodeInto(a, r, r.getChildCount());          
    class AnilTreeCellRenderer2 extends DefaultTreeCellRenderer{
    TreeBasic panel;
    DefaultMutableTreeNode currentNode;
      public AnilTreeCellRenderer2() {
         super();
    public Component getTreeCellRendererComponent
       (JTree tree, Object value, boolean selected, boolean expanded,
       boolean leaf, int row, boolean hasFocus){
         TextAreaNode2 currentNode = (TextAreaNode2)value;
         NodeGUI2 gNode = (NodeGUI2) currentNode.gNode;
        return gNode.box;
    class AnilTreeCellEditor2 extends DefaultTreeCellEditor{
      DefaultTreeCellRenderer rend;
      public AnilTreeCellEditor2(JTree tree, DefaultTreeCellRenderer r){
        super(tree, r);
        rend = r;
      public Component getTreeCellEditorComponent(JTree tree, Object value,
       boolean isSelected, boolean expanded, boolean leaf, int row){
        return rend.getTreeCellRendererComponent(tree, value, isSelected, expanded,
         leaf, row, true);
      public boolean isCellEditable(EventObject event){
        return true;
    class NodeGUI2 {
         final ResizeNode view;
         Box box = Box.createVerticalBox();
         final JTextArea aa = new JTextArea( 1, 5 );
         final JTextArea aaa = new JTextArea( 1, 8 );
         NodeGUI2( ResizeNode view_ ) {
              this.view = view_;
              box.add( aa );
              aa.setBorder( BorderFactory.createMatteBorder( 0, 0, 1, 0, Color.GREEN ) );
              box.add( aaa );
              box.setBorder( BorderFactory.createMatteBorder( 5, 5, 5, 5, Color.CYAN ) );
         private Dimension getEditorPreferredSize() {
              Insets insets = box.getInsets();
              Dimension boxSize = box.getPreferredSize();
              Dimension aaSize = aa.getPreferredSize();
              Dimension aaaSize = aaa.getPreferredSize();
              int height = aaSize.height + aaaSize.height + insets.top + insets.bottom;
              int width = Math.max( aaSize.width, aaaSize.width );
              if ( width < boxSize.width )
                   width += insets.right + insets.left + 3;     // 3 for cursor
              return new Dimension( width, height );               
    class TextAreaNode2 extends DefaultMutableTreeNode {  
         NodeGUI2 gNode;
         TextAreaNode2(ResizeNode view_) {     
              gNode = new NodeGUI2(view_);
    }

    the node on the tree is only painted on using the
    renderer to do the painting work. A mouse listener
    has to be added to the tree, and when moved over an
    area, you have to determine if you are over the
    border and which direction to update the cursor and
    to know which way to resize when dragged. One of the
    BasicRootPaneUI has some code that can help determine
    that.Thanks for replying. What is your opinion on this alternative idea that I just had?
    I am wondering if it might be easier to have a toggle button in the node that you click when you want to resize the node. Then a mouse-down and dragging the mouse will resize the node. Mouse-up will reset the toggle button, and so will mouse down in an invalid area.
    Anil

  • How to handle check box events in alv tree.

    hi,
    i am working in CL_GUI_COLUMN_TREE class.Also using Check box. Now i want to handle events for check box . I am new to ABAP Objects.
    Pls expaline in detail or send code
    thanks in advance,
    senthil kumar.r

    Hello Senthil
    Have a look at the sample report
    SAPCOLUMN_TREE_CONTROL_DEMO
    . The crucial points are:
    <b>(1) Register the required events at the control</b>
    * define the events which will be passed to the backend
      " checkbox change
      event-eventid = CL_GUI_COLUMN_TREE=>EVENTID_checkbox_change.
      event-appl_event = 'X'.
      append event to events.
      CALL METHOD G_TREE->SET_REGISTERED_EVENTS
        EXPORTING
          EVENTS = EVENTS
        EXCEPTIONS
          CNTL_ERROR                = 1
          CNTL_SYSTEM_ERROR         = 2
          ILLEGAL_EVENT_COMBINATION = 3.
      IF SY-SUBRC <> 0.
        MESSAGE A000.
      ENDIF.
    <b>(2) Set the event handler</b>
    assign event handlers in the application class to each desired event
      SET HANDLER G_APPLICATION->HANDLE_CHECKBOX_CHANGE FOR g_tree.
    <b>(3) Define and implement event handler method</b>
      METHOD  HANDLE_CHECKBOX_CHANGE.
        " this method handles the checkbox_change event of the tree
        " control instance
        " show the key of the node and the name of the item
        " of the clicked checkbox in a dynpro field
        G_EVENT = 'CHECKBOX_CHANGE'.
        G_NODE_KEY = NODE_KEY.
        G_ITEM_NAME = ITEM_NAME.
        CLEAR  G_HEADER_NAME.
      ENDMETHOD.
    Regards
      Uwe

  • Useful Code of the Day:  Hideable Tree Nodes

    Someone posted about how they could selectively hide tree nodes, and I already had this AbstractTreeModel class (which does some things DefaultTreeModel does and some it doesn't) and a concrete subclass for TreeNode objects, so I was thinking how one could do hideable nodes. So I came up with this solution.
    There's 4 classes here:
    - AbstractTreeModel is the base for the concrete TreeNodeTreeModel
    - TreeNodeTreeModel extends AbstractTreeModel to support TreeNodes (DefautlMutableTreeNode, etc.)
    - HideableMutableTreeNode which is a DefautlMutableTreeNode subclass which has a visible field (with is/set methods, of course).
    - HideableTreeModel is the hideable model which is a subclass of TreeNodeTreeModel.
    A HideableMutableTreeNode can be set invisible directly, but the tree still needs to be notified to update. So it's best to use the methods in HideableTreeModel which set a node's visibility which notify the tree of changes accordingly. Methods are also provided to check a full path's visibility or ensure a node including all parent nodes are visible.
    A HideableTreeModel can take any TreeNode class, it doesn't have to be all HideableMutableTreeNodes, but only HideableMutableTreeNodes can be made invisible, of course. Any other TreeNode type would just be considered visible.
    Hiding nodes works basically by making the tree think there's less nodes then there are. And to do this, the node counts and child index search just works by looping thru the parent's children. This has potential perfomance drawbacks of course, since one has to loop thru the node's children to get nodes every time. This could be alleviated by not supporting non-hideable nodes changing the internal maintenance of HideableMutableTreeNode contents. But I'll leave that to whoever really needs it. It shouldn't be a problem if there are are a relatively small set of child nodes in any given parent.
    Also, note that the root node in the model cannot be made invisible, cuz it'd be redundant since JTree can be set to hide the root node.
    // *** HideableTreeModel ***
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.event.*;
    import javax.swing.tree.*;
    * <code>HideableTreeModel</code> is an <code>TreeNodeTreeModel</code>
    * implementation for <code>HideableMutableTreeNode</code> objects.  The
    * model can also take any other <code>javax.swing.tree.TreeNode</code>
    * objects. 
    public class HideableTreeModel extends TreeNodeTreeModel {
          * Creates a new <code>HideableTreeModel</code> object.
          * @param  root  the root node
         public HideableTreeModel(TreeNode root) {
              super(root);
          * Checks if the specified node is visible.  A node can only be
          * hidden if the node is an instance of <code>HideableMutableTreeNode</code>.  <br />
          * <br />
          * Note that this only test the visibility of the specified node, not
          * whether a parent node is visible.  Use <code>isPathToNodeVisible(Object)</code>
          * to check if the full path is visible. 
          * @param  node  the node
          * @param  true if the node is visible, else false
         public boolean isNodeVisible(Object node) {
              if(node != getRoot()) {
                   if(node instanceof HideableMutableTreeNode) {
                        return ((HideableMutableTreeNode)node).isVisible();
              return true;
          * Sets the specified node to be hidden.  A node can only be made hidden
          * if the node is an instance of <code>HideableMutableTreeNode</code>.  <br />
          * <br />
          * Note that this method will notify the tree to reflect any changes to
          * node visibility.  <br />
          * <br />
          * Note that this will not alter the visibility of any nodes in the
          * specified node's path to the root node.  Use
          * <code>ensurePathToNodeVisible(Object)</code> instead to make sure the
          * full path down to that node is visible.  <br />
          * <br />
          * Note that this method will notify the tree to reflect any changes to
          * node visibility. 
          * @param  node  the node
          * @param  v     true for visible, false for hidden
          * @param  true if the node's visibility could actually change, else false
         public boolean setNodeVisible(Object node, boolean v) {
              // can't hide root
              if(node != getRoot()) {
                   if(node instanceof HideableMutableTreeNode) {
                        HideableMutableTreeNode n = (HideableMutableTreeNode)node;
                        // don't fix what ain't broke...
                        if(v != n.isVisible()) {
                             TreeNode parent = n.getParent();
                             if(v) {
                                  // need to get index after showing...
                                  n.setVisible(v);
                                  int index = getIndexOfChild(parent, n);
                                  super.nodeInserted(parent, n, index);
                             } else {
                                  // need to get index before hiding...
                                  int index = getIndexOfChild(parent, n);
                                  n.setVisible(v);
                                  super.nodeRemoved(parent, n, index);
                        return true;
              return false;
          * Checks if the specified node is visible and all nodes above it are
          * visible. 
          * @param  node  the node
          * @param  true if the path is visible, else false
         public boolean isPathToNodeVisible(Object node) {
              Object[] path = getPathToRoot(node);
              for(int i = 0; i < path.length; i++) {
                   if(!isNodeVisible(path)) {
                        return false;
              return true;
         * Sets the specified node and all nodes above it to be visible.
         * Note that this method will notify the tree to reflect any changes to
         * node visibility.
         * @param node the node
         public void ensurePathToNodeVisible(Object node) {
              Object[] path = getPathToRoot(node);
              for(int i = 0; i < path.length; i++) {
                   setNodeVisible(path[i], true);
         * Returns the child of parent at index index in the parent's child array.
         * @param parent the parent node
         * @param index the index
         * @return the child or null if no children
         public Object getChild(Object parent, int index) {
              if(parent instanceof TreeNode) {
                   TreeNode p = (TreeNode)parent;
                   for(int i = 0, j = -1; i < p.getChildCount(); i++) {
                        TreeNode pc = (TreeNode)p.getChildAt(i);
                        if(isNodeVisible(pc)) {
                             j++;
                        if(j == index) {
                             return pc;
              return null;
         * Returns the number of children of parent.
         * @param parent the parent node
         * @return the child count
         public int getChildCount(Object parent) {
              int count = 0;
              if(parent instanceof TreeNode) {
                   TreeNode p = (TreeNode)parent;
                   for(int i = 0; i < p.getChildCount(); i++) {
                        TreeNode pc = (TreeNode)p.getChildAt(i);
                        if(isNodeVisible(pc)) {
                             count++;
              return count;
         * Returns the index of child in parent.
         * @param parent the parent node
         * @param child the child node
         * @return the index of the child node in the parent
         public int getIndexOfChild(Object parent, Object child) {
              int index = -1;
              if(parent instanceof TreeNode && child instanceof TreeNode) {
                   TreeNode p = (TreeNode)parent;
                   TreeNode c = (TreeNode)child;
                   if(isNodeVisible(c)) {
                        index = 0;
                        for(int i = 0; i < p.getChildCount(); i++) {
                             TreeNode pc = (TreeNode)p.getChildAt(i);
                             if(pc.equals(c)) {
                                  return index;
                             if(isNodeVisible(pc)) {
                                  index++;
              return index;
         * Main method for testing.
         * @param args the command-line arguments
         public static void main(String[] args) {
              JFrame f = new JFrame();
              f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              HideableMutableTreeNode root = new HideableMutableTreeNode("root");
              root.add(new HideableMutableTreeNode("child_1"));
              final HideableMutableTreeNode c2 = new HideableMutableTreeNode("child_2");
              c2.setVisible(false);
              final HideableMutableTreeNode c2a = new HideableMutableTreeNode("child_2_A");
              c2.add(c2a);
              c2.add(new HideableMutableTreeNode("child_2_B"));
              root.add(c2);
              HideableMutableTreeNode c3 = new HideableMutableTreeNode("child_3");
              HideableMutableTreeNode cC = new HideableMutableTreeNode("child_3_C");
              cC.setVisible(false);
              c3.add(cC);
              c3.add(new HideableMutableTreeNode("child_3_D"));
              root.add(c3);
              root.add(new HideableMutableTreeNode("child_4"));
              root.add(new HideableMutableTreeNode("child_5"));
              DefaultMutableTreeNode c6 = new DefaultMutableTreeNode("child_6");
              c6.add(new DefaultMutableTreeNode("child_6_A"));
              c6.add(new DefaultMutableTreeNode("child_6_B"));
              root.add(c6);
              final HideableTreeModel model = new HideableTreeModel(root);
              JTree tree = new JTree(model);
              f.getContentPane().add(new JScrollPane(tree), BorderLayout.CENTER);
              JButton b = new JButton("toggle");
              b.addActionListener(new ActionListener() {
                   public void actionPerformed(ActionEvent e) {
                        model.setNodeVisible(c2, !model.isNodeVisible(c2));
                        //model.ensurePathToNodeVisible(c2a);
              f.getContentPane().add(b, BorderLayout.SOUTH);
              f.pack();
              f.setSize(300, 500);
              f.show();
    // *** HideableMutableTreeNode ***
    import javax.swing.*;
    import javax.swing.tree.*;
    * <code>HideableMutableTreeNode</code> is a <code>DefaultMutableTreeNode</code>
    * implementation that works with <code>HideableTreeModel</code>.
    public class HideableMutableTreeNode extends DefaultMutableTreeNode {
         * The node is visible flag.
         public boolean visible = true;
         * Creates a tree node that has no parent and no children, but which
         * allows children.
         public HideableMutableTreeNode() {
              super();
         * Creates a tree node with no parent, no children, but which allows
         * children, and initializes it with the specified user object.
         * @param userObject - an Object provided by the user that
         * constitutes the node's data
         public HideableMutableTreeNode(Object userObject) {
              super(userObject);
         * Creates a tree node with no parent, no children, initialized with the
         * specified user object, and that allows children only if specified.
         * @param userObject - an Object provided by the user that
         * constitutes the node's data
         * @param allowsChildren - if true, the node is allowed to have child
         * nodes -- otherwise, it is always a leaf node
         public HideableMutableTreeNode(Object userObject, boolean allowsChildren) {
              super(userObject, allowsChildren);
         * Checks if the node is visible.
         * @return true if the node is visible, else false
         public boolean isVisible() {
              return this.visible;
         * Sets if the node is visible.
         * @param v true if the node is visible, else false
         public void setVisible(boolean v) {
              this.visible = v;
    // *** TreeNodeTreeModel ***
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.event.*;
    import javax.swing.tree.*;
    * <code>TreeNodeTreeModel</code> is an <code>AbstractTreeModel</code>
    * implementation for <code>javax.swing.tree.TreeNode</code> objects.
    public class TreeNodeTreeModel extends AbstractTreeModel {
         * Creates a new <code>TreeNodeTreeModel</code> object.
         * @param root the root node
         public TreeNodeTreeModel(TreeNode root) {
              super();
              setRoot(root);
         * Returns the parent of the child node.
         * @param node the child node
         * @return the parent or null if root
         public Object getParent(Object node) {
              if(node != getRoot() && (node instanceof TreeNode)) {
                   return ((TreeNode)node).getParent();
              return null;
         * Returns the child of parent at index index in the parent's child array.
         * @param parent the parent node
         * @param index the index
         * @return the child or null if no children
         public Object getChild(Object parent, int index) {
              if(parent instanceof TreeNode) {
                   return ((TreeNode)parent).getChildAt(index);
              return null;
         * Returns the number of children of parent.
         * @param parent the parent node
         * @return the child count
         public int getChildCount(Object parent) {
              if(parent instanceof TreeNode) {
                   return ((TreeNode)parent).getChildCount();
              return 0;
         * Returns the index of child in parent.
         * @param parent the parent node
         * @param child the child node
         * @return the index of the child node in the parent
         public int getIndexOfChild(Object parent, Object child) {
              if(parent instanceof TreeNode && child instanceof TreeNode) {
                   return ((TreeNode)parent).getIndex((TreeNode)child);
              return -1;
         * Returns true if node is a leaf.
         * @param node the node
         * @return true if the node is a leaf
         public boolean isLeaf(Object node) {
              if(node instanceof TreeNode) {
                   return ((TreeNode)node).isLeaf();
              return true;
         * Main method for testing.
         * @param args the command-line arguments
         public static void main(String[] args) {
              JFrame f = new JFrame();
              f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              DefaultMutableTreeNode root = new DefaultMutableTreeNode("root");
              root.add(new DefaultMutableTreeNode("child_1"));
              DefaultMutableTreeNode c2 = new DefaultMutableTreeNode("child_2");
              c2.add(new DefaultMutableTreeNode("child_2_A"));
              c2.add(new DefaultMutableTreeNode("child_2_B"));
              root.add(c2);
              root.add(new DefaultMutableTreeNode("child_3"));
              root.add(new DefaultMutableTreeNode("child_4"));
              JTree tree = new JTree(new TreeNodeTreeModel(root));
              f.getContentPane().add(new JScrollPane(tree));
              f.pack();
              f.setSize(300, 500);
              f.show();
    // *** AbstractTreeModel ***
    import java.awt.*;
    import java.awt.event.*;
    import java.io.*;
    import java.net.*;
    import java.text.*;
    import java.util.*;
    import javax.swing.*;
    import javax.swing.event.*;
    import javax.swing.tree.*;
    public abstract class AbstractTreeModel implements TreeModel {
         * The list of tree model listeners.
         private Vector modelListeners = new Vector();
         * The root object of the tree.
         private Object root = null;
         * Basic no-op constructor.
         public AbstractTreeModel() {
         * Gets the root object of the tree.
         * @return the root object
         public Object getRoot() {
              return this.root;
         * Sets the root object of the tree.
         * @param r the root object
         protected void setRoot(Object r) {
              this.root = r;
         * Gets the path to the root node for the specified object.
         * @param node the root node
         * @return the path to the object or <CODE>null</CODE>
         public Object[] getPathToRoot(Object node) {
              return getPathToRoot(node, 0);
         * Gets the path to the root node for the specified object.
         * @param node the root node
         * @param i the current index
         * @return the path to the object or <CODE>null</CODE>
         private Object[] getPathToRoot(Object node, int i) {
              Object anode[];
              if(node == null) {
                   if(i == 0) {
                        return null;
                   anode = new Object[i];
              } else {
                   i++;
                   if(node == getRoot()) {
                        anode = new Object[i];
                   } else {
                        anode = getPathToRoot(getParent(node), i);
                   anode[anode.length - i] = node;
              return anode;
         * Gets the parent object of the specified object. This method is not
         * part of the <code>javax.swing.tree.TreeModel</code> interface, but is
         * required to support the <code>getPathToRoot(Object)</code> method,
         * which is widely used in this class. Therefore, it is important to
         * correctly implement this method.
         * @param obj the object
         * @parma the parent object or null if no parent or invalid object
         protected abstract Object getParent(Object obj);
         * Adds a listener for the <CODE>TreeModelEvent</CODE> posted after the
         * tree changes.
         * @param l the tree model listener
         public void addTreeModelListener(TreeModelListener l) {
              modelListeners.addElement(l);
         * Removes a listener previously added with addTreeModelListener().
         * @param l the tree model listener
         public void removeTreeModelListener(TreeModelListener l) {
              modelListeners.removeElement(l);
         * Forces the tree to reload. This is useful when many changes occur
         * under the root node in the tree structure.
         * <b>NOTE:</b> This will cause the tree to be collapsed. To maintain
         * the expanded nodes, see the <code>getExpandedPaths(JTree)</code>
         * and <code>expandPaths(JTree, ArrayList)</code> methods.
         * @see #getExpandedPaths(JTree)
         * @see #expandPaths(JTree, ArrayList)
         public void reload() {
              reload(getRoot());
         * Forces the tree to repaint. This is useful when many changes occur
         * under a specific node in the tree structure.
         * <b>NOTE:</b> This will cause the tree to be collapsed below the
         * updated node.
         * @param node the node that changed
         public void reload(Object node) {
              if(node != null) {
                   TreePath tp = new TreePath(getPathToRoot(node));
                   fireTreeStructureChanged(new TreeModelEvent(this, tp));
         * Messaged when the user has altered the value for the item identified
         * by <CODE>path</CODE> to <CODE>newValue</CODE>.
         * @param path the path to the changed object
         * @param newValue the new value
         public void valueForPathChanged(TreePath path, Object newValue) {
              nodeChanged(path.getLastPathComponent());
         * Notifies the tree that nodes were inserted. The index is looked up
         * automatically.
         * @param node the parent node
         * @param child the inserted child node
         public void nodeInserted(Object node, Object child) {
              nodeInserted(node, child, -1);
         * Notifies the tree that nodes were inserted.
         * @param node the parent node
         * @param child the inserted child node
         * @param index the index of the child
         public void nodeInserted(Object node, Object child, int index) {
              if(index < 0) {
                   index = getIndexOfChild(node, child);
              if(node != null && child != null && index >= 0) {
                   TreePath tp = new TreePath(getPathToRoot(node));
                   int[] ai = { index };
                   Object[] ac = { child };
                   fireTreeNodesInserted(new TreeModelEvent(this, tp, ai, ac));
         * Notifies the tree that nodes were removed. The index is required
         * since by this point, the object will no longer be in the tree.
         * @param node the parent node
         * @param child the removed child node
         * @param index the index of the child
         public void nodeRemoved(Object node, Object child, int index) {
              if(node != null && child != null && index >= 0) {
                   TreePath tp = new TreePath(getPathToRoot(node));
                   int[] ai = { index };
                   Object[] ac = { child };
                   fireTreeNodesRemoved(new TreeModelEvent(this, tp, ai, ac));
         * Notifies the tree that a node was changed.
         * @param node the changed node
         public void nodeChanged(Object node) {
              if(node != null) {
                   TreePath tp = new TreePath(getPathToRoot(node));
                   fireTreeNodesChanged(new TreeModelEvent(this, tp, null, null));
         * Fires "tree nodes changed" events to all listeners.
         * @param event the tree model event
         protected void fireTreeNodesChanged(TreeModelEvent event) {
              for(int i = 0; i < modelListeners.size(); i++) {
                   ((TreeModelListener)modelListeners.elementAt(i)).treeNodesChanged(event);
         * Fires "tree nodes inserted" events to all listeners.
         * @param event the tree model event
         protected void fireTreeNodesInserted(TreeModelEvent event) {
              for(int i = 0; i < modelListeners.size(); i++) {
                   ((TreeModelListener)modelListeners.elementAt(i)).treeNodesInserted(event);
         * Fires "tree nodes removed" events to all listeners.
         * @param event the tree model event
         protected void fireTreeNodesRemoved(TreeModelEvent event) {
              for(int i = 0; i < modelListeners.size(); i++) {
                   ((TreeModelListener)modelListeners.elementAt(i)).treeNodesRemoved(event);
         * Fires "tree structure changed" events to all listeners.
         * @param event the tree model event
         protected void fireTreeStructureChanged(TreeModelEvent event) {
              for(int i = 0; i < modelListeners.size(); i++) {
                   ((TreeModelListener)modelListeners.elementAt(i)).treeStructureChanged(event);
         * Records the list of currently expanded paths in the specified tree.
         * This method is meant to be called before calling the
         * <code>reload()</code> methods to allow the tree to store the paths.
         * @param tree the tree
         * @param pathlist the list of expanded paths
         public ArrayList getExpandedPaths(JTree tree) {
              ArrayList expandedPaths = new ArrayList();
              addExpandedPaths(tree, tree.getPathForRow(0), expandedPaths);
              return expandedPaths;
         * Adds the expanded descendants of the specifed path in the specified
         * tree to the internal expanded list.
         * @param tree the tree
         * @param path the path
         * @param pathlist the list of expanded paths
         private void addExpandedPaths(JTree tree, TreePath path, ArrayList pathlist) {
              Enumeration enum = tree.getExpandedDescendants(path);
              while(enum.hasMoreElements()) {
                   TreePath tp = (TreePath)enum.nextElement();
                   pathlist.add(tp);
                   addExpandedPaths(tree, tp, pathlist);
         * Re-expands the expanded paths in the specified tree. This method is
         * meant to be called before calling the <code>reload()</code> methods
         * to allow the tree to store the paths.
         * @param tree the tree
         * @param pathlist the list of expanded paths
         public void expandPaths(JTree tree, ArrayList pathlist) {
              for(int i = 0; i < pathlist.size(); i++) {
                   tree.expandPath((TreePath)pathlist.get(i));

    Hey
    I'm not trying to show anyone up here, but having just built a tree model for displaying an XML document in a tree, I thought this seemed like a neat exercise.
    I implemented this very differently from the @OP. I only have one class, HiddenNodeTreeModel. All the hidden node data is stored in the model itself in my class. The advantage of what I've created is it will work with any TreeModel. The disadvantage is that I think it's not going to be very scalable - the additional computing to get the number of child nodes and to adjust indexes is heavy. So if you need a scalable solution definitely don't use this.
    Anyway here you go
    HiddenNodeTreeModel.java
    ======================
    package tjacobs.ui.tree;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Iterator;
    import javax.swing.JFrame;
    import javax.swing.JMenu;
    import javax.swing.JMenuBar;
    import javax.swing.JMenuItem;
    import javax.swing.JTree;
    import javax.swing.event.TreeModelListener;
    import javax.swing.tree.DefaultMutableTreeNode;
    import javax.swing.tree.DefaultTreeModel;
    import javax.swing.tree.TreeModel;
    import javax.swing.tree.TreePath;
    import tjacobs.ui.WindowUtilities;
    public class HiddenNodeTreeModel implements TreeModel {
         TreeModel mModel;
         ArrayList<Object> mHidden = new ArrayList<Object>();
         public HiddenNodeTreeModel (TreeModel model) {
              mModel = model;
         public void addTreeModelListener(TreeModelListener arg0) {
              mModel.addTreeModelListener(arg0);
         private ArrayList<Integer> getHiddenChildren(Object parent) {
              ArrayList<Integer> spots = new ArrayList<Integer>();
              Iterator _i = mHidden.iterator();
              while (_i.hasNext()) {
                   Object hidden = _i.next();
                   int idx = mModel.getIndexOfChild(parent, hidden);
                   if (idx != -1) {
                        spots.add(idx);
              return spots;
         public Object getChild(Object arg0, int index) {
              ArrayList<Integer> spots = getHiddenChildren(arg0);
              Collections.sort(spots);
              Iterator<Integer> _i = spots.iterator();
              while (_i.hasNext()) {
                   int num = _i.next();
                   if (num <= index) {
                        index++;
              return mModel.getChild(arg0, index);
         public int getChildCount(Object arg0) {
              ArrayList list = getHiddenChildren(arg0);
              System.out.println("size = " + list.size());
              return mModel.getChildCount(arg0) - list.size();
         public int getIndexOfChild(Object arg0, Object arg1) {
              int index = mModel.getIndexOfChild(arg0, arg1);
              ArrayList<Integer> spots = getHiddenChildren(arg0);
              Collections.sort(spots);
              Iterator<Integer> _i = spots.iterator();
              int toSub = 0;
              while (_i.hasNext()) {
                   int num = _i.next();
                   if (num <= index) {
                        toSub++;
              return index - toSub;
         public Object getRoot() {
              // TODO Auto-generated method stub
              return mModel.getRoot();
         public boolean isLeaf(Object arg0) {
              // TODO Auto-generated method stub
              return mModel.isLeaf(arg0);
         public void removeTreeModelListener(TreeModelListener arg0) {
              mModel.removeTreeModelListener(arg0);
         public void valueForPathChanged(TreePath arg0, Object arg1) {
              mModel.valueForPathChanged(arg0, arg1);
         public void hideNode(Object node) {
              if (node instanceof TreePath) {
                   node = ((TreePath)node).getLastPathComponent();
              mHidden.add(node);
         public void showNode(Object node) {
              mHidden.remove(node);
         public void showAll() {
              mHidden.clear();
          * @param args
         public static void main(String[] args) {
              // TODO Auto-generated method stub
              DefaultMutableTreeNode A = new DefaultMutableTreeNode("A");
              DefaultMutableTreeNode B = new DefaultMutableTreeNode("B");
              DefaultMutableTreeNode C = new DefaultMutableTreeNode("C");
              DefaultMutableTreeNode D = new DefaultMutableTreeNode("D");
              DefaultMutableTreeNode E = new DefaultMutableTreeNode("E");
              DefaultMutableTreeNode F = new DefaultMutableTreeNode("F");
              A.add(B);
              B.add(C);
              B.add(D);
              B.add(E);
              E.add(F);
              DefaultTreeModel model = new DefaultTreeModel(A);
              final HiddenNodeTreeModel hmodel = new HiddenNodeTreeModel(model);
              final JTree tree = new JTree(hmodel);
              JFrame jf = new JFrame("HiddenNodeTreeModel Test");
              jf.add(tree);
              JMenuBar bar = new JMenuBar();
              jf.setJMenuBar(bar);
              JMenu menu = new JMenu("Options");
              bar.add(menu);
              final JMenuItem hide = new JMenuItem("Hide");
              final JMenuItem show = new JMenuItem("ShowAll");
              menu.add(hide);
              menu.add(show);
              ActionListener al = new ActionListener() {
                   public void actionPerformed(ActionEvent ae) {
                        if (ae.getSource() == hide) {
                             hmodel.hideNode(tree.getSelectionPath());
                             tree.updateUI();
                        else {
                             hmodel.showAll();
                             tree.updateUI();
              hide.addActionListener(al);
              show.addActionListener(al);
              jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              jf.setBounds(100,100,100,100);
              jf.setVisible(true);
    }

  • Creation of a Popup Menu for a Tree Node

    Hi Ppl,
      I need to create a Pop-up Menu for a tree node in WebDynpro Application, please give me a "How to .." sort of material or a link which would have same sort of information...
    Also, My requirement is to call the pop-up on the right click of mouse on the tree node, please let me know on which event handler I can call it ? Do I require a custom event handler for it ?
    Thanks in advance
    Anish

    Hi Anish,
    You simply add a Tree UI element, and then right-click the tree UI element and insert a TreeNode element.
    To the TreeNode element you can add a menu, and then to this menu you can add menu items. When the user right click the tree node, the menu item is displayed. If the user clicks the menu item, the action for the menuitem is run.
    Hope that helps.
    Daniel

  • How to cut, copy and paste a tree node in JTree?????

    Hi, Java GUI guru. Thank you for your help in advance.
    I am working on a File Explorer project with JTree. There are cut, copy and paste item menus in my menu bar. I need three EventAction methods or classes to implements the three tasks. I tried to use Clipboard to copy and paste tree node. But I can not copy any tree node from my tree.
    Are there any body has sample source code about cut, copy, and paste for tree? If possible, would you mind send me your sample source code to [email protected]
    I would appreciate you very very much for your help!!!!
    X.G.

    Hi, Paul Clapham:
    Thank you for your quick answer.
    I store the node in a DefaultMutableTreeNode variable, and assign it to another DefaultMutableTreeNode variable. I set up two classes (CopyNode and PasteNode). Here they are as follows:
    //CopyNode class
    import java.awt.*;
    import java.awt.event.*;
    import java.io.*;
    import java.util.*;
    import javax.swing.*;
    import javax.swing.tree.*;
    import javax.swing.event.*;
    public class CopyNode implements ActionListener{
    private TreeList jtree;
    String treeNodeName;
    TreePath currentSelection;
    DefaultMutableTreeNode currentNode;
    public CopyNode(TreeList t){
    jtree = t;
    public void actionPerformed(ActionEvent e){
    currentSelection = jtree.tree.getSelectionPath();
    if(currentSelection != null){
    currentNode = (DefaultMutableTreeNode)(currentSelection.getLastPathComponent());
    treeNodeName = currentNode.toString();
    //PasteNode class
    import java.awt.*;
    import java.awt.event.*;
    import java.io.*;
    import java.util.*;
    import javax.swing.*;
    import javax.swing.tree.*;
    import javax.swing.event.*;
    public class PasteNode extends DefaultMutableTreeNode{
    private TreeList jtree;
    CopyNode copyNode;
    public PasteNode(TreeList t){
    jtree = t;
    copyNode = new CopyNode(t);
    public DefaultMutableTreeNode addObject(Object child){
    DefaultMutableTreeNode parentNode = null;
    TreePath parentPath = jtree.tree.getSelectionPath();
    if(parentPath == null){
    parentNode = jtree.root;
    else{
    parentNode = (DefaultMutableTreeNode)parentPath.getLastPathComponent();
    return addObject(parentNode, child, true);
    public DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent, Object child, boolean shouldBeVisible){
    DefaultMutableTreeNode childNode = copyNode.currentNode;
    if(parent == null){
    parent = jtree.root;
    jtree.treemodel.insertNodeInto(childNode, parent, parent.getChildCount());
    if(shouldBeVisible){
    jtree.tree.scrollPathToVisible(new TreePath(childNode.getPath()));
    return childNode;
    I used these two classes objects in "actionPerformed(ActionEvent e)" methods in my tree:
    //invoke copyNode
    copyItem = new JMenuItem("Copy");
    copyItem.addActionListener(copyNode);
    //invoke pasteNode
    pasteItem = new JMenuItem("Paste");
    pasteItem.addActionListener(
    new ActionListener(){
    public void actionPerformed(ActionEvent e){
    pasteName.addObject(copyName.treeNodeName);
    When I run the drive code, making a copy some node from my tree list, I got bunch of error messages.
    Can you figour out what is wrong in my two classes? If you have sample code, would you mind mail me for reference.
    Thank you very much in advance.
    X.G.

  • Help with building a JTree using tree node and node renderers

    Hi,
    I am having a few problems with JTree's. basically I want to build JTree from a web spider. The webspide searches a website checking links and stores the current url that is being processed as a string in the variable msg. I wan to use this variable to build a JTree in a new class and then add it to my GUI. I have created a tree node class and a renderer node class, these classes are built fine. can someone point me in the direction for actually using these to build my tree in a seperate class and then displaying it in a GUI class?
    *nodeRenderer.java
    import javax.swing.*;
    import javax.swing.tree.*;
    import java.awt.*;
    import java.net.*;
    public class nodeRenderer extends DefaultTreeCellRenderer
                                       implements TreeCellRenderer
    public static Icon icon= null;
    public nodeRenderer() {
    icon = new ImageIcon(getClass().getResource("icon.gif"));
    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);
    treeNode node = (treeNode)(((DefaultMutableTreeNode)value).getUserObject());
    if(icon != null) // set a custom icon
    setOpenIcon(icon);
    setClosedIcon(icon);
    setLeafIcon(icon);
         return this;
    *treeNode.java
    *this is the class to represent a node
    import javax.swing.*;
    import javax.swing.tree.*;
    import java.util.*;
    import java.net.*;
    * Class used to hold information about a web site that has
    * been searched by the spider class
    public class treeNode
    *Url from the WebSpiderController Class
    *that is currently being processed
    public String msg;
    treeNode(String urlText)
         msg = urlText;
    String getUrlText()
         return msg;
    //gui.java
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.tree.*;
    import java.net.*;
    import java.io.*;
    import java.util.*;
    public class gui extends JFrame implements Runnable
         *declare variable, boolean
         *thread, a object and a center
         *pane
         protected URL urlInput;
         protected Thread bgThread;
         protected boolean run = false;
         protected WebSpider webSpider;
         public gui()
              *create the gui here
              setTitle("Testing Tool");
         setSize(600,600);
         //add Buttons to the tool bar
         start.setText("Start");
         start.setActionCommand("Start");
         toolBar.add(start);
         ButtonListener startListener = new ButtonListener();
              start.addActionListener(startListener);
              cancel.setText("Cancel");
         cancel.setActionCommand("Cancel");
         toolBar.add(cancel);
         ButtonListener cancelListener = new ButtonListener();
              cancel.addActionListener(cancelListener);
              close.setText("Close");
         close.setActionCommand("Close");
         toolBar.add(close);
         ButtonListener closeListener = new ButtonListener();
              close.addActionListener(closeListener);
              //creat a simple form
              urlLabel.setText("Enter URL:");
              urlLabel.setBounds(100,36,288,24);
              formTab.add(urlLabel);
              url.setBounds(170,36,288,24);
              formTab.add(url);
              current.setText("Currently Processing: ");
              current.setBounds(100,80,288,24);
              formTab.add(current);
         //add scroll bars to the error messages screen and website structure
         errorPane.setAutoscrolls(true);
         errorPane.setHorizontalScrollBarPolicy(javax.swing.
         ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
         errorPane.setVerticalScrollBarPolicy(javax.swing.
         ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
         errorPane.setOpaque(true);
         errorTab.add(errorPane);
         errorPane.setBounds(0,0,580,490);
         errorText.setEditable(false);
         errorPane.getViewport().add(errorText);
         errorText.setBounds(0,0,600,550);
         treePane.setAutoscrolls(true);
         treePane.setHorizontalScrollBarPolicy(javax.swing.
         ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
         treePane.setVerticalScrollBarPolicy(javax.swing.
         ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
         treePane.setOpaque(true);
         treeTab.add(treePane);
         treePane.setBounds(0,0,580,490);
         treeText.setEditable(false);
         treePane.getViewport().add(treeText);
         treeText.setBounds(0,0,600,550);
         //create the tabbed window           
    centerPane.setBorder(new javax.swing.border.EtchedBorder());
    formTab.setLayout(null);
    errorTab.setLayout(null);
    treeTab.setLayout(null);
    centerPane.addTab("Search Parameters", formTab);
    centerPane.addTab("Error Messages", errorTab);
    centerPane.addTab("Website Structure", treeTab);
              //add the tool bar and tabbed pane
              getContentPane().add(toolBar, java.awt.BorderLayout.NORTH);
    getContentPane().add(centerPane, java.awt.BorderLayout.CENTER);                    
              *create the tool bar pane, a center pane, add the buttons,
              *labels, tabs, a text field for user input here
              javax.swing.JPanel toolBar = new javax.swing.JPanel();
              javax.swing.JButton start = new javax.swing.JButton();
              javax.swing.JButton cancel = new javax.swing.JButton();
              javax.swing.JButton close = new javax.swing.JButton();      
              javax.swing.JTabbedPane centerPane = new javax.swing.JTabbedPane();
              javax.swing.JPanel formTab = new javax.swing.JPanel();
              javax.swing.JLabel urlLabel = new javax.swing.JLabel();
              javax.swing.JLabel current = new javax.swing.JLabel();
              javax.swing.JTextField url = new javax.swing.JTextField();
              javax.swing.JPanel errorTab = new javax.swing.JPanel();
              javax.swing.JTextArea errorText = new javax.swing.JTextArea();
              javax.swing.JScrollPane errorPane = new javax.swing.JScrollPane();
              javax.swing.JPanel treeTab = new javax.swing.JPanel();
              javax.swing.JTextArea treeText = new javax.swing.JTextArea();
              javax.swing.JScrollPane treePane = new javax.swing.JScrollPane();
              javax.swing.JTree searchTree = new javax.swing.JTree();
              *show the gui
              public static void main(String args[])
              (new gui()).setVisible(true);
         *listen for the button presses and set the
         *boolean flag depending on which button is pressed
         class ButtonListener implements ActionListener
              public void actionPerformed(ActionEvent event)
                   Object object = event.getSource();
                   if (object == start)
                        run = true;
                        startActionPerformed(event);
                   if (object == cancel)
                        run = false;
                        startActionPerformed(event);
                   if (object == close)
                        System.exit(0);
         *this method is called when the start or
         *cancel button is pressed.
         void startActionPerformed (ActionEvent event)
              if (run == true && bgThread == null)
                   bgThread = new Thread(this);
                   bgThread.start();
              if (run == false && bgThread != null)
                   webSpider.cancel();
         *this mehtod will start the background thred.
         *the background thread is required so that the
         *GUI is still displayed
         public void run()
              try
                   webSpider = new WebSpider(this);
                   webSpider.clear();
                   urlInput = new URL(url.getText());
                   webSpider.addURL(urlInput);
                   webSpider.run();
                   bgThread=null;
              catch (MalformedURLException e)
                   addressError addErr = new addressError();
                   addErr.addMsg = "URL ERROR - PLEASE CHECK";
                   SwingUtilities.invokeLater(addErr);
              *this method is called by the web spider
              *once a url is found. Validation of navigation
              *happens here.
              public boolean urlFound(URL urlInput,URL url)
                   CurrentlyProcessing pro = new CurrentlyProcessing();
              pro.msg = url.toString();
              SwingUtilities.invokeLater(pro);
              if (!testLink(url))
                        navigationError navErr = new navigationError();
                        navErr.navMsg = "Broken Link "+url+" caused on "+urlInput+"\n";
                        return false;
              if (!url.getHost().equalsIgnoreCase(urlInput.getHost()))
                   return false;
              else
                   return true;
              *this method is called internally to check
         *that a link works
              protected boolean testLink(URL url)
              try
                   URLConnection connection = url.openConnection();
                   connection.connect();
                   return true;
              catch (IOException e)
                   return false;
         *this method is called when an error is
         *found.
              public void URLError(URL url)
              *this method is called when an email
              *address is found
              public void emailFound(String email)
              /*this method will update any errors found inc
              *address errors and broken links
              class addressError implements Runnable
                   public String addMsg;
                   public void run()
                        errorText.append(addMsg);
                        current.setText("Currently Processing: "+ addMsg);
              class navigationError implements Runnable
                   public String navMsg;
                   public void run()
                        errorText.append(navMsg);
              *this method will update the currently
              *processing field on the GUI
              class CurrentlyProcessing implements Runnable
              public String msg;
              public void run()
                   current.setText("Currently Processing: " + msg );
    //webspider.java
    import java.util.*;
    import java.net.*;
    import java.io.*;
    import javax.swing.text.*;
    import javax.swing.text.html.*;
    import javax.swing.tree.*;
    import javax.swing.*;
    *this class implements the spider.
    public class WebSpider extends HTMLEditorKit
         *make a collection of the URL's
         protected Collection urlErrors = new ArrayList(3);
         protected Collection urlsWaiting = new ArrayList(3);
         protected Collection urlsProcessed = new ArrayList(3);
         //report URL's to this class
         protected gui report;
         *this flag will indicate whether the process
         *is to be cancelled
         protected boolean cancel = false;
         *The constructor
         *report the urls to the wui class
         public WebSpider(gui report)
         this.report = report;
         *get the urls from the above declared
         *collections
         public Collection getUrlErrors()
         return urlErrors;
         public Collection getUrlsWaiting()
         return urlsWaiting;
         public Collection getUrlsProcessed()
         return urlsProcessed;
         * Clear all of the collections.
         public void clear()
         getUrlErrors().clear();
         getUrlsWaiting().clear();
         getUrlsProcessed().clear();
         *Set a flag that will cause the begin
         *method to return before it is done.
         public void cancel()
         cancel = true;
         *add the entered url for porcessing
         public void addURL(URL url)
         if (getUrlsWaiting().contains(url))
              return;
         if (getUrlErrors().contains(url))
              return;
         if (getUrlsProcessed().contains(url))
              return;
         /*WRITE TO LOG FILE*/
         log("Adding to workload: " + url );
         getUrlsWaiting().add(url);
         *process a url
         public void processURL(URL url)
         try
              /*WRITE TO LOGFILE*/
              log("Processing: " + url );
              // get the URL's contents
              URLConnection connection = url.openConnection();
              if ((connection.getContentType()!=null) &&
         !connection.getContentType().toLowerCase().startsWith("text/"))
              getUrlsWaiting().remove(url);
              getUrlsProcessed().add(url);
              log("Not processing because content type is: " +
         connection.getContentType() );
                   return;
         // read the URL
         InputStream is = connection.getInputStream();
         Reader r = new InputStreamReader(is);
         // parse the URL
         HTMLEditorKit.Parser parse = new HTMLParse().getParser();
         parse.parse(r,new Parser(url),true);
    catch (IOException e)
         getUrlsWaiting().remove(url);
         getUrlErrors().add(url);
         log("Error: " + url );
         report.URLError(url);
         return;
    // mark URL as complete
    getUrlsWaiting().remove(url);
    getUrlsProcessed().add(url);
    log("Complete: " + url );
    *start the spider
    public void run()
    cancel = false;
    while (!getUrlsWaiting().isEmpty() && !cancel)
         Object list[] = getUrlsWaiting().toArray();
         for (int i=0;(i<list.length)&&!cancel;i++)
         processURL((URL)list);
    * A HTML parser callback used by this class to detect links
    protected class Parser extends HTMLEditorKit.ParserCallback
    protected URL urlInput;
    public Parser(URL urlInput)
    this.urlInput = urlInput;
    public void handleSimpleTag(HTML.Tag t,MutableAttributeSet a,int pos)
    String href = (String)a.getAttribute(HTML.Attribute.HREF);
    if((href==null) && (t==HTML.Tag.FRAME))
    href = (String)a.getAttribute(HTML.Attribute.SRC);
    if (href==null)
    return;
    int i = href.indexOf('#');
    if (i!=-1)
    href = href.substring(0,i);
    if (href.toLowerCase().startsWith("mailto:"))
    report.emailFound(href);
    return;
    handleLink(urlInput,href);
    public void handleStartTag(HTML.Tag t,MutableAttributeSet a,int pos)
    handleSimpleTag(t,a,pos); // handle the same way
    protected void handleLink(URL urlInput,String str)
    try
         URL url = new URL(urlInput,str);
    if (report.urlFound(urlInput,url))
    addURL(url);
    catch (MalformedURLException e)
    log("Found malformed URL: " + str);
    *log the information of the spider
    public void log(String entry)
    System.out.println( (new Date()) + ":" + entry );
    I have a seperate class for parseing the HTML. Any help would be greatly appreciated
    mrv

    Hi Sorry to be a pain again,
    I have re worked the gui class so it looks like this now:
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.tree.*;
    import javax.swing.event.*;
    import java.net.*;
    import java.io.*;
    import java.util.*;
    public class gui extends JFrame implements Runnable
         *declare variable, boolean
         *thread, a object and a center
         *pane
         protected URL urlInput;
         protected Thread bgThread;
         protected boolean run = false;
         protected WebSpider webSpider;
         public String msgInfo;
         public String brokenUrl;
         public String goodUrl;
         public String deadUrl;
         protected DefaultMutableTreeNode rootNode;
    protected DefaultTreeModel treeModel;
         public gui()
              *create the gui here
              setTitle("Testing Tool");
         setSize(600,600);
         //add Buttons to the tool bar
         start.setText("Start");
         start.setActionCommand("Start");
         toolBar.add(start);
         ButtonListener startListener = new ButtonListener();
              start.addActionListener(startListener);
              cancel.setText("Cancel");
         cancel.setActionCommand("Cancel");
         toolBar.add(cancel);
         ButtonListener cancelListener = new ButtonListener();
              cancel.addActionListener(cancelListener);
              close.setText("Close");
         close.setActionCommand("Close");
         toolBar.add(close);
         ButtonListener closeListener = new ButtonListener();
              close.addActionListener(closeListener);
              //creat a simple form
              urlLabel.setText("Enter URL:");
              urlLabel.setBounds(100,36,288,24);
              formTab.add(urlLabel);
              url.setBounds(170,36,288,24);
              formTab.add(url);
              current.setText("Currently Processing: ");
              current.setBounds(100,80,288,24);
              formTab.add(current);
         //add scroll bars to the error messages screen and website structure
         errorPane.setAutoscrolls(true);
         errorPane.setHorizontalScrollBarPolicy(javax.swing.
         ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
         errorPane.setVerticalScrollBarPolicy(javax.swing.
         ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
         errorPane.setOpaque(true);
         errorTab.add(errorPane);
         errorPane.setBounds(0,0,580,490);
         errorText.setEditable(false);
         errorPane.getViewport().add(errorText);
         errorText.setBounds(0,0,600,550);
         treePane.setAutoscrolls(true);
         treePane.setHorizontalScrollBarPolicy(javax.swing.
         ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
         treePane.setVerticalScrollBarPolicy(javax.swing.
         ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
         treePane.setOpaque(true);
         treeTab.add(treePane);
         treePane.setBounds(0,0,580,490);
         treeText.setEditable(false);
         treePane.getViewport().add(treeText);
         treeText.setBounds(0,0,600,550);
         //JTree
         // NEW CODE
         rootNode = new DefaultMutableTreeNode("Root Node");
         treeModel = new DefaultTreeModel(rootNode);
         treeModel.addTreeModelListener(new MyTreeModelListener());
         tree = new JTree(treeModel);
         tree.setEditable(true);
         tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
    tree.setShowsRootHandles(true);
         treeText.add(tree);
         //create the tabbed window           
    centerPane.setBorder(new javax.swing.border.EtchedBorder());
    formTab.setLayout(null);
    errorTab.setLayout(null);
    treeTab.setLayout(null);
    centerPane.addTab("Search Parameters", formTab);
    centerPane.addTab("Error Messages", errorTab);
    centerPane.addTab("Website Structure", treeTab);
              //add the tool bar and tabbed pane
              getContentPane().add(toolBar, java.awt.BorderLayout.NORTH);
    getContentPane().add(centerPane, java.awt.BorderLayout.CENTER);     
              *create the tool bar pane, a center pane, add the buttons,
              *labels, tabs, a text field for user input here
              javax.swing.JPanel toolBar = new javax.swing.JPanel();
              javax.swing.JButton start = new javax.swing.JButton();
              javax.swing.JButton cancel = new javax.swing.JButton();
              javax.swing.JButton close = new javax.swing.JButton();      
              javax.swing.JTabbedPane centerPane = new javax.swing.JTabbedPane();
              javax.swing.JPanel formTab = new javax.swing.JPanel();
              javax.swing.JLabel urlLabel = new javax.swing.JLabel();
              javax.swing.JLabel current = new javax.swing.JLabel();
              javax.swing.JTextField url = new javax.swing.JTextField();
              javax.swing.JPanel errorTab = new javax.swing.JPanel();
              javax.swing.JTextArea errorText = new javax.swing.JTextArea();
              javax.swing.JScrollPane errorPane = new javax.swing.JScrollPane();
              javax.swing.JPanel treeTab = new javax.swing.JPanel();
              javax.swing.JTextArea treeText = new javax.swing.JTextArea();
              javax.swing.JScrollPane treePane = new javax.swing.JScrollPane();
              javax.swing.JTree tree = new javax.swing.JTree();
              *show the gui
              public static void main(String args[])
              (new gui()).setVisible(true);
         *listen for the button presses and set the
         *boolean flag depending on which button is pressed
         class ButtonListener implements ActionListener
              public void actionPerformed(ActionEvent event)
                   Object object = event.getSource();
                   if (object == start)
                        run = true;
                        startActionPerformed(event);
                   if (object == cancel)
                        run = false;
                        startActionPerformed(event);
                   if (object == close)
                        System.exit(0);
         *this method is called when the start or
         *cancel button is pressed.
         void startActionPerformed (ActionEvent event)
              if (run == true && bgThread == null)
                   bgThread = new Thread(this);
                   bgThread.start();
                   //new line of code
                   treeText.addObject(msgInfo);
              if (run == false && bgThread != null)
                   webSpider.cancel();
         *this mehtod will start the background thred.
         *the background thread is required so that the
         *GUI is still displayed
         public void run()
              try
                   webSpider = new WebSpider(this);
                   webSpider.clear();
                   urlInput = new URL(url.getText());
                   webSpider.addURL(urlInput);
                   webSpider.run();
                   bgThread = null;
              catch (MalformedURLException e)
                   addressError addErr = new addressError();
                   addErr.addMsg = "URL ERROR - PLEASE CHECK";
                   SwingUtilities.invokeLater(addErr);
              *this method is called by the web spider
              *once a url is found. Validation of navigation
              *happens here.
              public boolean urlFound(URL urlInput,URL url)
                   CurrentlyProcessing pro = new CurrentlyProcessing();
              pro.msg = url.toString();
              SwingUtilities.invokeLater(pro);
              if (!testLink(url))
                        navigationError navErr = new navigationError();
                        navErr.navMsg = "Broken Link "+url+" caused on "+urlInput+"\n";
                        brokenUrl = url.toString();
                        return false;
              if (!url.getHost().equalsIgnoreCase(urlInput.getHost()))
                   return false;
              else
                   return true;
              *this method is returned if there is no link
              *on a web page, e.g. there us a dead end
              public void urlNotFound(URL urlInput)
                        deadEnd dEnd = new deadEnd();
                        dEnd.dEMsg = "No links on "+urlInput+"\n";
                        deadUrl = urlInput.toString();               
              *this method is called internally to check
         *that a link works
              protected boolean testLink(URL url)
              try
                   URLConnection connection = url.openConnection();
                   connection.connect();
                   goodUrl = url.toString();
                   return true;
              catch (IOException e)
                   return false;
         *this method is called when an error is
         *found.
              public void urlError(URL url)
              *this method is called when an email
              *address is found
              public void emailFound(String email)
              /*this method will update any errors found inc
              *address errors and broken links
              class addressError implements Runnable
                   public String addMsg;
                   public void run()
                        current.setText("Currently Processing: "+ addMsg);
                        errorText.append(addMsg);
              class navigationError implements Runnable
                   public String navMsg;
                   public void run()
                        errorText.append(navMsg);
              class deadEnd implements Runnable
                   public String dEMsg;
                   public void run()
                        errorText.append(dEMsg);
              *this method will update the currently
              *processing field on the GUI
              public class CurrentlyProcessing implements Runnable
                   public String msg;
              //new line
              public String msgInfo = msg;
              public void run()
                   current.setText("Currently Processing: " + msg );
         * NEW CODE
         * NEED THIS CODE SOMEWHERE
         * treeText.addObject(msgInfo);
         public DefaultMutableTreeNode addObject(Object child)
         DefaultMutableTreeNode parentNode = null;
         TreePath parentPath = tree.getSelectionPath();
         if (parentPath == null)
         parentNode = rootNode;
         else
         parentNode = (DefaultMutableTreeNode)
    (parentPath.getLastPathComponent());
         return addObject(parentNode, child, true);
         public DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent,
    Object child)
         return addObject(parent, child, false);
         public DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent,
         Object child,boolean shouldBeVisible)
         DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(child);
         if (parent == null)
         parent = rootNode;
         treeModel.insertNodeInto(childNode, parent, parent.getChildCount());
         if (shouldBeVisible)
         tree.scrollPathToVisible(new TreePath(childNode.getPath()));
              return childNode;
         public class MyTreeModelListener implements TreeModelListener
              public void treeNodesChanged (TreeModelEvent e)
                   DefaultMutableTreeNode node;
                   node = (DefaultMutableTreeNode)
                   (e.getTreePath().getLastPathComponent());
                   try
                        int index = e.getChildIndices()[0];
                        node = (DefaultMutableTreeNode)
                        (node.getChildAt(index));
                   catch (NullPointerException exc)
              public void treeNodesInserted(TreeModelEvent e)
              public void treeStructureChanged(TreeModelEvent e)
              public void treeNodesRemoved(TreeModelEvent e)
    I beleive that this line of code is required:
    treeText.addObject(msgInfo);
    I have placed it where the action events start the spider, but i keep getting this error:
    cannot resolve symbol
    symbol : method addObject (java.lang.String)
    location: class javax.swing.JTextArea
    treeText.addObject(msgInfo);
    Also the jtree is not showing the window that I want it to and I am not too sure why. could you have a look to see why? i think it needs a fresh pair of eyes.
    Many thanks
    MrV

Maybe you are looking for

  • Line Item Display Variant MIRO-column position needs to be changed..

    Hi, What is the possible way of setting the column position in line item display variant in MIRO screen. I need to change the positions of couple of columns so need to have  one layout as per my requirement. Does this involve only confiuration or it

  • Problem in Markup with text tokens 1

    Hi I am using the text for searching the documents of type html in my web site. The markup is working fine, when called with only single text token ie, "java". But it fails when called with more than one token, say "java vb", as this java and vb are

  • New ipad and can't get magazine

    Purchased a new ipad air. And now I can't download my magazine

  • CC&B functional question

    Hi, is it possible to apply or maintain a credit to account instead of service agreement ? For Example, Requirement is to give $50 credit to an Account X. This credit should be utilized by all the service agreements in that account as per payment dis

  • MacBook Pro OS X 10.5.8 desktop background freezing, icons inaccessible

    I have a late 2008 Unibody MacBook Pro. For the past few months, the background has been freezing, but recently it has been much more frequently. All applications seem to work fine, even the dock is accessible, but any thing that I have on the deskto