Deleting a RichTree component tree node
Hi,
I would like to delete a node in a tree and have that reflected in my tree model. Can anyone help with some sample code on how to do this? I'm using the RichTree component in JDev 11g.
Thanks
Colin
Colin,
Here are two good blog entries that demonstrates how-to programmatically manipulate the tree component and its underlying CollectionModel. In 11 the APIs on the CollectionModel remain unchanged other than being repackaged into an Apache Trinidad package. Neither entry shows you how to delete a node but this is as simple as removing an item from the CollectionModel and refreshing the tree. See if that helps.
http://technology.amis.nl/blog/?p=1313
http://thepeninsulasedge.com/blog/2006/10/10/adf-faces-working-with-the-aftree/
--Ric
Similar Messages
-
Selecting a RichTree component tree node
Hi,
How do I get the selected tree node in a RichTree component?. I would like to select the node with the mouse and possibly use the popup menu to initiate an action (e.g. delete). How do I add an item to the popup menu to do this? I'm using the RichTree component in JDev 11g. Any sample code would be helpful.
Thanks
ColinColin,
To perform some operation on node selection within af:tree component you simply need to create a selectionlistener and decorate the tree component with the listener you implemented. For the context-menu you describe the af:tree has an attribute named contextMenuId. Set the value of this attribute to equal the id of an af:popup that contains an af:menu that represents the menu that you want displayed on a right-click. Below is a link to the tag doc for the af:tree component
http://www.oracle.com/technology/products/adf/adffaces/11/doc/multiproject/adf-richclient-api/tagdoc/af_tree.html
--Ric -
JSF tree view GUI component and tree node actions
Hi,
I am new in using JSF and have a problem with my simple test application.
The application contains a tree view control with one static tree node and a separate text area. Clicking on the tree node shall fill the text area with the string 'hello'. Seems to be very simple, but it doesn't work.
What did I do?
First of all I use the Sun Java Studio Creator 2.
By double clicking on the tree node in the design window of the IDE a method called treeNode1_action() was created. I also added the String text to the session bean. treeNode1_Action() does not more than setting text='hello' ( getSessionBean().setText('hello'); ).
The jsp file contains the line
<ui:textArea binding="#{Page1.textArea}" id="textArea" style="height: 192px; left: 360px; top: 48px; position: absolute; width: 456px" text="#{SessionBean1.text}"/>, so the text of the text area is bound to the session property 'text'.
Running the application and clicking on the tree node does nothing except reloading the page (no 'hello' inside the text area).
Using the debugger showed me that the bean property text is set correctly to 'hello', also after reloading the page.
What did I do wrong?
What do I have to do to display 'hello' in the text area?
I would be glad for some good advice to solve my problem and looking forward for an answer.
Regards from germany
Matthiaswant to remove the green patch from the jsf tree componentas u said ,, it is COMPONENET so this is a pre-made creator component that u cant chnage its attributes ,,
instead u can extract Theam.jar file and change the icons ,, u i didnt do it before ,, but u may be find what u want there,
hope this will help
good luck
Mohammed -
Select tree node in tree component
hi,
i am developing a web site which has a site map as a tree component, the sitemap is a inserted in a page fragment, users could click tree nodes to go to corresponding pages. also on other pages, i have next and previous buttons which allow users to navigate through pages. the question is how can i update the tree component when users navigate using the next and previous buttons so that the correct tree node is highlighted?
i tried to use the selected property for the tree component, but it does not do anything.
thanks,
leeHi,
Duplicate thread of
http://swforum.sun.com/jive/thread.jspa?threadID=64518
MJ -
I want to delete all tree node at a time
hi all
i built my tree manualy using ftree.add_tree_node (not by record group and populate the RG) and i want to delete all tree nodes at a time in one statment
please urgenthi
try something like this.
DECLARE
htree ITEM;
num_selected NUMBER;
BEGin
-- Find the tree itself.
htree := Find_Item('tree_block.htree3');
-- Find the number of nodes marked as selected.
num_selected := Ftree.Get_tree_Property(htree, Ftree.SELECTION_COUNT);
-- Loop through nodes and delete them. Since nodes are internally
-- re-numbered when one is deleted, be sure to loop in reverse
-- order from last to first.
FOR j in num_selected..1 LOOP
Ftree.delete_tree_node(htree, Ftree.Get_tree_Selection(htree, j));
END LOOP;
END;If its Correct/helpful please mark it thanks.
Sarah -
Add/Edit/Delete Tree Nodes using CL_GUI_ALV_TREE
Hi All,
I am looking for an example of program with CL_GUI_ALV_TREE that have a functionality of add a tree node, edit a tree node, and delete a tree node.
I have already looked the BCALV_TREE* demo program but could not able to find a program to add/edit/delete node tree elements.
Any info on this.
Thanks
aRsHello aRs
Here is a sample report showing how to delete nodes in an ALV tree. The report was copied from BCALV_TREE_01. Search for added code:
*$ADDED: begin
*$ADDED: end[/code]
When you display the tree expand the first folder completely. When entering 'DELETE' into the command field directly the first flight date node will be deleted.
REPORT ZUS_SDN_BCALV_TREE_01_DELNODE.
based on: REPORT bcalv_tree_01.
Purpose:
~~~~~~~~
This report shows the essential steps to build up a hierarchy
using an ALV Tree Control (class CL_GUI_ALV_TREE).
Note that it is not possible to build up this hierarchy
using a simple ALV Tree Control (class CL_GUI_ALV_TREE_SIMPLE).
To check program behavior
~~~~~~~~~~~~~~~~~~~~~~~~~
Start this report. The hierarchy tree consists of nodes for each
month on top level (this level can not be build by a simple ALV Tree
because there is no field for months in our output table SFLIGHT.
Thus, you can not define this hierarchy by sorting).
Nor initial calculations neither a special layout has been applied
(the lines on the right do not show anything).
Note also that this example does not build up and change the
fieldcatalog of the output table. For this reason, all fields
of the output table are shown in the columns although the fields
CARRID and FLDATE are already placed in the tree on the left.
(Of course, this is not a good style. See BCALV_TREE_02 on how to
hide columns).
Essential steps (Search for '§')
~~~~~~~~~~~~~~~
1.Usual steps when using control technology.
1a. Define reference variables.
1b. Create ALV Tree Control and corresponding container.
2.Create Hierarchy-header
3.Create empty Tree Control
4.Create hierarchy (nodes and leaves)
4a. Select data
4b. Sort output table according to your conceived hierarchy
4c. Add data to tree
5.Send data to frontend.
6.Call dispatch to process toolbar functions
*$ADDED: begin
DATA:
gd_del_nkey TYPE lvc_nkey.
*$ADDED: end
§1a. Define reference variables
DATA: g_alv_tree TYPE REF TO cl_gui_alv_tree,
g_custom_container TYPE REF TO cl_gui_custom_container.
DATA: gt_sflight TYPE sflight OCCURS 0, "Output-Table
ok_code LIKE sy-ucomm,
save_ok LIKE sy-ucomm, "OK-Code
g_max TYPE i VALUE 255.
END-OF-SELECTION.
CALL SCREEN 100.
*& Module PBO OUTPUT
process before output
MODULE pbo OUTPUT.
SET PF-STATUS 'MAIN100'.
SET TITLEBAR 'MAINTITLE'.
IF g_alv_tree IS INITIAL.
PERFORM init_tree.
CALL METHOD cl_gui_cfw=>flush
EXCEPTIONS
cntl_system_error = 1
cntl_error = 2.
IF sy-subrc NE 0.
CALL FUNCTION 'POPUP_TO_INFORM'
EXPORTING
titel = 'Automation Queue failure'(801)
txt1 = 'Internal error:'(802)
txt2 = 'A method in the automation queue'(803)
txt3 = 'caused a failure.'(804).
ENDIF.
ENDIF.
ENDMODULE. " PBO OUTPUT
*& Module PAI INPUT
process after input
MODULE pai INPUT.
save_ok = ok_code.
CLEAR ok_code.
CASE save_ok.
WHEN 'EXIT' OR 'BACK' OR 'CANC'.
PERFORM exit_program.
*$ADDED: begin
WHEN 'DELETE'.
CALL METHOD g_alv_tree->delete_subtree
EXPORTING
i_node_key = gd_del_nkey
I_UPDATE_PARENTS_EXPANDER = SPACE
i_update_parents_folder = 'X'
EXCEPTIONS
node_key_not_in_model = 1
OTHERS = 2.
IF sy-subrc <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
CALL METHOD g_alv_tree->frontend_update.
*$ADDED: end
WHEN OTHERS.
§6. Call dispatch to process toolbar functions
CALL METHOD cl_gui_cfw=>dispatch.
ENDCASE.
CALL METHOD cl_gui_cfw=>flush.
ENDMODULE. " PAI INPUT
*& Form init_tree
text
--> p1 text
<-- p2 text
FORM init_tree.
§1b. Create ALV Tree Control and corresponding Container.
create container for alv-tree
DATA: l_tree_container_name(30) TYPE c.
l_tree_container_name = 'CCONTAINER1'.
CREATE OBJECT g_custom_container
EXPORTING
container_name = l_tree_container_name
EXCEPTIONS
cntl_error = 1
cntl_system_error = 2
create_error = 3
lifetime_error = 4
lifetime_dynpro_dynpro_link = 5.
IF sy-subrc <> 0.
MESSAGE x208(00) WITH 'ERROR'(100).
ENDIF.
create tree control
CREATE OBJECT g_alv_tree
EXPORTING
parent = g_custom_container
node_selection_mode = cl_gui_column_tree=>node_sel_mode_single
item_selection = 'X'
no_html_header = 'X'
no_toolbar = ''
EXCEPTIONS
cntl_error = 1
cntl_system_error = 2
create_error = 3
lifetime_error = 4
illegal_node_selection_mode = 5
failed = 6
illegal_column_name = 7.
IF sy-subrc <> 0.
MESSAGE x208(00) WITH 'ERROR'. "#EC NOTEXT
ENDIF.
§2. Create Hierarchy-header
The simple ALV Tree uses the text of the fields which were used
for sorting to define this header. When you use
the 'normal' ALV Tree the hierarchy is build up freely
by the programmer this is not possible, so he has to define it
himself.
DATA l_hierarchy_header TYPE treev_hhdr.
PERFORM build_hierarchy_header CHANGING l_hierarchy_header.
§3. Create empty Tree Control
IMPORTANT: Table 'gt_sflight' must be empty. Do not change this table
(even after this method call). You can change data of your table
by calling methods of CL_GUI_ALV_TREE.
Furthermore, the output table 'gt_outtab' must be global and can
only be used for one ALV Tree Control.
CALL METHOD g_alv_tree->set_table_for_first_display
EXPORTING
i_structure_name = 'SFLIGHT'
is_hierarchy_header = l_hierarchy_header
CHANGING
it_outtab = gt_sflight. "table must be empty !
§4. Create hierarchy (nodes and leaves)
PERFORM create_hierarchy.
§5. Send data to frontend.
CALL METHOD g_alv_tree->frontend_update.
wait for automatic flush at end of pbo
ENDFORM. " init_tree
*& Form build_hierarchy_header
build hierarchy-header-information
-->P_L_HIERARCHY_HEADER strucxture for hierarchy-header
FORM build_hierarchy_header CHANGING
p_hierarchy_header TYPE treev_hhdr.
p_hierarchy_header-heading = 'Month/Carrier/Date'(300).
p_hierarchy_header-tooltip = 'Flights in a month'(400).
p_hierarchy_header-width = 30.
p_hierarchy_header-width_pix = ' '.
ENDFORM. " build_hierarchy_header
*& Form exit_program
free object and leave program
FORM exit_program.
CALL METHOD g_custom_container->free.
LEAVE PROGRAM.
ENDFORM. " exit_program
*& Form create_hierarchy
text
--> p1 text
<-- p2 text
FORM create_hierarchy.
DATA: ls_sflight TYPE sflight,
lt_sflight TYPE sflight OCCURS 0,
l_yyyymm(6) TYPE c, "year and month of sflight-fldate
l_yyyymm_last(6) TYPE c,
l_carrid LIKE sflight-carrid,
l_carrid_last LIKE sflight-carrid.
DATA: l_month_key TYPE lvc_nkey,
l_carrid_key TYPE lvc_nkey,
l_last_key TYPE lvc_nkey.
§4a. Select data
SELECT * FROM sflight INTO TABLE lt_sflight UP TO g_max ROWS.
§4b. Sort output table according to your conceived hierarchy
We sort in this order:
year and month (top level nodes, yyyymm of DATS)
carrier id (next level)
day of month (leaves, dd of DATS)
SORT lt_sflight BY fldate0(6) carrid fldate6(2).
Note: The top level nodes do not correspond to a field of the
output table. Instead we use data of the table to invent another
hierarchy level above the levels that can be build by sorting.
§4c. Add data to tree
LOOP AT lt_sflight INTO ls_sflight.
Prerequesite: The table is sorted.
You add a node everytime the values of a sorted field changes.
Finally, the complete line is added as a leaf below the last
node.
l_yyyymm = ls_sflight-fldate+0(6).
l_carrid = ls_sflight-carrid.
Top level nodes:
IF l_yyyymm <> l_yyyymm_last. "on change of l_yyyymm
l_yyyymm_last = l_yyyymm.
*Providing no key means that the node is added on top level:
PERFORM add_month USING l_yyyymm
CHANGING l_month_key.
The month changed, thus, there is no predecessor carrier
CLEAR l_carrid_last.
ENDIF.
Carrier nodes:
(always inserted as child of the last month
which is identified by 'l_month_key')
IF l_carrid <> l_carrid_last. "on change of l_carrid
l_carrid_last = l_carrid.
PERFORM add_carrid_line USING ls_sflight
l_month_key
CHANGING l_carrid_key.
ENDIF.
Leaf:
(always inserted as child of the last carrier
which is identified by 'l_carrid_key')
PERFORM add_complete_line USING ls_sflight
l_carrid_key
CHANGING l_last_key.
ENDLOOP.
ENDFORM. " create_hierarchy
*& Form add_month
FORM add_month USING p_yyyymm TYPE c
p_relat_key TYPE lvc_nkey
CHANGING p_node_key TYPE lvc_nkey.
DATA: l_node_text TYPE lvc_value,
ls_sflight TYPE sflight,
l_month(15) TYPE c. "output string for month
get month name for node text
PERFORM get_month USING p_yyyymm
CHANGING l_month.
l_node_text = l_month.
add node:
ALV Tree firstly inserts this node as a leaf if you do not provide
IS_NODE_LAYOUT with field ISFOLDER set. In form 'add_carrid_line'
the leaf gets a child and thus ALV converts it to a folder
automatically.
CALL METHOD g_alv_tree->add_node
EXPORTING
i_relat_node_key = p_relat_key
i_relationship = cl_gui_column_tree=>relat_last_child
i_node_text = l_node_text
is_outtab_line = ls_sflight
IMPORTING
e_new_node_key = p_node_key.
ENDFORM. " add_month
FORM add_carrid_line USING ps_sflight TYPE sflight
p_relat_key TYPE lvc_nkey
CHANGING p_node_key TYPE lvc_nkey.
DATA: l_node_text TYPE lvc_value,
ls_sflight TYPE sflight.
add node
ALV Tree firstly inserts this node as a leaf if you do not provide
IS_NODE_LAYOUT with field ISFOLDER set. In form 'add_carrid_line'
the leaf gets a child and thus ALV converts it to a folder
automatically.
l_node_text = ps_sflight-carrid.
CALL METHOD g_alv_tree->add_node
EXPORTING
i_relat_node_key = p_relat_key
i_relationship = cl_gui_column_tree=>relat_last_child
i_node_text = l_node_text
is_outtab_line = ls_sflight
IMPORTING
e_new_node_key = p_node_key.
ENDFORM. " add_carrid_line
*& Form add_complete_line
FORM add_complete_line USING ps_sflight TYPE sflight
p_relat_key TYPE lvc_nkey
CHANGING p_node_key TYPE lvc_nkey.
DATA: l_node_text TYPE lvc_value.
WRITE ps_sflight-fldate TO l_node_text MM/DD/YYYY.
add leaf:
ALV Tree firstly inserts this node as a leaf if you do not provide
IS_NODE_LAYOUT with field ISFOLDER set.
Since these nodes will never get children they stay leaves
(as intended).
CALL METHOD g_alv_tree->add_node
EXPORTING
i_relat_node_key = p_relat_key
i_relationship = cl_gui_column_tree=>relat_last_child
is_outtab_line = ps_sflight
i_node_text = l_node_text
IMPORTING
e_new_node_key = p_node_key.
*$ADDED: begin
IF ( ps_sflight-fldate = '20040522' ). " first flight date
IF ( gd_del_nkey IS INITIAL ). " collect only first date
gd_del_nkey = p_node_key.
ENDIF.
ENDIF.
*$ADDED: end
ENDFORM. " add_complete_line
*& Form GET_MONTH
text
-->P_P_YYYYMM text
<--P_L_MONTH text
FORM get_month USING p_yyyymm
CHANGING p_month.
Returns the name of month according to the digits in p_yyyymm
DATA: l_monthdigits(2) TYPE c.
l_monthdigits = p_yyyymm+4(2).
CASE l_monthdigits.
WHEN '01'.
p_month = 'January'(701).
WHEN '02'.
p_month = 'February'(702).
WHEN '03'.
p_month = 'March'(703).
WHEN '04'.
p_month = 'April'(704).
WHEN '05'.
p_month = 'May'(705).
WHEN '06'.
p_month = 'June'(706).
WHEN '07'.
p_month = 'July'(707).
WHEN '08'.
p_month = 'August'(708).
WHEN '09'.
p_month = 'September'(709).
WHEN '10'.
p_month = 'October'(710).
WHEN '11'.
p_month = 'November'(711).
WHEN '12'.
p_month = 'December'(712).
ENDCASE.
CONCATENATE p_yyyymm+0(4) '->' p_month INTO p_month.
ENDFORM. " GET_MONTH
/code
Regards
Uwe -
Hello All
I am Creating a Tree and It is going to Populate only when the Node is Expanded.
I.E. the Child records are created only when the Node is Expanded.
What we Did is that when we are creating a Parent Node, we are populating a dummy child node to the Parent Node, so that the + sign will be shown.
Now when I am Expanding the + sign, it has to delete the Dummy child node and then create the Child nodes under the Dummy one.
For this One I am unable to Find a solution.
PLEASE HELP ME REGARDING THIS ONE.
THIS PROBLEM IS RELATING TO FORMSIn the when-tree-node-expanded trigger.
Store the system.trigger_node. This is the parent.
Search, starting with the parent, for a child which has the value/label that you gave the dummy node. Did you find one? If yes then delete it.
If you didn't find one then you stop as you've already expanded this node I guess.
After you delete the child you must then add the new children. So loop through the code that produces the list of new children you want, and add them under the parent that you started with.
Hope this helps. -
Version: Jdeveloper 11.1.2.1.0
how to get programmatically tree node value.
i have tried but cann't read value from selected node.
please help me.
here is my application creation steps:
1. New Application
2. Fusion Web Application (ADF) Template
3. Create View Object VOTreeMst
Query:
Select Department_Name,Department_Id
From Departments
4. Create View Object VOTreeChd
Query:
Select Last_Name,Employee_Id,Department_Id
From Employees
5. Create View Link VLTreeMstChd
VOTreeMst.DepartmentId=VOTreeChd.DepartmentId
And Add to Application Module
6. Create page page1 in ViewController
New-->Web Tier-->JSF/Facelets-->Page
Selected Document Type JSP XML
7. Drag VOTreeMst1 From Data Controls into page1
and select Tree-->ADF Tree
8. ADD java Code into selection Listener
public void nodeSelect(SelectionEvent selectionEvent) {
//original selection listener set by ADF
String adfSelectionListener = "#{bindings.VOTreeMst1.treeModel.makeCurrent}";
//make sure the default selection listener functionality is preserved.
//you don't need to do this for multi select trees as the ADF binding
//only supports single current row selection
/* START PRESERVER DEFAULT ADF SELECT BEHAVIOR */
FacesContext fctx = FacesContext.getCurrentInstance();
Application application = fctx.getApplication();
ELContext elCtx = fctx.getELContext();
ExpressionFactory exprFactory = application.getExpressionFactory();
MethodExpression me = null;
me = exprFactory.createMethodExpression(elCtx, adfSelectionListener, Object.class,
new Class[] { SelectionEvent.class });
me.invoke(elCtx, new Object[] { selectionEvent });
/* END PRESERVER DEFAULT ADF SELECT BEHAVIOR */
RichTree tree = (RichTree)selectionEvent.getSource();
TreeModel model = (TreeModel)tree.getValue();
//get selected nodes
RowKeySet rowKeySet = selectionEvent.getAddedSet();
Iterator rksIterator = rowKeySet.iterator();
//for single select configurations, thi sonly is called once
while (rksIterator.hasNext()) {
List key = (List)rksIterator.next();
JUCtrlHierBinding treeBinding = null;
CollectionModel collectionModel = (CollectionModel)tree.getValue();
treeBinding = (JUCtrlHierBinding)collectionModel.getWrappedData();
JUCtrlHierNodeBinding nodeBinding = treeBinding.findNodeByKeyPath(key);
Row rw = nodeBinding.getRow();
//print first row attribute. Note that in a tree you have to determine the node
//type if you want to select node attributes by name and not index
String rowType = rw.getStructureDef().getDefName();
if(rowType.equalsIgnoreCase("VOTreeMst")){
System.out.println("This row is a department: " + rw.getAttribute("DepartmentId"));
else if(rowType.equalsIgnoreCase("VOTreeChd")){
System.out.println("This row is an employee: " + rw.getAttribute("EmployeeId"));
else{
System.out.println("Huh ????");
// ... do more usefuls stuff here
9. when i click on first node it is working but i click on second node it is not working
error message::
<LifecycleImpl> <_handleException> ADF_FACES-60098:Faces lifecycle receives unhandled exceptions in phase INVOKE_APPLICATION 5
javax.el.ELException: java.lang.NullPointerException
at com.sun.el.parser.AstValue.invoke(Unknown Source)
at com.sun.el.MethodExpressionImpl.invoke(Unknown Source)
at org.apache.myfaces.trinidad.component.UIXComponentBase.broadcastToMethodExpression(UIXComponentBase.java:1589)
at org.apache.myfaces.trinidad.component.UIXTree.broadcast(UIXTree.java:237)
<RegistrationConfigurator> <handleError> ADF_FACES-60096:Server Exception during PPR, #1
javax.el.ELException: java.lang.NullPointerException
I have also tried using following code but same problem
public void onTreeSelect(SelectionEvent selectionEvent) {
//original selection listener set by ADF
String adfSelectionListener = "#{bindings.VOTreeMst1.treeModel.makeCurrent}";
//make sure the default selection listener functionality is preserved.
//you don't need to do this for multi select trees as the ADF binding
//only supports single current row selection
/* START PRESERVER DEFAULT ADF SELECT BEHAVIOR */
FacesContext fctx = FacesContext.getCurrentInstance();
Application application = fctx.getApplication();
ELContext elCtx = fctx.getELContext();
ExpressionFactory exprFactory = application.getExpressionFactory();
MethodExpression me = null;
me = exprFactory.createMethodExpression(elCtx, adfSelectionListener, Object.class,
new Class[] { SelectionEvent.class });
me.invoke(elCtx, new Object[] { selectionEvent });
/* END PRESERVER DEFAULT ADF SELECT BEHAVIOR */
RichTree tree = (RichTree)selectionEvent.getSource();
TreeModel model = (TreeModel)tree.getValue();
//get selected nodes
RowKeySet rowKeySet = selectionEvent.getAddedSet();
Iterator rksIterator = rowKeySet.iterator();
//for single select configurations, thi sonly is called once
while (rksIterator.hasNext()) {
List key = (List)rksIterator.next();
JUCtrlHierBinding treeBinding = null;
treeBinding = (JUCtrlHierBinding)((CollectionModel)tree.getValue()).getWrappedData();
JUCtrlHierNodeBinding nodeBinding = treeBinding.findNodeByKeyPath(key);
Row rw = nodeBinding.getRow();
//print first row attribute. Note that in a tree you have to determine the node
//type if you want to select node attributes by name and not index
System.out.println("row: " + rw.getAttribute(0));
But
If i create .jspx page From
Web Tier->Jsp->page Then it is working fine
when i create .jspx page From
Web Tier->JSF\Facelets->page Then it is not working
i need to get value from "Web Tier->JSF\Facelets->page"
is there any help please?You should try Franks generic selectionListener http://www.oracle.com/technetwork/developer-tools/adf/learnmore/25-generic-tree-selection-listener-169164.pdf. For help on hoe to get the selected tree node data check http://www.oracle.com/technetwork/developer-tools/adf/learnmore/26-get-selected-tree-node-data-169165.pdf
Timo -
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). -
RichTree component hangs (+ server crash) with setDisplayRowKey
Details:
JDeveloper + ADF 11.1.1.4.0
Java 6.0 Update 24
Tested with IE 8 and FF 4
Integrated WebLogic 10.3.4.0 (I haven't tested this on other servers yet, but even so, the server shouldn't crash, see below)
I'll describe my simplified use case here before tackling the real issue:
On a page I have a RichTree component, which is rendered based on certain simple conditions. When these conditions are met, the tree shows up and needs to render its nodes according to specific requirements.
So, suppose we have this fully expanded simple tree, of which each row is clickable (Command(Image)Link) and upon clicking it refreshes the page with the data tied to that row shown on the page (the data is bound to an entity based view object that recursively traverses itself to provide the data):
* Root
|- 1
|- a
|- x
|- 2
|- a
|- x
|- p
|- y
|- b
|- 3
|- aIf I want row 2-a-x to be displayed, then the tree should be rendered as follows (with the specified row 'marked', so that it stands out from other rows):
* Root
|- 1
|- 2
|- a
|- x
|- y
|- b
|- 3I've managed this use case by employing the method setDisplayRowKey on the tree and providing the keys of the rows 2, a and x in that order (specifying other rows to be displayed generates a new list of parent keys). The tree renders correctly with the specified row displayed and the rest collapsed, which is good, but everytime it renders, it hangs and says it's retrieving data in a yellow message bar, while the tree is still collapseable and functional. Clicking on one of the rows resolves the hanging issue (the message disappears and the tree is rendered again), but no action is fired. Clicking a row again resumes the normal functioning of the tree and the page refreshes correctly with the new data due to the action bound to that row.
I've also discovered that when I use setActiveRowKey and setRowKey in addition to setDisplayRowKey, the hanging issue does not occur anymore on the first rendering of the tree. When the tree is hidden again, however, and rendered again, then the problem comes back.
It appears that there is some server traffic going on at the end of the rendering of the tree, but I have no clue what it is. Meanwhile, the page itself keeps functioning as it should: navigation works and actions are fired (except the one from the tree itself). When I stop the deployment while this is happening, ADF complains immediately that it has lost connection to the server. If I do not stop the deployment and leave it alone for some time, eventually the server crashes and shuts down with the following message:
EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000000006dbfe570, pid=4796, tid=1312
It has left behind a fairly big log with information regarding threads and memory mapping. I could try to create a test case, so you can try it out (if I can reproduce it), but before I do that, I'd like to hear if there's anything I can do to resolve this issue. Thanks in advance! For now I'll simply expand everything upon initial display and 'mark' the required row, so that it stands out from the rest of the rows.
Edit: I might point out that when I do not use setDisplayRowKey and expand the tree either manually or automatically (fully) upon initial display, everything is working fine.
Edited by: Laurens van der Blom on 25-mei-2011 4:14Could someone please give me insight into this issue? I've tried again to solve it, but to no avail.
-
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 -
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
mrvHi 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 -
How to trigger an ActionListener in different class on click of a tree node
Hi guyz,
There are three panels inside my main Frame
-->TopPanel,MiddlePanel and BottomPanel. I have a tree structure inside a panel. This panel along with couple more panels is in MiddlePanel. My main class is "mainClass.java". Inside that i have an actionListener for a specific button. I need to trigger that actionListener when i click one of the tree nodes in the panel i specified before. The problem is that my MiddlePanel is itself a different ".java" file which is being called in my "mainClass" when a specific button is clicked. There are different buttons in my "mainClass" file and for each one i am creating different MiddlePanels depending on the buttons clicked.
So, if i click the tree node, i need to remove the MiddlePanel and recreate the MiddlePanel(One that will be created when a different button in the mainClass file is clicked). i.e., i need to trigger the actionListener for that corresponding button. Is there a way to do it?use this code to call different panel by selecting tree node.....ok
import javax.swing.*;
import javax.swing.tree.*;
import java.awt.*;
import java.sql.SQLException;
import javax.swing.event.*;
class MainTree extends JFrame
private static final long serialVersionUID = 1L;
CardLayout cl = new CardLayout();
JPanel panel = new JPanel(cl);
public MainTree() throws Exception
JPanel blankPanel = new JPanel();
blankPanel.setBorder(BorderFactory.createTitledBorder("Blank Panel"));
panel.add(blankPanel,"0");
panel.add(blankPanel,BorderLayout.CENTER);
panel.setPreferredSize(new Dimension(800, 100));
setSize(1000, 700);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
// getContentPane().setLayout(new GridLayout(1,2));
getContentPane().setLayout(new BorderLayout());
ConfigTree test = new ConfigTree();
DefaultMutableTreeNode mainTree = (DefaultMutableTreeNode)test.buildTree();
JTree tree = new JTree(mainTree);
tree.setCellRenderer(new DefaultTreeCellRenderer(){
private static final long serialVersionUID = 1L;
public Component getTreeCellRendererComponent(JTree tree,Object value,
boolean sel,boolean expanded,boolean leaf,int row,boolean hasFocus){
JLabel lbl = (JLabel)super.getTreeCellRendererComponent(tree,value,sel,expanded,leaf,row,hasFocus);
NodeWithID node = (NodeWithID)((DefaultMutableTreeNode)value).getUserObject();
if(node.icon != null)lbl.setIcon(node.icon);
return lbl;
getContentPane().add(new JScrollPane(tree));
loadCardPanels((DefaultMutableTreeNode)((DefaultTreeModel)tree.getModel()).getRoot());
getContentPane().add(panel,BorderLayout.EAST);
getContentPane().add(blankPanel,BorderLayout.WEST);
// getContentPane().add(panel);
tree.addTreeSelectionListener(new TreeSelectionListener(){
public void valueChanged(TreeSelectionEvent tse){
NodeWithID node =(NodeWithID)((DefaultMutableTreeNode)((TreePath)tse.getPath())
.getLastPathComponent()).getUserObject();
if(node.nodePanel != null)
String cardLayoutID = node.ID;
cl.show(panel,cardLayoutID);
cl.show(panel,"0");
public void loadCardPanels(DefaultMutableTreeNode dmtn)
for(int x = 0; x < dmtn.getChildCount(); x++)
if(((DefaultMutableTreeNode)dmtn.getChildAt(x)).isLeaf() == false)
loadCardPanels((DefaultMutableTreeNode)dmtn.getChildAt(x));
NodeWithID node = (NodeWithID)((DefaultMutableTreeNode)dmtn.getChildAt(x)).getUserObject();
if(node.nodePanel != null)
String cardLayoutID = node.ID;
panel.add(cardLayoutID,node.nodePanel);
public static void main(String[] args) throws Exception{new MainTree().setVisible(true);}
class ConfigTree
public Object buildTree() throws Exception
NodeWithID n0 = new NodeWithID("HelpDesk","");
NodeWithID n1 = new NodeWithID("Administrator",n0.nodeName);
NodeWithID n2 = new NodeWithID("Report Form",n1.nodeName,new Tree().getContentPane());
NodeWithID n3 = new NodeWithID("Create User",n2.nodeName,new JPanel());
NodeWithID n4 = new NodeWithID("Unlock User",n2.nodeName,new unlockui().getContentPane());
NodeWithID n5 = new NodeWithID("List User",n2.nodeName,new JPanel());
NodeWithID n6 = new NodeWithID("Assign Role",n2.nodeName,new AssignRole());
NodeWithID n9 = new NodeWithID("Operator",n1.nodeName,new JPanel());
NodeWithID n10 = new NodeWithID("Create Ticket",n9.nodeName,new JPanel());
NodeWithID n11 = new NodeWithID("My Ticket",n9.nodeName,new JPanel());
NodeWithID n12 = new NodeWithID("All Ticket",n9.nodeName,new JPanel());
NodeWithID n13 = new NodeWithID("Event Viewer",n1.nodeName,new JPanel());
DefaultMutableTreeNode top = new DefaultMutableTreeNode(n0);
DefaultMutableTreeNode branch1 = new DefaultMutableTreeNode(n1);
top.add(branch1);
DefaultMutableTreeNode node1_b1 = new DefaultMutableTreeNode(n2);
DefaultMutableTreeNode n1_node1_b1 = new DefaultMutableTreeNode(n3);
DefaultMutableTreeNode n2_node1_b1 = new DefaultMutableTreeNode(n4);
DefaultMutableTreeNode n3_node1_b1 = new DefaultMutableTreeNode(n5);
DefaultMutableTreeNode n4_node1_b1 = new DefaultMutableTreeNode(n6);
branch1.add(node1_b1);
branch1.add(n1_node1_b1);
branch1.add(n2_node1_b1);
branch1.add(n3_node1_b1);
branch1.add(n4_node1_b1);
DefaultMutableTreeNode node4_b1 = new DefaultMutableTreeNode(n9);
DefaultMutableTreeNode n1_node4_b1 = new DefaultMutableTreeNode(n10);
DefaultMutableTreeNode n2_node4_b1 = new DefaultMutableTreeNode(n11);
DefaultMutableTreeNode n3_node4_b1 = new DefaultMutableTreeNode(n12);
node4_b1.add(n1_node4_b1);
node4_b1.add(n2_node4_b1);
node4_b1.add(n3_node4_b1);
DefaultMutableTreeNode node5_b1 = new DefaultMutableTreeNode(n13);
branch1.add(node1_b1);
branch1.add(node4_b1);
branch1.add(node5_b1);
return top;
class NodeWithID
String nodeName;
String ID;
JPanel nodePanel;
ImageIcon icon;
public NodeWithID(String nn,String parentName)
nodeName = nn;
ID = parentName+" - "+nodeName;
public NodeWithID(String nn,String parentName,Container container)
this(nn,parentName);
nodePanel = (JPanel) container;
nodePanel.setBorder(BorderFactory.createTitledBorder(ID + " Panel"));
public NodeWithID(String nn,String parentName,JPanel p, ImageIcon i)
this(nn,parentName,p);
icon = i;
public String toString(){return nodeName;}
} -
Update tree node icon, better way?
Hi,.
I have my own custom renderer for my JTree....such as
public class MyTreeNodeRenderer extends JLabel implements TreeCellRenderer {
public Component getTreeCellRendererComponent(
JTree treeVal,
Object valueVal,
boolean selectedVal,
boolean expandedVal,
boolean leafVal,
int rowVal,
boolean hasFocusVal) {
MyTreeNode node = (MyTreeNode) valueVal;
// get the latest type for this node
node.type = getType(node);
if (node.type == 1) {
setIcon(TYPE1_ICON);
else {
setIcon(TYPE_BASIC_ICON);
return this;
}...intially the tree nodes have their icons, as they should...later on their "type" is updated...so instead of being 1..its now something else...so the icon should change.....but it doesnt occur fast enough...so i added this to my renderer
public void doRepaint() {
repaint();
myTree.repaint();
}basically anytime i needed to update the icon in the tree i called the doRepaint when i want the new icon to appear in the tree..that helped somewhat..but it is still kinda slow....any ideas how to do this?valueForPathChanged() serves different purposes as you can see from its description. You need to call treeModel.nodeChanged(node) after your node changed its "type". If you don't want to hold or don't have treeModel reference you could use tree classes from .useful library and be able to call nodeChanged() directly from a node that has been changed.
Denis Krukovsky
http://dotuseful.sourceforge.net/ -
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 appreciatedHi,
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
Maybe you are looking for
-
What's a loss how to respond when iPad?
What's a loss how to respond when iPad?
-
Pictures are no longer loading in Safari, any clues?
Recently I'm finding that many pages on Safari are not loading properly and/or pictures do not load. Perhaps I need to update something, but I am not sure what or how. Does anyone have any suggestions? Thanks!
-
Lost all my settings setting up a new user Helllllllp?
I was setting up a new user account and somehow reset my desktop to default. My data is still on the hard drive but I can't find my Phone Book Data for example. Other data I am looking for is my Safari Bookmarks, old emails etc. Any suggestions? Than
-
Web Intelligence Document Freezing
Hello everyone, I hope someone could help me solve this issue. I open a new Web Intelligence document, select the required universe on which to build my document, it starts loading for a couple of minutes and then freezes. this issue appeared just y
-
Search for the t-code where the specefic output type is used
Hi I want to know how can we search for the t-code used for a specefic output type in use? I have a requirement where in i have a output type, i knwo teh prog name and the form name... i know it is used in SD and billing but i am not able ot exactl