[Webinar] Streamline your web hosting managementRegister Today

x
?
Solved

Distinguishing components of a JTree node

Posted on 2002-07-01
6
Medium Priority
?
489 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
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
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 

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 2000 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: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone 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

Are you developing a Java application and want to create Excel Spreadsheets? You have come to the right place, this article will describe how you can create Excel Spreadsheets from a Java Application. For the purposes of this article, I will be u…
In this post we will learn how to make Android Gesture Tutorial and give different functionality whenever a user Touch or Scroll android screen.
Viewers learn how to read error messages and identify possible mistakes that could cause hours of frustration. Coding is as much about debugging your code as it is about writing it. Define Error Message: Line Numbers: Type of Error: Break Down…
This video teaches viewers about errors in exception handling.
Suggested Courses
Course of the Month8 days, 7 hours left to enroll

613 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