Cómo agregar un hipervínculo en JLabel

¿Cuál es la mejor manera de agregar un hipervínculo en jLabel? Puedo obtener la vista usando tags html, pero ¿cómo abrir el navegador cuando el usuario hace clic en él?

Puede hacer esto usando un JLabel , pero una alternativa sería JButton un JButton . De esta forma, no tiene que preocuparse por la accesibilidad y puede simplemente disparar eventos usando un 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("Click the https://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-jlabel/link" + " to go to the Java website."); 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 */ } } 

Me gustaría ofrecer otra solución. Es similar a los ya propuestos ya que usa código HTML en un JLabel y registra un MouseListener en él, pero también muestra un HandCursor cuando mueves el mouse sobre el enlace, por lo que el aspecto es exactamente como lo que la mayoría de los usuarios esperarían . Si la plataforma no admite la navegación, no se crea un enlace HTML azul subrayado que pueda engañar al usuario. En cambio, el enlace se acaba de presentar como texto sin formato. Esto podría combinarse con la clase SwingLink propuesta por @ dimo414.

 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 = ""; private static final String HREF_END = ""; private static final String HTML = ""; private static final String HTML_END = ""; public JLabelLink() { setTitle("HTML https://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-jlabel/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(https://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-jlabel/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 { 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 https://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-jlabel/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 https://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-jlabel/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); } }); } } 

Escribí un artículo sobre cómo configurar un hipervínculo o un mailto en jLabel.

Así que inténtalo:

Creo que eso es exactamente lo que estás buscando.

Aquí está el ejemplo completo del código:

 /** * Example of a jLabel Hyperhttps://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-jlabel/link 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(" contact : YourEmailAddress@gmail.com"); contact.setCursor(new Cursor(Cursor.HAND_CURSOR)); website.setText(" Website : http://www.google.com/"); 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 } } }); } } 

Tal vez use JXHyperhttps://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-jlabel/link de SwingX en su lugar. Extiende JButton . Algunos enlaces útiles:

  • Clase JXHyperhttps://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-jlabel/link
  • SwingX: considere JXHyperhttps://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-jlabel/link como una alternativa a los botones

Actualización : he ordenado más la clase SwingLink y he agregado más funciones; Puede encontrar una copia actualizada del mismo aquí: https://bitbucket.org/dimo414/jgrep/src/tip/src/grep/SwingLink.java


La respuesta de @ McDowell es genial, pero hay varias cosas que podrían mejorarse. Notablemente, se puede hacer clic en el texto que no sea el hipervínculo, y aún se ve como un botón, aunque se haya cambiado / ocultado parte del diseño. Si bien la accesibilidad es importante, una UI coherente también lo es.

Así que armé una clase que extendía JLabel basada en el código de McDowell. Es autónomo, maneja los errores correctamente y se siente más como un enlace:

 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 https://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-jlabel/link = ul ? ""+text+"" : text; super.setText(""+ https://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-jlabel/link+""); 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 https://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-jlabel/link, your computer is likely misconfigured.", "Cannot Launch Link",JOptionPane.WARNING_MESSAGE); } } else { JOptionPane.showMessageDialog(null, "Java is not able to launch https://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-jlabel/links on your computer.", "Cannot Launch Link", JOptionPane.WARNING_MESSAGE); } } } 

También podría, por ejemplo, cambiar el color del enlace a púrpura después de hacer clic, si eso le pareció útil. Es todo autocontenido, simplemente llama:

 SwingLink https://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-jlabel/link = new SwingLink("Java", "http://java.sun.com"); mainPanel.add(https://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-jlabel/link); 

Puede intentar usar un JEditorPane en lugar de un JLabel. Esto comprende HTML básico y enviará un evento Hyperhttps://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-jlabel/linkEvent al Hyperhttps://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-jlabel/linkListener que usted registra con JEditPane.

Si no funciona, entonces:

  1. Cree un JLabel y agregue un MouseListener (decore la etiqueta para que parezca un hipervínculo)
  2. Implementar el evento mouseClicked ()
  3. En la implementación del evento mouseClicked (), realice su acción

Eche un vistazo a java.awt.Desktop API para abrir un enlace usando el navegador predeterminado (esta API solo está disponible desde Java6).

Sé que llegué un poco tarde a la fiesta, pero hice un pequeño método que otros podrían encontrar interesante / útil.

 public static JLabel https://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-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 https://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-jlabel/link = new JLabel(); https://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-jlabel/link.setText(""+text+""); if(!toolTip.equals("")) https://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-jlabel/link.setToolTipText(toolTip); https://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-jlabel/link.setCursor(new Cursor(Cursor.HAND_CURSOR)); https://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-jlabel/link.addMouseListener(new MouseListener() { public void mouseExited(MouseEvent arg0) { https://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-jlabel/link.setText(""+text+""); } public void mouseEntered(MouseEvent arg0) { https://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-jlabel/link.setText(""+text+""); } 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 https://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-jlabel/link."); JDialog dialog = pane.createDialog(new JFrame(), ""); dialog.setVisible(true); } } public void mousePressed(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } }); return https://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-jlabel/link; } 

Te dará una JLabel que actúa como un enlace adecuado.

En acción:

 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(https://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-jlabel/linkify("this", "http://facebook.com", "Facebook")); container.add(new JLabel(" https://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-jlabel/link to open Facebook.")); frame.setVisible(true); } 

Si no desea información sobre herramientas, solo envíe un nulo.

¡Espero que alguien encuentre esto útil! (Si lo hace, asegúrese de avisarme, me gustaría saberlo).

Use un JEditorPane con un Hyperhttps://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-jlabel/linkListener .

Simplemente ponga window.open(website url) , funciona todo el tiempo.

El siguiente código requiere que JHyperLink se agregue a su ruta de comstackción.

 JHyperhttps://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-jlabel/link stackOverflow = new JHyperhttps://stackoverflow.com/questions/527719/how-to-add-hyperlink-in-jlabel/link("Click HERE!", "https://www.stackoverflow.com/"); JComponent[] messageComponents = new JComponent[] { stackOverflow }; JOptionPane.showMessageDialog(null, messageComponents, "StackOverflow", JOptionPane.PLAIN_MESSAGE); 

Tenga en cuenta que puede llenar la matriz JComponent con más componentes Swing .

Resultado:

Puedes usar esto debajo de

 actionListener -> Runtime.getRuntime().exec("cmd.exe /c start chrome www.google.com")` 

o si desea utilizar Internet Explorer o Firefox, reemplace chrome con iexplore o firefox