有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java将鼠标光标悬停在JTree中的节点上

我正在创建一个JTree,并添加一些节点,如下所示:

DefaultMutableTreeNode top = new DefaultMutableTreeNode("The Java Series");
tree = new JTree(top);
...
DefaultMutableTreeNode node = new DefaultMutableTreeNode("<html><a href=\"    \">"+code+"</a>  "+description+"</html>");
top.add(node);
...

现在我在节点中添加了一个“addMouseMotionListener”,这样就可以了。我的问题是,每当我将鼠标光标悬停在节点的任何部分上时,鼠标光标都会发生变化。我真正想要的是,只在鼠标悬停在节点的HTML超链接文本部分时更改鼠标光标

 "<a href=\"\">"+code+"</a>"

而不是描述

那么,有没有一种方法可以使鼠标光标仅在鼠标悬停在节点的某些部分时发生变化

提前谢谢


共 (2) 个答案

  1. # 1 楼答案

    该代码适用于:

        tree_object.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));
                    }
                }
         });
    
  2. # 2 楼答案

    好吧,我花了一段时间,但我在评论中描述的似乎奏效了。也许还有其他更好的方法,我很想读一读,但到目前为止,我只找到了这些

    这个想法是:

    1. 我用一个绝地窗格作为树的渲染器
    2. 我听鼠标移动(还有,作为鼠标点击的奖励)
    3. 对于每个事件,我都会为悬停的单元格重新创建渲染器
    4. 我将事件转换为组件坐标
    5. 我使用viewToModel查找是否悬停在锚元素上
    6. 我相应地更改光标

    这是代码,作为奖励,你还可以获得工作超链接

    import java.awt.BorderLayout;
    import java.awt.Component;
    import java.awt.Cursor;
    import java.awt.Desktop;
    import java.awt.Point;
    import java.awt.Rectangle;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.io.IOException;
    import java.net.URI;
    import java.net.URISyntaxException;
    
    import javax.swing.JEditorPane;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JScrollPane;
    import javax.swing.JTree;
    import javax.swing.SwingUtilities;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    import javax.swing.text.AttributeSet;
    import javax.swing.text.Element;
    import javax.swing.text.html.HTML;
    import javax.swing.text.html.HTMLDocument;
    import javax.swing.tree.DefaultMutableTreeNode;
    import javax.swing.tree.DefaultTreeCellRenderer;
    import javax.swing.tree.DefaultTreeModel;
    import javax.swing.tree.TreeCellRenderer;
    import javax.swing.tree.TreeModel;
    import javax.swing.tree.TreeNode;
    import javax.swing.tree.TreePath;
    
    public class TestTreeHyperlinks {
    
        private final class HyperlinkMouseListener extends MouseAdapter {
            private final JTree tree;
    
            private HyperlinkMouseListener(JTree tree) {
                this.tree = tree;
            }
    
            @Override
            public void mouseExited(MouseEvent e) {
                tree.setCursor(Cursor.getDefaultCursor());
            }
    
            @Override
            public void mouseClicked(MouseEvent e) {
                Element h = getHyperlinkElement(e);
                if (h != null) {
                    Object attribute = h.getAttributes().getAttribute(HTML.Tag.A);
                    if (attribute instanceof AttributeSet) {
                        AttributeSet set = (AttributeSet) attribute;
                        String href = (String) set.getAttribute(HTML.Attribute.HREF);
                        if (href != null) {
                            try {
                                Desktop.getDesktop().browse(new URI(href));
                            } catch (IOException e1) {
                                e1.printStackTrace();
                            } catch (URISyntaxException e1) {
                                e1.printStackTrace();
                            }
                        }
                    }
                }
            }
    
            @Override
            public void mouseMoved(MouseEvent event) {
                boolean isHyperlink = isHyperlink(event);
                if (isHyperlink) {
                    tree.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
                } else {
                    tree.setCursor(Cursor.getDefaultCursor());
                }
    
            }
    
            private boolean isHyperlink(MouseEvent event) {
                return getHyperlinkElement(event) != null;
            }
    
            private Element getHyperlinkElement(MouseEvent event) {
                Point p = event.getPoint();
                int selRow = tree.getRowForLocation(p.x, p.y);
                TreeCellRenderer r = tree.getCellRenderer();
                if (selRow != -1 && r != null) {
                    TreePath path = tree.getPathForRow(selRow);
                    Object lastPath = path.getLastPathComponent();
                    Component rComponent = r.getTreeCellRendererComponent(tree, lastPath, tree.isRowSelected(selRow), tree.isExpanded(selRow),
                            tree.getModel().isLeaf(lastPath), selRow, true);
                    if (rComponent instanceof JEditorPane) {
                        Rectangle pathBounds = tree.getPathBounds(path);
                        JEditorPane editor = (JEditorPane) rComponent;
                        editor.setBounds(tree.getRowBounds(selRow));
                        p.translate(-pathBounds.x, -pathBounds.y);
                        int pos = editor.getUI().viewToModel(editor, p);
                        if (pos >= 0 && editor.getDocument() instanceof HTMLDocument) {
                            HTMLDocument hdoc = (HTMLDocument) editor.getDocument();
                            Element elem = hdoc.getCharacterElement(pos);
                            if (elem.getAttributes().getAttribute(HTML.Tag.A) != null) {
                                return elem;
                            }
                        }
                    }
                }
                return null;
            }
        }
    
        @SuppressWarnings("serial")
        public class MyTreeCellRenderer extends DefaultTreeCellRenderer implements TreeCellRenderer {
    
            private JEditorPane editorPane;
    
            public MyTreeCellRenderer() {
                editorPane = new JEditorPane("text/html", null);
            }
    
            @Override
            public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row,
                    boolean hasFocus) {
                Component c = super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
                if (c instanceof JLabel) {
                    JLabel label = (JLabel) c;
                    editorPane.setText(label.getText());
                    editorPane.setToolTipText(label.getToolTipText());
                    editorPane.setOpaque(label.isOpaque());
                    editorPane.setBackground(label.getBackground());
                    editorPane.setBorder(label.getBorder());
                }
                return editorPane;
            }
        }
    
        protected void initUI() {
            final JTree tree = new JTree(getTreeModel());
            tree.setCellRenderer(new MyTreeCellRenderer());
            HyperlinkMouseListener listener = new HyperlinkMouseListener(tree);
            tree.addMouseListener(listener);
            tree.addMouseMotionListener(listener);
            JFrame f = new JFrame(TestTreeHyperlinks.class.getSimpleName());
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.add(new JScrollPane(tree), BorderLayout.CENTER);
            f.pack();
            f.setSize(f.getWidth() + 100, f.getHeight() + 100);
            f.setVisible(true);
    
        }
    
        private TreeModel getTreeModel() {
            return new DefaultTreeModel(
                    getNodes(new DefaultMutableTreeNode("<html>Root <a href=\"http://www.google.be\">Google</a></html>"), 5));
        }
    
        private TreeNode getNodes(DefaultMutableTreeNode parent, int i) {
            if (i > 0) {
                for (int j = 0; j < 5; j++) {
                    DefaultMutableTreeNode newChild = new DefaultMutableTreeNode(
                            "<html>Node "
                                    + (j + 1)
                                    + " <a href=\"http://www.stackoverflow.com\">a link to stackoverflow</a></html> and some more text not in an hyperlink");
                    getNodes(newChild, i - 1);
                    parent.add(newChild);
                }
            }
            return parent;
        }
    
        public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
                UnsupportedLookAndFeelException {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            SwingUtilities.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    new TestTreeHyperlinks().initUI();
                }
            });
        }
    
    }