Jtree: "check if tree node is a folder" not wrkin
Hi, I have a JTree and If a folder does not has any file, it displays as file not folder. Is there any way to fix it. I want to represent an empty folder as folder not file. here is the code. Thanks for help.
if(!f.isDirectory()) {
System.out.println("FILE - " + f.getName());
DefaultMutableTreeNode child = new DefaultMutableTreeNode(f.getName());
node.add(child);
else {
DefaultMutableTreeNode child = new DefaultMutableTreeNode(f.getName());
node.add(child);
File fList[] = f.listFiles();
for(int i = 0; i < fList.length; i++)
getList(child, fList);
Sorry for not formatting the code:
here is the code again:
public void getDirectories()
getList(root, new File("c:/FIST/Projects/"));
KeyStroke ks = KeyStroke.getKeyStroke("ctrl A");
tree.getInputMap().put(ks, "none");
public void getList(DefaultMutableTreeNode node, File f)
if(!f.isDirectory())
DefaultMutableTreeNode child = new DefaultMutableTreeNode(f.getName());
int i=child.getLevel();
if(i==0)
node.add(child);
else {
DefaultMutableTreeNode child = new DefaultMutableTreeNode(f.getName());
node.add(child);
File fList[] = f.listFiles();
for(int i = 0; i < fList.length; i++)
getList(child, fList);
Similar Messages
-
I am allowing the user to search for a node in a JTree. I can find the node and progamatically expand and select the node. What I would like to do next is find the x,y coordinates of this selected node so I can use Robot to move the mouse to this node. I have hover help which is chock full of information in HTML describing this node, however, the user now is required to move the cursor to this selected node to see the hover help.
Any help would be appreciated.Hi ,
try this
jlabel.setIcon( null ) ; -
Displaying the entire text of a tree node when the tree isn�t wide enough
Hi,
I have a JTree displayed in a JScrollPane, so there is a chance that some of the tree data may be hidden if the tree's width is insufficient, so when the user moves the cursor over a tree node whose text is not completely visible (cut off by the right edge of the scroll pane and/or window), a tooltip is displayed to show the entire node text. So far so good!
If the user double click a node in the tree a new window is supposed to be opened. This works fine if the tooltip hasn�t been displayed jet, but if it has then the user has to click 3 times to open the window.
The first time to remove the tooltip and the next 2 opens the window.
How can I awoid this?
Thanks!!!!
:-)LisaAny ideas, please?
-
On right click, the focus is not set on tree node.
Dear members,
I have a tree and a database block, when i right click on a tree node, the focus is not set on the node.
If I first click on the node and then right click on selected node it populate the database block.
But I want to populate the datablock on right click.
how to implement it?
Regards:No body ever encountered this problem?
Any advice would be appreciated.
Thanks -
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 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. -
JTree - Fetch URL from a tree node.
Now I have created one JTree and one JEditorPane.
Basically I am creating a help file. (a chm file in windows).
So I need to handle mouse click event on each node on JTree.
I have used such format to add a hyperlink.
sample code:---------------------------------------------------------------------------------------------------------------------------
javax.swing.tree.DefaultMutableTreeNode treeNode1 = new javax.swing.tree.DefaultMutableTreeNode("JTree");
javax.swing.tree.DefaultMutableTreeNode treeNode2 = new javax.swing.tree.DefaultMutableTreeNode("colors");
javax.swing.tree.DefaultMutableTreeNode treeNode3 = new javax.swing.tree.DefaultMutableTreeNode("blue");
treeNode2.add(treeNode3);
treeNode3 = new javax.swing.tree.DefaultMutableTreeNode("violet");
treeNode2.add(treeNode3);
treeNode3 = new javax.swing.tree.DefaultMutableTreeNode("red");
treeNode2.add(treeNode3);
treeNode3 = new javax.swing.tree.DefaultMutableTreeNode("yellow");
treeNode2.add(treeNode3);
treeNode1.add(treeNode2);
treeNode2 = new javax.swing.tree.DefaultMutableTreeNode("s");
treeNode3 = new javax.swing.tree.DefaultMutableTreeNode("<html><a href='C:\\Program Files\\Java\\jdk1.6\\README.html'>Read Me</a></html>");
treeNode2.add(treeNode3);
jTree1.setModel(new javax.swing.tree.DefaultTreeModel(treeNode1));
jTree1.addMouseListener(new java.awt.event.MouseAdapter() {
public void mousePressed(java.awt.event.MouseEvent evt) {
TreeListener(evt);
private void TreeListener(java.awt.event.MouseEvent evt) {
int selRow= jTree1.getRowForLocation(evt.getX(), evt.getY());
TreePath tp = jTree1.getPathForLocation(evt.getX(), evt.getY());
if(selRow!=-1) {
if(evt.getClickCount()==1) {
jTree1.setSelectionPath(tp);
Now there is a hyperlink created for that node "Read Me".
My Question is ..........
How do I fetch this stored URL in each node for setting it to my JEditorPane....???ok, it seems to be working now. I just return the JInternalFrame in the getTreeCellRendererComponent() method.
-
How to set the default tree node in JTree?
I want to set a default tree node in JTree when start the program,
what is the method or the function to call?
Thanks~If you by "default" mean "selected", then you can use one of the setSelectionXXX methods in the JTree API.
If you by "default" mean something else, never mind this post :-) -
Post Back Tree view when tree node check changed
Hi everyone,
I have a tree view, both child and parent have check box. I want to check all the child on the parent selection.
I try "SelectedNodeChanged" but the page doesn't post back to fire my function.
I know I can use javascript to post back the page, but is there any other way to post back my page without javascript???
Thnaks in advance.Hi everyone,
I have a tree view, both child and parent have check box. I want to check all the child on the parent selection.
I try "SelectedNodeChanged" but the page doesn't post back to fire my function.
I know I can use javascript to post back the page, but is there any other way to post back my page without javascript???
Thnaks in advance.
Assuming this is a WinForm application (it looks like it may not be), the following works pretty well:
Option Strict On
Option Explicit On
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles MyBase.Load
With TreeView1
.CheckBoxes = True
.ShowLines = True
.ShowPlusMinus = True
.ShowRootLines = True
.ExpandAll()
End With
End Sub
' Updates all child tree nodes recursively.
Private Sub CheckAllChildNodes(ByVal treeNode As TreeNode, ByVal nodeChecked As Boolean)
Dim node As TreeNode
For Each node In treeNode.Nodes
node.Checked = nodeChecked
If node.Nodes.Count > 0 Then
' If the current node has child nodes, call the CheckAllChildsNodes method recursively.
Me.CheckAllChildNodes(node, nodeChecked)
End If
Next node
End Sub
' NOTE This code can be added to the BeforeCheck event handler instead of the AfterCheck event.
' After a tree node's Checked property is changed, all its child nodes are updated to the same value.
Private Sub node_AfterCheck(ByVal sender As Object, ByVal e As TreeViewEventArgs) Handles TreeView1.AfterCheck
' The code only executes if the user caused the checked state to change.
If e.Action <> TreeViewAction.Unknown Then
If e.Node.Nodes.Count > 0 Then
' Calls the CheckAllChildNodes method, passing in the current
' Checked value of the TreeNode whose checked state changed.
Me.CheckAllChildNodes(e.Node, e.Node.Checked)
End If
End If
End Sub
End Class
The reference for that is this MSDN document.
If you're looking for a true tri-state operation though, honestly you might want to look at some third-party controls.
I hope that helps. :)
Please call me Frank :) -
Folder icon display at richfaces tree node
Hello All,
I would like to use richfaces tree structure.
But the issue with that is the folder icon display at each tree node.
For some reason i don't want the folder icon at the tree node.
Is there anyway to get rid of that?
I tried to change the image (iconFolder.gif) to some 1X1 pixel image in the richfaces jar file.
But when i added the new jar with new image for icon, that image is not loading.
I'm using Jboss4.2 as my application server.
Please help me to remove the folder display at tree node.
Thanks in advance.
Regards,
ElizabathHi,
I could see the icon attribute to specify the folder icon at the node. I placed a 1x1 pixel image as the iconfolder image. But that results in a blank pixel at the node. I wish to get rid of that.
Also i wanted to change the navigation images too. i would like to have the + and - sign images instead of arrows.
Any suggestions? -
JTree - Sometimes tree node is not selected, while clicking it using mouse
Hi,
I'm sure that it is a very rare scenario.But ,sometimes i couldnt select a tree node on mouse click.It happens very rarely and simulating the behaviour is not possible.If anyone have gone thru this,plz repond.
Thanks,
Kathirdid you try debug with a breakPoint on mouseListener->mouseClick event, and see if the selectionModel changes?
-
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,
ChrisOne 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! ) -
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);
} -
How to hide a tree node from the GUI but still keep it in the tree model?
Hi, All
I used a JTree in my project in which I have a DefaultTreeModel to store all the tree structure and a JTree show it on the screen. But for some reason, I want to hide some of the nodes from the user, but I don't want to remove them from the tree model because later on I still need to use them.
I searched on the web, some people suggested method to hide the root node, but that's not appliable to my project because I want to hide some non-root nodes; Some people also suggested to collapse the parent node when there are child to hide, it is not appliable to me either, because there still some other childnodes (sibling of the node to hide) I want to show.
How can I hide some of the tree node from the user? Thanks for any information.
LindaHere's an example using a derivation of DefaultTreeModel that shows (or does not show) two types of Sneech (appologies to the good Dr Zeus) by overiding two methods on the model.
Now, there are many things wrong with this example (using instanceof, for example), but it's pretty tight and shows one way of doing what you want.
Note: to make it useful, you''d have to change the implementation of setShowStarBelliedSneeches() to do something more sophisticated than simply firing a structure change event on the root node. You'd want to find all the star bellied sneech nodes and call fireTreeNodesRemoved(). That way the tree would stay expanded rather than collapse as it does now.
import javax.swing.JTree;
import javax.swing.JScrollPane;
import javax.swing.JOptionPane;
import javax.swing.JCheckBox;
import javax.swing.JPanel;
import javax.swing.tree.TreePath;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.DefaultMutableTreeNode;
import java.awt.Dimension;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Enumeration;
class FilteredTree
private class PlainBelliedSneech {
public String toString() { return "Plain Bellied Sneech"; }
private class StarBelliedSneech {
public String toString() { return "Star Bellied Sneech"; }
private class FilteredTreeModel
extends DefaultTreeModel
private boolean mShowStarBelliedSneeches= true;
private DefaultMutableTreeNode mRoot;
FilteredTreeModel(DefaultMutableTreeNode root)
super(root);
mRoot= root;
public Object getChild(Object parent, int index)
DefaultMutableTreeNode node=
(DefaultMutableTreeNode) parent;
if (mShowStarBelliedSneeches)
return node.getChildAt(index);
int pos= 0;
for (int i= 0, cnt= 0; i< node.getChildCount(); i++) {
if (((DefaultMutableTreeNode) node.getChildAt(i)).getUserObject()
instanceof PlainBelliedSneech)
if (cnt++ == index) {
pos= i;
break;
return node.getChildAt(pos);
public int getChildCount(Object parent)
DefaultMutableTreeNode node=
(DefaultMutableTreeNode) parent;
if (mShowStarBelliedSneeches)
return node.getChildCount();
int childCount= 0;
Enumeration children= node.children();
while (children.hasMoreElements()) {
if (((DefaultMutableTreeNode) children.nextElement()).getUserObject()
instanceof PlainBelliedSneech)
childCount++;
return childCount;
public boolean getShowStarBelliedSneeches() {
return mShowStarBelliedSneeches;
public void setShowStarBelliedSneeches(boolean showStarBelliedSneeches)
if (showStarBelliedSneeches != mShowStarBelliedSneeches) {
mShowStarBelliedSneeches= showStarBelliedSneeches;
Object[] path= { mRoot };
int[] childIndices= new int[root.getChildCount()];
Object[] children= new Object[root.getChildCount()];
for (int i= 0; i< root.getChildCount(); i++) {
childIndices= i;
children[i]= root.getChildAt(i);
fireTreeStructureChanged(this, path, childIndices, children);
private FilteredTree()
final DefaultMutableTreeNode root= new DefaultMutableTreeNode("Root");
DefaultMutableTreeNode parent;
DefaultMutableTreeNode child;
for (int i= 0; i< 2; i++) {
parent= new DefaultMutableTreeNode(new PlainBelliedSneech());
root.add(parent);
for (int j= 0; j< 2; j++) {
child= new DefaultMutableTreeNode(new StarBelliedSneech());
parent.add(child);
for (int k= 0; k< 2; k++)
child.add(new DefaultMutableTreeNode(new PlainBelliedSneech()));
for (int j= 0; j< 2; j++)
parent.add(new DefaultMutableTreeNode(new PlainBelliedSneech()));
parent= new DefaultMutableTreeNode(new StarBelliedSneech());
root.add(parent);
for (int j= 0; j< 2; j++) {
child= new DefaultMutableTreeNode(new PlainBelliedSneech());
parent.add(child);
for (int k= 0; k< 2; k++)
child.add(new DefaultMutableTreeNode(new StarBelliedSneech()));
for (int j= 0; j< 2; j++)
parent.add(new DefaultMutableTreeNode(new StarBelliedSneech()));
final FilteredTreeModel model= new FilteredTreeModel(root);
JTree tree= new JTree(model);
tree.setShowsRootHandles(true);
tree.putClientProperty("JTree.lineStyle", "Angled");
tree.setRootVisible(false);
JScrollPane sp= new JScrollPane(tree);
sp.setPreferredSize(new Dimension(200,400));
final JCheckBox check= new JCheckBox("Show Star Bellied Sneeches");
check.setSelected(model.getShowStarBelliedSneeches());
check.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
model.setShowStarBelliedSneeches(check.isSelected());
JPanel panel= new JPanel(new BorderLayout());
panel.add(check, BorderLayout.NORTH);
panel.add(sp, BorderLayout.CENTER);
JOptionPane.showOptionDialog(
null, panel, "Sneeches on Beeches",
JOptionPane.DEFAULT_OPTION,
JOptionPane.PLAIN_MESSAGE,
null, new String[0], null
System.exit(0);
public static void main(String[] argv) {
new FilteredTree(); -
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
Maybe you are looking for
-
i open firefox and get two popups that state "you have chosen to open and then its for firefox setup 3.6.1 or beta which i once used and uninstalled. a second is for a file in my documents--always the same file.
-
How can I public more than one iWeb site ?
Dear iLife users, I have a website http://www.inmokvc.com created with iWeb a couple of years ago and still online, now I would like to bring online a second website also created with iWeb but can't bring it online: I have a new domain name for my se
-
No sound through headphones/microphone ALC892
I've been trying for days to fix this issue, and am lost. I've got a new desktop and cannot get sound to come out my headphones, or take input from my microphone. I believe my sound card driver is installed correctly, and that it is a pulseaudio pr
-
Checked checkboxes in Numbers for iPad
Hi, Before submitting feedback to Apple about the following glitch, I'm posting it here to find out whether any Numbers for iOS jockeys have experienced the glitch also. In Numbers 09 (2.0.3) under Snow Leopard.8, I imported a spreadsheet created in
-
I cannot download updates to Photoshop Elements 9. I get an error message that my serial number is not recognized or eligible. Can you help with this?