如何在JLabel中添加超链接
在jLabel中添加超链接的最佳方法是什么? 我可以使用html标签获取视图,但是当用户点击它时如何打开浏览器?
你可以使用JLabel
来做到这一点,但另一种方法是devise一个JButton
。 这样,您不必担心可访问性 ,只需使用ActionListener
触发事件即可。
public static void main(String[] args) throws URISyntaxException { final URI uri = new URI("http://java.sun.com"); class OpenUrlAction implements ActionListener { @Override public void actionPerformed(ActionEvent e) { open(uri); } } JFrame frame = new JFrame("Links"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(100, 400); Container container = frame.getContentPane(); container.setLayout(new GridBagLayout()); JButton button = new JButton(); button.setText("<HTML>Click the <FONT color=\"#000099\"><U>link</U></FONT>" + " to go to the Java website.</HTML>"); button.setHorizontalAlignment(SwingConstants.LEFT); button.setBorderPainted(false); button.setOpaque(false); button.setBackground(Color.WHITE); button.setToolTipText(uri.toString()); button.addActionListener(new OpenUrlAction()); container.add(button); frame.setVisible(true); } private static void open(URI uri) { if (Desktop.isDesktopSupported()) { try { Desktop.getDesktop().browse(uri); } catch (IOException e) { /* TODO: error handling */ } } else { /* TODO: error handling */ } }
我想提供另一个解决scheme。 它与已经提出的类似,因为它使用JLabel中的HTML代码,并且在其上注册了一个MouseListener,但是当您将鼠标移动到链接上时,它也显示一个HandCursor,所以外观与大多数用户所期望的一样。 如果平台不支持浏览,则不会创build蓝色,带下划线的HTML链接,这可能会误导用户。 相反,链接只是以纯文本forms呈现。 这可以和@ dimo414提出的SwingLink类相结合。
public class JLabelLink extends JFrame { private static final String LABEL_TEXT = "For further information visit:"; private static final String A_VALID_LINK = "http://stackoverflow.com"; private static final String A_HREF = "<a href=\""; private static final String HREF_CLOSED = "\">"; private static final String HREF_END = "</a>"; private static final String HTML = "<html>"; private static final String HTML_END = "</html>"; public JLabelLink() { setTitle("HTML link via a JLabel"); setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); Container contentPane = getContentPane(); contentPane.setLayout(new FlowLayout(FlowLayout.LEFT)); JLabel label = new JLabel(LABEL_TEXT); contentPane.add(label); label = new JLabel(A_VALID_LINK); contentPane.add(label); if (isBrowsingSupported()) { makeLinkable(label, new LinkMouseListener()); } pack(); } private static void makeLinkable(JLabel c, MouseListener ml) { assert ml != null; c.setText(htmlIfy(linkIfy(c.getText()))); c.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); c.addMouseListener(ml); } private static boolean isBrowsingSupported() { if (!Desktop.isDesktopSupported()) { return false; } boolean result = false; Desktop desktop = java.awt.Desktop.getDesktop(); if (desktop.isSupported(Desktop.Action.BROWSE)) { result = true; } return result; } private static class LinkMouseListener extends MouseAdapter { @Override public void mouseClicked(java.awt.event.MouseEvent evt) { JLabel l = (JLabel) evt.getSource(); try { URI uri = new java.net.URI(JLabelLink.getPlainLink(l.getText())); (new LinkRunner(uri)).execute(); } catch (URISyntaxException use) { throw new AssertionError(use + ": " + l.getText()); //NOI18N } } } private static class LinkRunner extends SwingWorker<Void, Void> { private final URI uri; private LinkRunner(URI u) { if (u == null) { throw new NullPointerException(); } uri = u; } @Override protected Void doInBackground() throws Exception { Desktop desktop = java.awt.Desktop.getDesktop(); desktop.browse(uri); return null; } @Override protected void done() { try { get(); } catch (ExecutionException ee) { handleException(uri, ee); } catch (InterruptedException ie) { handleException(uri, ie); } } private static void handleException(URI u, Exception e) { JOptionPane.showMessageDialog(null, "Sorry, a problem occurred while trying to open this link in your system's standard browser.", "A problem occured", JOptionPane.ERROR_MESSAGE); } } private static String getPlainLink(String s) { return s.substring(s.indexOf(A_HREF) + A_HREF.length(), s.indexOf(HREF_CLOSED)); } //WARNING //This method requires that s is a plain string that requires //no further escaping private static String linkIfy(String s) { return A_HREF.concat(s).concat(HREF_CLOSED).concat(s).concat(HREF_END); } //WARNING //This method requires that s is a plain string that requires //no further escaping private static String htmlIfy(String s) { return HTML.concat(s).concat(HTML_END); } /** * @param args the command line arguments */ public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new JLabelLink().setVisible(true); } }); } }
我写了一篇关于如何在jLabel上设置超链接或mailto的文章。
所以试试吧 :
我想这正是你正在寻找的。
以下是完整的代码示例:
/** * Example of a jLabel Hyperlink and a jLabel Mailto */ import java.awt.Cursor; import java.awt.Desktop; import java.awt.EventQueue; 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.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; /** * * @author ibrabelware */ public class JLabelLink extends JFrame { private JPanel pan; private JLabel contact; private JLabel website; /** * Creates new form JLabelLink */ public JLabelLink() { this.setTitle("jLabelLinkExample"); this.setSize(300, 100); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setLocationRelativeTo(null); pan = new JPanel(); contact = new JLabel(); website = new JLabel(); contact.setText("<html> contact : <a href=\"\">YourEmailAddress@gmail.com</a></html>"); contact.setCursor(new Cursor(Cursor.HAND_CURSOR)); website.setText("<html> Website : <a href=\"\">http://www.google.com/</a></html>"); website.setCursor(new Cursor(Cursor.HAND_CURSOR)); pan.add(contact); pan.add(website); this.setContentPane(pan); this.setVisible(true); sendMail(contact); goWebsite(website); } /** * @param args the command line arguments */ public static void main(String args[]) { /* * Create and display the form */ EventQueue.invokeLater(new Runnable() { @Override public void run() { new JLabelLink().setVisible(true); } }); } private void goWebsite(JLabel website) { website.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { try { Desktop.getDesktop().browse(new URI("http://www.google.com/webhp?nomo=1&hl=fr")); } catch (URISyntaxException | IOException ex) { //It looks like there's a problem } } }); } private void sendMail(JLabel contact) { contact.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { try { Desktop.getDesktop().mail(new URI("mailto:YourEmailAddress@gmail.com?subject=TEST")); } catch (URISyntaxException | IOException ex) { //It looks like there's a problem } } }); } }
也许使用SwingX的 JXHyperlink
。 它扩展JButton
。 一些有用的链接:
- JXHyperlink类
- SwingX:考虑JXHyperlink作为替代button
更新我已经整理了SwingLink
类并添加了更多的function; 一个最新的副本可以在这里find: https : //bitbucket.org/dimo414/jgrep/src/tip/src/grep/SwingLink.java
@麦克道威尔的答案很好,但有几件事情可以改进。 值得注意的是超链接以外的其他文本是可点击的,并且它仍然看起来像一个button,即使一些样式已经被改变/隐藏。 虽然可访问性很重要,但一个连贯的用户界面也是如此。
所以我把基于McDowell代码的JLabel类放在一起。 它是自包含的,正确处理错误,感觉更像是一个链接:
public class SwingLink extends JLabel { private static final long serialVersionUID = 8273875024682878518L; private String text; private URI uri; public SwingLink(String text, URI uri){ super(); setup(text,uri); } public SwingLink(String text, String uri){ super(); setup(text,URI.create(uri)); } public void setup(String t, URI u){ text = t; uri = u; setText(text); setToolTipText(uri.toString()); addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { open(uri); } public void mouseEntered(MouseEvent e) { setText(text,false); } public void mouseExited(MouseEvent e) { setText(text,true); } }); } @Override public void setText(String text){ setText(text,true); } public void setText(String text, boolean ul){ String link = ul ? "<u>"+text+"</u>" : text; super.setText("<html><span style=\"color: #000099;\">"+ link+"</span></html>"); this.text = text; } public String getRawText(){ return text; } private static void open(URI uri) { if (Desktop.isDesktopSupported()) { Desktop desktop = Desktop.getDesktop(); try { desktop.browse(uri); } catch (IOException e) { JOptionPane.showMessageDialog(null, "Failed to launch the link, your computer is likely misconfigured.", "Cannot Launch Link",JOptionPane.WARNING_MESSAGE); } } else { JOptionPane.showMessageDialog(null, "Java is not able to launch links on your computer.", "Cannot Launch Link", JOptionPane.WARNING_MESSAGE); } } }
例如,您也可以在点击后将链接颜色更改为紫色,如果这看起来很有用。 这是完全自足的,你只需要打电话:
SwingLink link = new SwingLink("Java", "http://java.sun.com"); mainPanel.add(link);
您可以尝试使用JEditorPane而不是JLabel。 这理解了基本的HTML,并将HyperlinkEvent事件发送到您在JEditPane中注册的HyperlinkListener。
如果<a href="link">不起作用,那么:
- 创build一个JLabel并添加一个MouseListener(装饰标签看起来像一个超链接)
- 实现mouseClicked()事件
- 在mouseClicked()事件的执行中,执行你的动作
查看使用默认浏览器打开链接的java.awt.Desktop API(此API仅可从Java6获得)。
我知道我晚了些,但是我做了一些别人可能觉得很酷/有用的方法。
public static JLabel linkify(final String text, String URL, String toolTip) { URI temp = null; try { temp = new URI(URL); } catch (Exception e) { e.printStackTrace(); } final URI uri = temp; final JLabel link = new JLabel(); link.setText("<HTML><FONT color=\"#000099\">"+text+"</FONT></HTML>"); if(!toolTip.equals("")) link.setToolTipText(toolTip); link.setCursor(new Cursor(Cursor.HAND_CURSOR)); link.addMouseListener(new MouseListener() { public void mouseExited(MouseEvent arg0) { link.setText("<HTML><FONT color=\"#000099\">"+text+"</FONT></HTML>"); } public void mouseEntered(MouseEvent arg0) { link.setText("<HTML><FONT color=\"#000099\"><U>"+text+"</U></FONT></HTML>"); } public void mouseClicked(MouseEvent arg0) { if (Desktop.isDesktopSupported()) { try { Desktop.getDesktop().browse(uri); } catch (Exception e) { e.printStackTrace(); } } else { JOptionPane pane = new JOptionPane("Could not open link."); JDialog dialog = pane.createDialog(new JFrame(), ""); dialog.setVisible(true); } } public void mousePressed(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } }); return link; }
它会给你一个JLabel,就像一个适当的链接。
在行动:
public static void main(String[] args) { JFrame frame = new JFrame("Linkify Test"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(400, 100); frame.setLocationRelativeTo(null); Container container = frame.getContentPane(); container.setLayout(new GridBagLayout()); container.add(new JLabel("Click ")); container.add(linkify("this", "http://facebook.com", "Facebook")); container.add(new JLabel(" link to open Facebook.")); frame.setVisible(true); }
如果你不想提示工具提示空白。
希望有人认为这有用! (如果你这样做,一定要让我知道,我很乐意听到。)
使用带有HyperlinkListener
的JEditorPane
。
只要把window.open(website url)
,它每次都有效。
以下代码需要将JHyperLink
添加到您的构buildpath中。
JHyperlink stackOverflow = new JHyperlink("Click HERE!", "https://www.stackoverflow.com/"); JComponent[] messageComponents = new JComponent[] { stackOverflow }; JOptionPane.showMessageDialog(null, messageComponents, "StackOverflow", JOptionPane.PLAIN_MESSAGE);
请注意,您可以使用更多的Swing
组件来填充JComponent
数组。
结果:
你可以在下使用这个
actionListener -> Runtime.getRuntime().exec("cmd.exe /c start chrome www.google.com")`
或者如果您想使用Internet Explorer或Firefox,请使用iexplore
或firefox
replacechrome