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

问题描述:

我想让一个节点成为一个可点击的URL,但我似乎无法弄清楚如何。Java JTree节点是一个可点击的URL链接

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

这是我的代码:

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); 
    } 
} 

我为是有点小白的道歉,但你必须从某个地方开始,对不对?

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

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

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


[...]但你得开始的地方,对不对?

正是!请允许我在这里提供一些更详细的信息,希望对学习更多内容有所帮助。

您将面临的一个挑战是如何知道给定节点打开哪个URL。目前您只知道显示的String,我认为这是一个安全的假设,您不希望为每个节点显示完整的URL。我建议不要使用String参数创建DefaultMutableTreeNode对象,而是建议创建一个对象来代替传递给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 t我们创造的帽子。

这看起来不错,只是我们会遇到非叶节点节点的类转换问题!为了解决这个问题,我们可以为这些节点创建一个类似的类(例如,ParentNodeObject)。为了获得良好的面向对象,我们应该认识到这两个类的共同行为(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()方法也叫做。在这种情况下,我们只关心在叶节点上双击时发生的情况,所以我们只需要填写该方法。

+0

太棒了!非常感谢你的帮助。我明天早上下班的时候会考虑一下。我今晚没有时间了。非常感谢,我一定会更新这个主题。 – TheGreyNight

+0

@ TheGreyNight不客气!让我知道是否有任何不完整的意义或可以使用更好的解释。 – avojak

虽然我还没有检查上述代码,这里是我解决这个问题是怎么当我在等待此主题回复:

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语句,但它足够简单让我自己理解。