java - Java 中 JTree 行上呈现的按钮上的 MouseListener

标签 java swing jbutton jtree mouselistener

我被关于 Java 和 JTree 的使用的问题所困扰:

我想用一些 JButtons 组件(或图像,我不介意)逐个节点地创建一个 JTree,如下图所示。同一行将有 3 个或 4 个按钮。我成功地做到了。

enter image description here

但是我被阻止的地方是当我想在每个按钮上添加一个鼠标监听器来管理它们的工具提示或对它们的操作时。 事实上,JTree 组件大部分时间用于管理全节点上的操作,而不是其内部组件。

我做了一个简短的代码,与我必须使用的真正的大代码进行比较,以快速测试我所说的内容:

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.tree.*;

import java.awt.event.*;
import java.awt.*;
import java.io.IOException;
import java.net.URL;

public class TreeWithPopup extends JPanel {

    DefaultMutableTreeNode root, node1, node2, node3;

    public TreeWithPopup() {
        MyJTree tree;
        root = new DefaultMutableTreeNode("root", true);
        node1 = new DefaultMutableTreeNode("node 1", true);
        node2 = new DefaultMutableTreeNode("node 2", true);
        node3 = new DefaultMutableTreeNode("node 3", true);
        root.add(node1);
        node1.add(node2);
        root.add(node3);
        setLayout(new BorderLayout());
        tree = new MyJTree(root);
        tree.setCellRenderer(new PCellRenderer());
        add(new JScrollPane((JTree) tree), "Center");
    }

    public Dimension getPreferredSize() {
        return new Dimension(300, 300);
    }

    public static void main(String s[]) {
        JFrame frame = new JFrame("Tree with button");
        TreeWithPopup panel = new TreeWithPopup();
        frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        frame.setForeground(Color.black);
        frame.setBackground(Color.lightGray);
        frame.getContentPane().add(panel, "Center");
        frame.setSize(panel.getPreferredSize());
        frame.setVisible(true);
        frame.addWindowListener(new WindowCloser());
    }
}

class WindowCloser extends WindowAdapter {
    public void windowClosing(WindowEvent e) {
        Window win = e.getWindow();
        win.setVisible(false);
        System.exit(0);
    }
}

class MyJTree extends JTree implements ActionListener {

    MyJTree(DefaultMutableTreeNode dmtn) {
        super(dmtn);
        addMouseListener(new MouseListener() {
            public void mouseClicked(MouseEvent arg0) {
                System.out.println("JTree.MouseListener");
            }

            public void mouseEntered(MouseEvent arg0) {
                System.out.println("JTree.MouseListener");
            }

            public void mouseExited(MouseEvent arg0) {
                System.out.println("JTree.MouseListener");
            }

            public void mousePressed(MouseEvent arg0) {
                System.out.println("JTree.MouseListener");
            }

            public void mouseReleased(MouseEvent arg0) {
                System.out.println("JTree.MouseListener");
            }
        });

    }

    public void actionPerformed(ActionEvent ae) {
        System.out.println("MyJTree.ActionPerformed");
    }

}

class PCellRenderer extends DefaultTreeCellRenderer {
    public Component getTreeCellRendererComponent(JTree ptree, Object pvalue, boolean psel, boolean pexpanded, boolean pleaf, int prow,
            boolean phasFocus) {
        Box myPanel = new Box(BoxLayout.X_AXIS);

        JButton myButton = new JButton("test");
        Image imgToUse = null;
        Image imgRollOver = null;
        try {
            URL urlIcon = new URL("file:///C:/1.jpg"); // <===== change their the path to icons
            imgToUse = ImageIO.read(urlIcon);
            urlIcon = new URL("file:///C:/2.jpg"); // <===== change their the path to icons
            imgRollOver = ImageIO.read(urlIcon);
        } catch (IOException e) {
            e.printStackTrace();
        }
        myButton.setRolloverIcon(new ImageIcon(imgRollOver));
        myButton.setIcon(new ImageIcon(imgToUse));
        myButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                System.out.println(" detected on ");
            }
        });

        myButton.addMouseListener(new MouseListener() {
            public void mouseClicked(MouseEvent arg0) {
                System.out.println("myButton.MouseListener");
            }

            public void mouseEntered(MouseEvent arg0) {
                System.out.println("myButton.MouseListener");
            }

            public void mouseExited(MouseEvent arg0) {
                System.out.println("myButton.MouseListener");
            }

            public void mousePressed(MouseEvent arg0) {
                System.out.println("myButton.MouseListener");
            }

            public void mouseReleased(MouseEvent arg0) {
                System.out.println("myButton.MouseListener");
            }
        });
        myPanel.add(myButton);

        return myPanel;
    }
}

