我可以使用以下代码检测何时鼠标悬停在JTree的文本部分上。我还想检测用户何时将鼠标悬停在JTree文本左侧的图标上,该图标用于展开/折叠内容并相应地更改光标。我该怎么办?
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
public class Testing {
public static void main(String[] args) throws Exception {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JTree tree = new JTree(buildTree());
tree.addMouseMotionListener(new MouseMotionListener() {
@Override
public void mouseDragged(MouseEvent e) {
}
@Override
public void mouseMoved(MouseEvent e) {
TreePath tp = ((JTree) e.getSource()).getPathForLocation(e.getX(), e.getY());
if (tp != null) {
((JTree) e.getSource()).setCursor(new Cursor(Cursor.HAND_CURSOR));
} else {
((JTree) e.getSource()).setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
}
});
frame.add(panel);
panel.add(tree);
frame.setSize(new Dimension(200, 200));
frame.setVisible(true);
}
public static DefaultMutableTreeNode buildTree() {
DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
DefaultMutableTreeNode subOne = new DefaultMutableTreeNode("Test1");
DefaultMutableTreeNode leafOne = new DefaultMutableTreeNode("Leaf");
DefaultMutableTreeNode subTwo = new DefaultMutableTreeNode("Test2");
subOne.add(leafOne); //Drop down button should detect hover over
root.add(subOne);
root.add(subTwo);
return root;
}
}
答案 0 :(得分:2)
这是为您提供的解决方案。由于必需的方法被声明为protected,因此我们需要进行反射以检查鼠标是否位于图标上。
import java.awt.Cursor;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.lang.reflect.Method;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.plaf.basic.BasicTreeUI;
import javax.swing.tree.TreePath;
public class TreeTest implements Runnable {
@Override
public void run() {
JTree tree = new JTree();
tree.addMouseMotionListener(new MouseMotionListener() {
@Override
public void mouseDragged(MouseEvent e) {
}
@Override
public void mouseMoved(MouseEvent e) {
JTree t = (JTree) e.getSource();
TreePath tp = t.getPathForLocation(e.getX(), e.getY());
if (tp != null) {
t.setCursor(new Cursor(Cursor.HAND_CURSOR));
} else {
boolean overIcon = false;
tp = t.getClosestPathForLocation(e.getX(), e.getY());
if (tp != null && t.getUI() instanceof BasicTreeUI) {
BasicTreeUI ui = (BasicTreeUI) tree.getUI();
if (isInExpandControl(ui, tp, e)) {
overIcon = true;
t.setCursor(new Cursor(Cursor.MOVE_CURSOR)); // set another cursor
}
}
if (!overIcon) {
t.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
}
}
});
JFrame frm = new JFrame("Tree test");
frm.add(new JScrollPane(tree));
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.pack();
frm.setLocationRelativeTo(null);
frm.setVisible(true);
}
private boolean isInExpandControl(BasicTreeUI ui, TreePath tp, MouseEvent evt) {
try {
Method m = BasicTreeUI.class.getDeclaredMethod("isLocationInExpandControl", TreePath.class, int.class, int.class);
m.setAccessible(true);
return Boolean.TRUE.equals(m.invoke(ui, tp, evt.getX(), evt.getY()));
} catch (Exception e) {
return false;
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new TreeTest());
}
}