Java JTree节点是可点击的URL链接

时间:2017-05-30 16:51:18

标签: java jtree

我正在尝试将节点设为可点击的网址,但我似乎无法弄清楚如何。

我搜索过高低,我似乎无法找到解决方案。

这是我的代码:

public class NyttigeLinks {

    private static JFrame nyttigeLinks;

    public static void main(String[] args) {

                    initialize();
            }

    public NyttigeLinks() {

    }

    private static void initialize() {
        nyttigeLinks = new JFrame();
        nyttigeLinks.setBounds(new Rectangle(0, 0, 350, 650));
        nyttigeLinks.getContentPane().setBounds(new Rectangle(0, 0, 350, 650));
        nyttigeLinks.getContentPane().setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
        nyttigeLinks.getContentPane().setLayout(null);

        JLabel logoLabel = new JLabel("");
        logoLabel.setIcon(new ImageIcon(NyttigeLinks.class.getResource("/images/ssiLogo.jpg")));
        logoLabel.setBounds(0, 0, 350, 60);

        JTree tree = new JTree();

        nyttigeLinks.getContentPane().add(logoLabel);

        JScrollPane scrollPane = new JScrollPane(tree);
        scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        scrollPane.setBounds(10, 71, 324, 508);
        nyttigeLinks.getContentPane().add(scrollPane);

        tree.setModel(new DefaultTreeModel(
            new DefaultMutableTreeNode("Nyttige Links\t") {
                {
                    DefaultMutableTreeNode node_1;
                    node_1 = new DefaultMutableTreeNode("Projekt Wiki");
                        node_1.add(new DefaultMutableTreeNode("AO"));
                        node_1.add(new DefaultMutableTreeNode("Attends"));
                        node_1.add(new DefaultMutableTreeNode("Carlsberg"));
                        node_1.add(new DefaultMutableTreeNode("COOP"));
                        node_1.add(new DefaultMutableTreeNode("Dafgaard"));
                        node_1.add(new DefaultMutableTreeNode("Jysk DK"));
                        node_1.add(new DefaultMutableTreeNode("Jysk SE"));
                        node_1.add(new DefaultMutableTreeNode("Kvadrat"));
                        node_1.add(new DefaultMutableTreeNode("Solar"));
                        node_1.add(new DefaultMutableTreeNode("Stockmann"));
                        node_1.add(new DefaultMutableTreeNode("Tine"));
                        node_1.add(new DefaultMutableTreeNode("Unicef"));
                        node_1.add(new DefaultMutableTreeNode("Vectura"));
                    add(node_1);
                    node_1 = new DefaultMutableTreeNode("Helpdesk Norcic");
                        node_1.add(new DefaultMutableTreeNode("Test"));
                    add(node_1);
                    node_1 = new DefaultMutableTreeNode("Test");
                        node_1.add(new DefaultMutableTreeNode("AO"));
                        node_1.add(new DefaultMutableTreeNode("Attends"));
                        node_1.add(new DefaultMutableTreeNode("Carlsberg"));
                        node_1.add(new DefaultMutableTreeNode("COOP"));
                        node_1.add(new DefaultMutableTreeNode("Dafgaard"));
                        node_1.add(new DefaultMutableTreeNode("Jysk DK"));
                        node_1.add(new DefaultMutableTreeNode("Jysk SE"));
                        node_1.add(new DefaultMutableTreeNode("Kvadrat"));
                        node_1.add(new DefaultMutableTreeNode("Solar"));
                        node_1.add(new DefaultMutableTreeNode("Stockmann"));
                        node_1.add(new DefaultMutableTreeNode("Tine"));
                        node_1.add(new DefaultMutableTreeNode("Unicef"));
                        node_1.add(new DefaultMutableTreeNode("VecturaAO"));
                        node_1.add(new DefaultMutableTreeNode("Attends"));
                        node_1.add(new DefaultMutableTreeNode("Carlsberg"));
                        node_1.add(new DefaultMutableTreeNode("COOP"));
                        node_1.add(new DefaultMutableTreeNode("Dafgaard"));
                        node_1.add(new DefaultMutableTreeNode("Jysk DK"));
                        node_1.add(new DefaultMutableTreeNode("Jysk SE"));
                        node_1.add(new DefaultMutableTreeNode("Kvadrat"));
                        node_1.add(new DefaultMutableTreeNode("Solar"));
                        node_1.add(new DefaultMutableTreeNode("Stockmann"));
                        node_1.add(new DefaultMutableTreeNode("Tine"));
                        node_1.add(new DefaultMutableTreeNode("Unicef"));
                        node_1.add(new DefaultMutableTreeNode("VecturaAO"));
                        node_1.add(new DefaultMutableTreeNode("Attends"));
                        node_1.add(new DefaultMutableTreeNode("Carlsberg"));
                        node_1.add(new DefaultMutableTreeNode("COOP"));
                        node_1.add(new DefaultMutableTreeNode("Dafgaard"));
                        node_1.add(new DefaultMutableTreeNode("Jysk DK"));
                        node_1.add(new DefaultMutableTreeNode("Jysk SE"));
                        node_1.add(new DefaultMutableTreeNode("Kvadrat"));
                        node_1.add(new DefaultMutableTreeNode("Solar"));
                        node_1.add(new DefaultMutableTreeNode("Stockmann"));
                        node_1.add(new DefaultMutableTreeNode("Tine"));
                        node_1.add(new DefaultMutableTreeNode("Unicef"));
                        node_1.add(new DefaultMutableTreeNode("Vectura"));
                    add(node_1);
                }
            }
        ));
        tree.setBounds(10, 71, 324, 540);
        tree.setRootVisible(false);

        JLabel bottomLabelTop = new JLabel("                   Nyttige Links Version 1.0");
        bottomLabelTop.setBounds(0, 590, 230, 14);
        nyttigeLinks.getContentPane().add(bottomLabelTop);

        JLabel bottomLabelBot = new JLabel("                              Made by xxx");
        bottomLabelBot.setBounds(0, 605, 230, 15);
        nyttigeLinks.getContentPane().add(bottomLabelBot);

        JButton btnNewButton = new JButton("Admin");
        btnNewButton.setIcon(new ImageIcon(NyttigeLinks.class.getResource("/images/appIcon.ico")));
        btnNewButton.setBounds(240, 590, 80, 20);
        nyttigeLinks.getContentPane().add(btnNewButton);
        nyttigeLinks.setPreferredSize(new Dimension(350, 650));
        nyttigeLinks.setSize(new Dimension(350, 650));
        nyttigeLinks.setResizable(false);
        nyttigeLinks.setTitle("Nyttige Links");
        nyttigeLinks.setIconImage(Toolkit.getDefaultToolkit().getImage(NyttigeLinks.class.getResource("/images/appIcon.ico")));
        nyttigeLinks.setBackground(Color.YELLOW);
        nyttigeLinks.setBounds(100, 100, 350, 650);
        nyttigeLinks.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        nyttigeLinks.setVisible(true);
    }
}

