2009-02-09 22 views
81

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

+0

[http: //sourceforge.net/projects/jhyperlink/](http://sourceforge.net/projects/jhyperlink/) – dm76

+0

solución simple que puede encontrar aquí: [solución] (http://stackoverflow.com/questions/8669350/jlabel-hyperlink-to-open-browser-at-correct-url) –

Respuesta

87

Usted puede hacer esto utilizando una JLabel, pero una alternativa sería el estilo de un JButton. De esta manera, no tiene que preocuparse por accessibility y solo puede disparar eventos usando 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 */ } 
    } 
+0

Esto fue tan útil y genial, siempre me pregunté cómo hacerlo, gracias un millón :) –

+1

+1 Alternativamente use un 'JTextField' como se muestra en [esta respuesta] (http://stackoverflow.com/a/13871898/418556). –

+0

+1 gran trabajo hecho hombre :) – saikosen

4

Si < a href = "link" > no funciona, entonces:

  1. Crear un JLabel y añadir un MouseListener (decorar la etiqueta para que parezca un hipervínculo)
  2. Implementar mouseClicked() caso
  3. en la implementación de mouseClicked() caso, lleve a cabo su acción

Tenga una mirada en java.awt.Desktop API para OpenIn g un enlace utilizando el navegador predeterminado (esta API solo está disponible desde Java6).

13

actualización he puso en orden la clase SwingLink más allá y añade más características; una copia actualizada de la misma se puede encontrar aquí: https://bitbucket.org/dimo414/jgrep/src/tip/src/grep/SwingLink.java


@ respuesta de McDowell es grande, 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 amplía JLabel basada en el código de McDowell. Es autónomo, controla 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 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); 
    } 
    } 
} 

Usted también podría, por ejemplo, cambiar el color de los enlaces a púrpura después de haber hecho clic, si eso pareció útil. Todo es independiente, sólo tiene que llamar:

SwingLink link = new SwingLink("Java", "http://java.sun.com"); 
mainPanel.add(link); 
+1

Acabo de agregar nueva solicitud de extracción para agregar uri setter – boly38

10

puede intentar utilizar un JEditorPane en lugar de un JLabel. Esto comprende HTML básico y enviará un evento HyperlinkEvent al HyperlinkListener que usted registra con JEditPane.

+1

Esta es la mejor solución si tiene texto con algunos hipervínculos (posiblemente modificados sobre la marcha). La mayoría de las otras soluciones requieren colocar el hipervínculo en un control separado. – user149408

27

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 la apariencia & es como la mayoría de los usuarios Esperaría. 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 = "<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); 
     } 
    }); 
} 
} 
+1

no hacer la conexión en el EDT es una excelente opción. Necesita arreglar SwingX HyperlinkAction para no hacerlo también :-) – kleopatra

+0

archivó un problema en SwingX: http: // java.net/jira/browse/SWINGX-1530 - gracias por mencionar esto :-) – kleopatra

+0

@kleopatra De nada :) Parece que no pudiste reproducir el comportamiento de bloqueo de Desktop.browse - en mi máquina lenta no bloquea seguro, más notablemente si el navegador aún no está abierto. – Stefan

16

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

Así que sólo tratar it:

Creo que eso es exactamente lo que está buscando.

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

/** 
* 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=\"\">[email protected]</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:[email protected]?subject=TEST")); 
       } catch (URISyntaxException | IOException ex) { 
        //It looks like there's a problem 
       } 
      } 
     }); 
    } 
} 
4

Sé que soy un poco tarde a la fiesta, pero hice un pequeño método que otros podrían encontrar fresco/utilidad.

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

Le 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(linkify("this", "http://facebook.com", "Facebook")); 
    container.add(new JLabel(" link to open Facebook.")); 
    frame.setVisible(true); 
} 

Si desea información sobre herramientas no basta con enviar un nulo.

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

4

Use JEditorPane con HyperlinkListener.

2

Simplemente ponga window.open(website url), funciona siempre.

1

El siguiente código requiere JHyperLink para agregar a su ruta de compilación.

JHyperlink stackOverflow = new JHyperlink("Click HERE!", 
       "https://www.stackoverflow.com/"); 

JComponent[] messageComponents = new JComponent[] { stackOverflow }; 

JOptionPane.showMessageDialog(null, messageComponents, "StackOverflow", 
       JOptionPane.PLAIN_MESSAGE); 

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

Resultado:

1

Se puede usar esta bajo una

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

o si desea utilizar Internet Explorer o Firefox reemplazar chrome con iexplore o firefox