你只需要更改图标路径或将以下两个图标放在“c:/”

enter image description here

enter image description here

我还搜索了使用行事件的 x/y 位置,但在渲染后我无法找到我的按钮的位置。

如果有人知道如何做到这一点,他会非常有帮助。

谢谢,至少阅读这个问题 ;-)

最佳答案

工具提示支持实际上是由 TableCellRenderer 直接提供的。您的 TableCellRenderer 有点困惑。它从 DefaultTreeCellRenderer 扩展而来,但不使用它的任何功能,而是创建一个新的 BoxJButton 并在每次单元格加载时加载图标呈现...

这会增加您的内存使用量并减慢您的应用程序...

相反,尝试类似...

class PCellRenderer extends Box implements TreeCellRenderer {

    private Image imgToUse = null;
    private Image imgRollOver = null;

    public PCellRenderer() {
        super(BoxLayout.X_AXIS);

        JButton myButton = new JButton("test");
        try {
            URL urlIcon = new URL("file:///C:/1.jpg"); // <===== change their the path to icons
            imgToUse = ImageIO.read(urlIcon);
            urlIcon = new URL("file:///C:/2.jpg"); // <===== change their the path to icons
            imgRollOver = ImageIO.read(urlIcon);
        } catch (IOException e) {
            e.printStackTrace();
        }
        myButton.setRolloverIcon(new ImageIcon(imgRollOver));
        myButton.setIcon(new ImageIcon(imgToUse));

        add(myButton);
    }

    public Component getTreeCellRendererComponent(JTree ptree, Object pvalue, boolean psel, boolean pexpanded, boolean pleaf, int prow,
            boolean phasFocus) {
        // set the tooltip text here...
        // Maybe change the icon...
        return this;
    }
}

现在,实际上正在做某事......

渲染器是橡皮图章。那实际上不是生命的组成部分。把它们想象成照片。你可以给你的 friend 拍一张快照,但你不能和他们互动……这里也是一样的……

您对 JTree 上的 MouseListener 的想法是正确的,实际上是 JavaDocs实际上有一个演示......

public void mousePressed(MouseEvent e) {
    int selRow = tree.getRowForLocation(e.getX(), e.getY());
    TreePath selPath = tree.getPathForLocation(e.getX(), e.getY());
    if(selRow != -1) {
        if(e.getClickCount() == 1) {
            mySingleClick(selRow, selPath);
        }
        else if(e.getClickCount() == 2) {
            myDoubleClick(selRow, selPath);
        }
    }
}

关于java - Java 中 JTree 行上呈现的按钮上的 MouseListener,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16829967/

相关文章:

java - 更改默认 "tab"操作(转移焦点)

java - Linux平台下按钮颜色问题

java.lang.LinkageError : loader constraint violation: loader (instance of org/apache/catalina/loader/WebappClassLoader) 错误

java - Gradle IntelliJ创意

java - Thread Busy apache tomcat解压数据

每次我停止点击时,Java 点击计数器都会重置

java - 如何在GIF动画背景上创建隐形按钮?

java - 如何设置 RTC 工作项的 "Found In"属性值?

java - JComponent - 设置透明背景

java - 当我按下几个 Jbuttons 时无法播放多个声音