Solved

Distinguishing components of a JTree node

Posted on 2002-07-01
6
474 Views
Last Modified: 2008-02-01
Is there any way to distinguish between a mouse event on the icon,text, or any other object instaniated in a TreeCellRenderer of a node? I'm trying to assign two different actions to someone clicking on the text of a node and someone clicking on the Icon of a node.
0
Comment
Question by:ashep15
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
6 Comments
 

Author Comment

by:ashep15
ID: 7122366
I have a DefaultTreeCellRender :

class NodeRenderer extends DefaultTreeCellRenderer {

     private JPanel panel = new JPanel();
     private Component strut = Box.createHorizontalStrut(5);
     private JLabel image = new JLabel(new ImageIcon("../../images/info.jpg"));
     
     
     
     public NodeRenderer(){

          panel.setBackground(UIManager.getColor("Tree.textBackground"));
          setOpaque(false);
          panel.setOpaque(false);
         
          panel.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
          panel.add(this);
          panel.add(strut);
          panel.add(image);
     }
     
     public Component getTreeCellRendererComponent(JTree t, Object o, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
     
          DataObj node = (DataObj)o;
          super.getTreeCellRendererComponent(t, o, selected, expanded, leaf, row, hasFocus);
          image.setVisible(node.isLeaf());
         
          return panel;
     }

}


I want to distinguish when someone clicks on the image as opposed to anywhere else on the tree cell.
0
 
LVL 35

Expert Comment

by:girionis
ID: 7122456
 I guess you could use some of the methods defined in the JTree class:

"public Rectangle getRowBounds(int row)"

Returns the Rectangle that the node at the specified row is drawn in.

"public Rectangle getPathBounds(TreePath path)"

Returns the Rectangle that the specified node will be drawn into. Returns null if any component in the path is hidden (under a collapsed parent).

  For more information look at teh API documentation.

   Hope it helps.
0
 
LVL 92

Expert Comment

by:objects
ID: 7123373
Try adding your mouse listener to the components of your renderer.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:ashep15
ID: 7124669
Adding a mouseListener doesn't work becuase it's overridden when the tree renders each cell using one instance of JPanel. I've added a mouseListener to my JLabel, but it gets wiped out when rendered. I also tried adding a mouseListener to the NodeRenderer itself to no avail.

I thought if this could be done, it would be by using the coordinates of where on the Rectangle object the mouse clicked occured.
0
 
LVL 7

Accepted Solution

by:
Igor Bazarny earned 500 total points
ID: 7130075
Hi,

Try following code. Does it work for you?

Regards,
Igor Bazarny,
Brainbench MVP for Java 1
-----------------------------------------------------

package ee.swing.tree;

import java.awt.Component;
import java.awt.Rectangle;
import java.awt.event.MouseListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.event.*;

public class HitTest{
    public static void main(String[] args){
        new HitTest().run();
    }
   
    public void run(){
        JFrame frame = new JFrame("Hit Test");
        final JTree tree = new JTree(buildModel());
        frame.getContentPane().add(tree);

        TreeCellRenderer renderer = tree.getCellRenderer();
        Component prototype = renderer.getTreeCellRendererComponent(tree,"text",false,false,false,0,false);
        if( prototype instanceof JLabel ){
            JLabel label = (JLabel)prototype;
            final int icon = label.getIcon() == null ? 0 : label.getIcon().getIconWidth();
            final int gap = label.getIconTextGap();
            tree.addMouseListener(new MouseAdapter(){
                public void mouseClicked(MouseEvent event){
                    TreePath path = tree.getClosestPathForLocation(event.getX(), event.getY());
                    Rectangle bounds = tree.getPathBounds(path);
                    if( bounds.contains(event.getPoint()) ){
                        if( event.getX() < bounds.x+icon ){
                            System.out.println("Click on icon");
                        }
                        else if(event.getX() < bounds.x+icon+gap){
                            System.out.println("Click on gap");
                        }
                        else{
                            System.out.println("Click on text");
                        }
                    }
                }
            });
        }

        frame.pack();
        frame.setVisible(true);

    }