我为一个菜鸟道歉,但你必须从某个地方开始,对吗?

如果有人能指出我正确的方向,我会非常感激!大家晚安!

2 个答案:

答案 0 :(得分:2)

我不相信有办法让节点本身成为一个URL。但是,您可以通过在单击节点时使用侦听器打开浏览器来完成相同的操作。要打开浏览器,您可以使用Desktop#browse(URI)方法。

关于点击主题,我建议不要在单击节点时打开URL。对于非常烦人的用户(IMO)。相反,我建议使用双击。 This answer提供了区分单击和双击以及如何将其添加到Tree的好方法。

  

[...]但你必须从某个地方开始,对吧?

完全!请允许我在此提供更多细节,希望对学习更多有所帮助。

您将面临的一个挑战是如何知道为给定节点打开哪个URL。目前您只知道显示的String,我认为您可以安全地假设您不希望为每个节点显示完整的URL。我建议创建一个对象以传入DefaultMutableTreeNode构造函数,而不是使用String参数创建DefaultMutableTreeNode个对象。此对象还可以具有URI属性,以便它知道要打开的URL。

例如:

public class LeafNodeObject {
    private final URI uri;

    public LeafNodeObject(final String display, final URI uri) {
        this.display = display;
        this.uri = uri;
    }

    /**
     * Override so that we control what is display on the Node
     */
    @Override
    public String toString() {
        return display;
    }

    public void onDoubleClick() {
        try {
            Desktop.getDesktop().browse(uri);
        } catch (final IOException e) {
            e.printStackTrace();
        }
    }

}

可以像这样添加节点:

node_1.add(new DefaultMutableTreeNode(new LeafNodeObject("Test", new URI("www.eclipse.org"))));

在我们的听众中(从上面的链接略微修改):

