Johann Bauer
Johann Bauer

Reputation: 2606

Detect double click on a JTree row

I add a mouse listener to a JTree like this:

 trProjects.addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                int selRow = trProjects.getRowForLocation(e.getX(), e.getY());
                TreePath selPath = trProjects.getPathForLocation(e.getX(), e.getY());
                if(selRow != -1 && e.getClickCount() == 2 && selPath != null) {
                    Object selectedNode = selPath.getLastPathComponent();
                    // do something else
                }
            }
        });

This detects if a user double-clicks on either the icon or the text of the JTree. But I want it to also detect if the user clicks anywhere else in that row.

To illustrate my problem, I made a screenshot:

visualization of the problem

What can I do detect double-clicks on the right side of the row?

Upvotes: 1

Views: 1038

Answers (1)

aterai
aterai

Reputation: 9808

Not sure if it work on all Look and Feels but you can try to override XXXTreeUI#getPathBounds(...):

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.plaf.synth.SynthTreeUI;

public final class DoubleClicksOnRightSideRowTest {
  private JComponent makeUI() {
    final JTree trProjects = new JTree();
    trProjects.setUI(new SynthTreeUI() {
      @Override public Rectangle getPathBounds(JTree tree, TreePath path) {
        if (tree != null && treeState != null) {
          Rectangle rect = treeState.getBounds(path, new Rectangle());
          if (rect != null) {
            Insets insets = tree.getInsets();
            rect.width = tree.getWidth();
            rect.y += insets.top;
          }
          return rect;
        }
        return null;
      }
    });
    trProjects.addMouseListener(new MouseAdapter() {
      @Override public void mousePressed(MouseEvent e) {
        int selRow = trProjects.getRowForLocation(e.getX(), e.getY());
        TreePath selPath = trProjects.getPathForLocation(e.getX(), e.getY());
        if (selRow != -1 && e.getClickCount() == 2 && selPath != null) {
          Object selectedNode = selPath.getLastPathComponent();
          System.out.println("do something else");
        }
      }
    });
    return new JScrollPane(trProjects);
  }
  public static void main(String... args) {
    EventQueue.invokeLater(new Runnable() {
      @Override public void run() {
        createAndShowGUI();
      }
    });
  }
  public static void createAndShowGUI() {
    try {
      for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) {
        if ("Nimbus".equals(laf.getName())) {
          UIManager.setLookAndFeel(laf.getClassName());
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    JFrame f = new JFrame();
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    f.getContentPane().add(new DoubleClicksOnRightSideRowTest().makeUI());
    f.setSize(320, 240);
    f.setLocationRelativeTo(null);
    f.setVisible(true);
  }
}

Upvotes: 1

Related Questions