    private TreeModel buildModel(){
        DefaultMutableTreeNode root = new DefaultMutableTreeNode("root");
        DefaultMutableTreeNode node2 = new DefaultMutableTreeNode("Node 1");
        root.add(node2);
        node2.add(new DefaultMutableTreeNode("Subnode 1-1"));
        node2.add(new DefaultMutableTreeNode("Subnode 1-2"));
        node2.add(new DefaultMutableTreeNode("Subnode 1-3"));
        node2 = new DefaultMutableTreeNode("Node 2");
        root.add(node2);
        node2.add(new DefaultMutableTreeNode("Subnode 2-1"));
        node2.add(new DefaultMutableTreeNode("Subnode 2-2"));
        node2.add(new DefaultMutableTreeNode("Subnode 2-3"));
        node2.add(new DefaultMutableTreeNode("Subnode 2-4"));
        return new DefaultTreeModel(root);
    }
}
0
 

Author Comment

by:ashep15
ID: 7132072
That was it! I just added the mouseClicked function to my existing mouseListener on the JTree. In my NodeRenderer class I added the icon and gap width as constants....

tree.addMouseListener(new MouseAdapter() {
                   
                    public void mousePressed(MouseEvent e) {

                         JTree t = (JTree)e.getSource();
                         int row = t.getRowForLocation(e.getX(), e.getY());
                   
                         if (row != -1){
                              isNewSubset = false;
                              TreePath path = t.getPathForRow(row);
                              DataObj someNode = (DataObj)path.getLastPathComponent();
                             
                              if(someNode.fileIndex > -1){
                                   //display documentView data for the current data entity
                                   DataFile docFile = (DataFile)(fileCollection.elementAt(someNode.fileIndex));
                                   
                                   if(documentView.getText() != docFile.documentation.toString()){
                                        documentView.setText(docFile.documentation.toString());
                                   }
                              } else {
                                   //don't show anything if there is no .ndx file
                                   documentView.setText("");
                              }
                         }
                    }
                   
                    public void mouseClicked(MouseEvent event){
                                             
                         TreePath path = tree.getClosestPathForLocation(event.getX(), event.getY());
          Rectangle bounds = tree.getPathBounds(path);
          if( bounds.contains(event.getPoint()) ){
               if( event.getX() < bounds.x+treeRenderer.icon_size ){
                 System.out.println("Click on icon");
            }
            else if(event.getX() < bounds.x+treeRenderer.icon_size+treeRenderer.gap_size){
              System.out.println("Click on gap");
            }
            else{
              System.out.println("Click on text");
            }
              }
            }
          });
         
          tree.setCellRenderer(treeRenderer);


with treeRenderer being of type of NodeRenderer....


class NodeRenderer extends DefaultTreeCellRenderer {

     private JPanel panel = new JPanel();
     private Component strut = Box.createHorizontalStrut(5);
     private JLabel image = new JLabel(new ImageIcon("../../images/info.jpg"));
     final int icon_size;
  final int gap_size;
     
     
     public NodeRenderer(){

          icon_size = image.getIcon() == null ? 0 : image.getIcon().getIconWidth();
          gap_size = image.getIconTextGap();
          panel.setBackground(UIManager.getColor("Tree.textBackground"));
          setOpaque(false);
          panel.setOpaque(false);
         
          panel.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
          panel.add(this);
          panel.add(strut);
          panel.add(image);
     }
     
     public Component getTreeCellRendererComponent(JTree t, Object o, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
     
          DataObj node = (DataObj)o;
          super.getTreeCellRendererComponent(t, o, selected, expanded, leaf, row, hasFocus);
          image.setVisible(node.isLeaf());
         
          return panel;
     }

}
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

INTRODUCTION Working with files is a moderately common task in Java.  For most projects hard coding the file names, using parameters in configuration files, or using command-line arguments is sufficient.   However, when your application has vi…
Introduction This article is the last of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers our test design approach and then goes through a simple test case example, how …
This tutorial covers a practical example of lazy loading technique and early loading technique in a Singleton Design Pattern.
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.
Suggested Courses

624 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question