在Java上的JTree行上呈现的按钮上的MouseListener

时间:2013-05-30 07:07:16

标签: java swing jbutton jtree mouselistener

我遇到了关于Java和使用JTree的问题:

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

enter image description here

但我被阻止的地方是我想在每个按钮上添加一个mouselistener来管理他们的工具提示或对它们采取行动。 事实上,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位置,但在渲染后我无法找到按钮的位置。

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

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

1 个答案:

答案 0 :(得分:2)

工具提示支持实际上是由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;
    }
}

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

渲染器是橡皮图章。这实际上不是生命的组成部分。把它们想象成照片。你可以快照一下你的朋友,但是你无法与他们互动......同样的事情......

您对MouseListener JTree的想法是正确的,事实上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);
        }
    }
}