final MouseListener ml = new MouseAdapter() {
    public void mousePressed(final MouseEvent e) {
        final int selRow = tree.getRowForLocation(e.getX(), e.getY());
        final TreePath selPath = tree.getPathForLocation(e.getX(), e.getY());
        if (selRow != -1) {
            final DefaultMutableTreeNode node = (DefaultMutableTreeNode) selPath.getLastPathComponent();
            if (e.getClickCount() == 1) {
                // Single click
            } else if (e.getClickCount() == 2) {
                // Double click
                ((LeafNodeObject) node.getUserObject()).onDoubleClick();
            }
        }
    }
};

现在,当有双击事件时,我们会在我们创建的onDoubleClick()上调用LeafNodeObject方法。

这看起来很棒,除了我们将遇到非叶节点节点的类转换问题!为了解决这个问题,我们可以为这些节点创建一个类似的类(例如ParentNodeObject)。为了良好的OOP,我们应该认识到这两个类的共同行为(onDoubleClick(),还有onSingleClick()),并为共享能力创建一个接口。

例如:

public interface NodeObject {
    public void onSingleClick();
    public void onDoubleClick();
}

现在我们可以让我们的两个类实现这个接口:

public class ParentNodeObject implements NodeObject {
    private final String display;

    public ParentNodeObject(final String display) {
        this.display = display;
    }

    /**
     * Override so that we control what is display on the Node
     */
    @Override
    public String toString() {
        return display;
    }

    @Override
    public void onSingleClick() {
        // Do nothing
    }

    @Override
    public void onDoubleClick() {
        // Do nothing
    }
}

public class LeafNodeObject implements NodeObject {
    private final URI uri;

    public LeafNodeObject(final String display, final URI uri) {
        this.display = display;
        this.uri = uri;
    }

    /**
     * Override so that we control what is display on the Node
     */
    @Override
    public String toString() {
        return display;
    }

    @Override
    public void onSingleClick() {
        // Do nothing
    }

    @Override
    public void onDoubleClick() {
        try {
            Desktop.getDesktop().browse(uri);
        } catch (final IOException e) {
            e.printStackTrace();
        }
    }

}

因此,在我们的监听器中,我们不再需要知道(并且不再关心)该节点是父节点还是叶节点。我们可以简单地调用onSingleClick()onDoubleClick(),然后实现处理其余部分!

if (e.getClickCount() == 1) {
    // Single click
    ((NodeObject) node.getUserObject()).onSingleClick();
} else if (e.getClickCount() == 2) {
    // Double click
    ((NodeObject) node.getUserObject()).onDoubleClick();
}

回到代码中,可以像这样添加父节点和子节点:

node_1 = new DefaultMutableTreeNode(new ParentNodeObject("Helpdesk Norcic"));
node_1.add(new DefaultMutableTreeNode(new LeafNodeObject("Test", new URI("www.eclipse.org"))));

现在,当您单击或双击任何节点时,也会调用onSingleClick()onDoubleClick()方法。在这种情况下,我们只关心在叶节点上双击时会发生什么,所以我们只需要填写该方法。

答案 1 :(得分:0)

虽然我没有检查上面提到的代码,但是在我等待回复此帖子时,我是如何解决这个问题的:

class SelectionListener implements TreeSelectionListener {

    public void valueChanged(TreeSelectionEvent se) {
        JTree tree = (JTree) se.getSource();
        DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
        String selectedNodeName = selectedNode.toString();
        if (selectedNode.isLeaf()) {
            if (selectedNodeName == "Unicef") {
                try {
                    java.awt.Desktop.getDesktop().browse(java.net.URI.create("http://www.eb.dk"));
                } catch (IOException e1) {
                    // make a error pop up appear here
                    JOptionPane.showMessageDialog(null, "Something went wrong, please report this to the developer!", "Something went wrong", 0);
                    e1.printStackTrace();

                }
            }

            if (selectedNodeName == "Vectura") {
                try {
                    java.awt.Desktop.getDesktop().browse(java.net.URI.create("http://www.google.com"));
                } catch (IOException e1) {
                    // make a error pop up appear here
                    JOptionPane.showMessageDialog(null, "Something went wrong, please report this to the developer!", "Something went wrong", 0);
                    e1.printStackTrace();

                }
            }

        }

    }
}

这绝对不是一种很好的方式,因为它会导致很多if语句,但这对我来说很容易理解。