¿Cuál es la mejor manera de agregar un hipervínculo en un JLabel? Puedo obtener la vista usando etiquetas html, pero ¿cómo abrir el navegador cuando el usuario hace clic en él?
solución simple que puede encontrar aquí: solución
bench_doos
Respuestas:
97
Puede hacer esto usando a JLabel, pero una alternativa sería diseñar a JButton. De esa manera, no tiene que preocuparse por la accesibilidad y solo puede disparar eventos usando un ActionListener.
publicstaticvoid main(String[] args)throwsURISyntaxException{final URI uri =new URI("http://java.sun.com");classOpenUrlActionimplementsActionListener{@Overridepublicvoid actionPerformed(ActionEvent e){
open(uri);}}JFrame frame =newJFrame("Links");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(100,400);Container container = frame.getContentPane();
container.setLayout(newGridBagLayout());JButton button =newJButton();
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(newOpenUrlAction());
container.add(button);
frame.setVisible(true);}privatestaticvoid open(URI uri){if(Desktop.isDesktopSupported()){try{Desktop.getDesktop().browse(uri);}catch(IOException e){/* TODO: error handling */}}else{/* TODO: error handling */}}
+1 Utilice alternativamente a JTextFieldcomo se muestra en esta respuesta .
Andrew Thompson
1
Incluso se puede hacer clic en el texto que no forma parte del enlace para seguir el enlace.
neuralmer
28
Me gustaría ofrecer otra solución más. 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 que la mayoría de los usuarios esperarían. . Si la navegación no es compatible con la plataforma, no se crea ningún enlace HTML subrayado en azul que pueda engañar al usuario. En cambio, el enlace se presenta como texto sin formato. Esto podría combinarse con la clase SwingLink propuesta por @ dimo414.
publicclassJLabelLinkextendsJFrame{privatestaticfinalString LABEL_TEXT ="For further information visit:";privatestaticfinalString A_VALID_LINK ="http://stackoverflow.com";privatestaticfinalString A_HREF ="<a href=\"";privatestaticfinalString HREF_CLOSED ="\">";privatestaticfinalString HREF_END ="</a>";privatestaticfinalString HTML ="<html>";privatestaticfinalString HTML_END ="</html>";publicJLabelLink(){
setTitle("HTML link via a JLabel");
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);Container contentPane = getContentPane();
contentPane.setLayout(newFlowLayout(FlowLayout.LEFT));JLabel label =newJLabel(LABEL_TEXT);
contentPane.add(label);
label =newJLabel(A_VALID_LINK);
contentPane.add(label);if(isBrowsingSupported()){
makeLinkable(label,newLinkMouseListener());}
pack();}privatestaticvoid 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);}privatestaticboolean isBrowsingSupported(){if(!Desktop.isDesktopSupported()){returnfalse;}boolean result =false;Desktop desktop = java.awt.Desktop.getDesktop();if(desktop.isSupported(Desktop.Action.BROWSE)){
result =true;}return result;}privatestaticclassLinkMouseListenerextendsMouseAdapter{@Overridepublicvoid mouseClicked(java.awt.event.MouseEvent evt){JLabel l =(JLabel) evt.getSource();try{
URI uri =new java.net.URI(JLabelLink.getPlainLink(l.getText()));(newLinkRunner(uri)).execute();}catch(URISyntaxException use){thrownewAssertionError(use +": "+ l.getText());//NOI18N}}}privatestaticclassLinkRunnerextendsSwingWorker<Void,Void>{privatefinal URI uri;privateLinkRunner(URI u){if(u ==null){thrownewNullPointerException();}
uri = u;}@OverrideprotectedVoid doInBackground()throwsException{Desktop desktop = java.awt.Desktop.getDesktop();
desktop.browse(uri);returnnull;}@Overrideprotectedvoid done(){try{
get();}catch(ExecutionException ee){
handleException(uri, ee);}catch(InterruptedException ie){
handleException(uri, ie);}}privatestaticvoid 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);}}privatestaticString 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 escapingprivatestaticString 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 escapingprivatestaticString htmlIfy(String s){return HTML.concat(s).concat(HTML_END);}/**
* @param args the command line arguments
*/publicstaticvoid main(String[] args){SwingUtilities.invokeLater(newRunnable(){@Overridepublicvoid run(){newJLabelLink().setVisible(true);}});}}
@kleopatra De nada :) Parece que no pudiste reproducir el comportamiento de bloqueo de Desktop.browse - en mi máquina lenta se bloquea con seguridad, sobre todo si el navegador no está abierto todavía.
Stefan
¡buen punto! agregó su comentario al problema; casi tendía a cerrarse porque no se soluciona, su comentario me salvó :-)
kleopatra
Esta es una solución interesante. Me gusta cómo extiende JLabel; esto significa que es más probable que GroupLayout lo coloque como una etiqueta, no como un botón. He notado que el uso de botones parece aumentar el espacio que se obtiene entre los componentes ...
Trejkaz
17
Escribí un artículo sobre cómo configurar un hipervínculo o un mailto en un jLabel.
La respuesta de @ McDowell es excelente, pero hay varias cosas que podrían mejorarse. En particular, 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 estilo. Si bien la accesibilidad es importante, una interfaz de usuario 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:
publicclassSwingLinkextendsJLabel{privatestaticfinallong serialVersionUID =8273875024682878518L;privateString text;private URI uri;publicSwingLink(String text, URI uri){super();
setup(text,uri);}publicSwingLink(String text,String uri){super();
setup(text,URI.create(uri));}publicvoid setup(String t, URI u){
text = t;
uri = u;
setText(text);
setToolTipText(uri.toString());
addMouseListener(newMouseAdapter(){publicvoid mouseClicked(MouseEvent e){
open(uri);}publicvoid mouseEntered(MouseEvent e){
setText(text,false);}publicvoid mouseExited(MouseEvent e){
setText(text,true);}});}@Overridepublicvoid setText(String text){
setText(text,true);}publicvoid 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;}publicString getRawText(){return text;}privatestaticvoid 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);}}}
También puede, por ejemplo, cambiar el color del enlace a púrpura después de hacer clic, si le parece útil. Todo es autónomo, simplemente llama:
SwingLink link =newSwingLink("Java","http://java.sun.com");
mainPanel.add(link);
Acabo de agregar una nueva solicitud de extracción para agregar uri setter
boly38
Si el ratón se convierte en una mano, ¡será aún mejor!
Leon
@Leon eche un vistazo a la versión vinculada en la parte superior de mi respuesta, usa setCursor(new Cursor(Cursor.HAND_CURSOR));y tiene algunas otras mejoras sobre la variante en línea en esta respuesta.
dimo414
14
Quizás use JXHyperlinkde SwingX en su lugar. Se extiende JButton. Algunos enlaces útiles:
Puede intentar usar un JEditorPane en lugar de un JLabel. Esto comprende HTML básico y enviará un evento HyperlinkEvent al HyperlinkListener que registre con JEditPane.
Esta es la mejor solución si tiene texto con algunos hipervínculos (posiblemente cambiados sobre la marcha). La mayoría de las otras soluciones requieren colocar el hipervínculo en un control separado.
user149408
5
Si <a href="link"> no funciona, entonces:
Cree un JLabel y agregue un MouseListener (decore la etiqueta para que parezca un hipervínculo)
Respuestas:
Puede hacer esto usando a
JLabel
, pero una alternativa sería diseñar aJButton
. De esa manera, no tiene que preocuparse por la accesibilidad y solo puede disparar eventos usando unActionListener
.fuente
JTextField
como se muestra en esta respuesta .Me gustaría ofrecer otra solución más. 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 que la mayoría de los usuarios esperarían. . Si la navegación no es compatible con la plataforma, no se crea ningún enlace HTML subrayado en azul que pueda engañar al usuario. En cambio, el enlace se presenta como texto sin formato. Esto podría combinarse con la clase SwingLink propuesta por @ dimo414.
fuente
Escribí un artículo sobre cómo configurar un hipervínculo o un mailto en un jLabel.
Así que sólo tratar de que :
Creo que eso es exactamente lo que estás buscando.
Aquí está el ejemplo de código completo:
fuente
Actualización He ordenado aún más la
SwingLink
clase y he agregado más funciones; se puede encontrar una copia actualizada aquí: https://bitbucket.org/dimo414/jgrep/src/tip/src/grep/SwingLink.javaLa respuesta de @ McDowell es excelente, pero hay varias cosas que podrían mejorarse. En particular, 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 estilo. Si bien la accesibilidad es importante, una interfaz de usuario 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:
También puede, por ejemplo, cambiar el color del enlace a púrpura después de hacer clic, si le parece útil. Todo es autónomo, simplemente llama:
fuente
setCursor(new Cursor(Cursor.HAND_CURSOR));
y tiene algunas otras mejoras sobre la variante en línea en esta respuesta.Quizás use
JXHyperlink
de SwingX en su lugar. Se extiendeJButton
. Algunos enlaces útiles:fuente
Puede intentar usar un JEditorPane en lugar de un JLabel. Esto comprende HTML básico y enviará un evento HyperlinkEvent al HyperlinkListener que registre con JEditPane.
fuente
Si <a href="link"> no funciona, entonces:
Eche un vistazo a la API java.awt.Desktop para abrir un enlace utilizando el navegador predeterminado (esta API solo está disponible en Java6).
fuente
Sé que llego un poco tarde a la fiesta, pero hice un pequeño método que otros podrían encontrar interesante / útil.
Le dará un JLabel que actúa como un enlace adecuado.
En acción:
Si no desea información sobre herramientas, envíe un mensaje nulo.
¡Espero que alguien encuentre esto útil! (Si lo hace, asegúrese de hacérmelo saber, me encantaría saberlo).
fuente
Utilice a
JEditorPane
con aHyperlinkListener
.fuente
En pocas palabras
window.open(website url)
, funciona todo el tiempo.fuente
El siguiente código
JHyperLink
debe agregarse a su ruta de compilación.Tenga en cuenta que puede llenar la
JComponent
matriz con másSwing
componentes.Resultado:
fuente
Puede usar esto bajo un
o si desea utilizar Internet Explorer o Firefox, reemplácelo
chrome
coniexplore
ofirefox
fuente