Quelle est la meilleure façon d'ajouter un lien hypertexte dans un JLabel? Je peux obtenir la vue en utilisant des balises html, mais comment ouvrir le navigateur lorsque l'utilisateur clique dessus?
solution simple que vous pouvez trouver ici: solution
bench_doos
Réponses:
97
Vous pouvez le faire en utilisant a JLabel, mais une alternative serait de styliser a JButton. De cette façon, vous n'avez pas à vous soucier de l' accessibilité et pouvez simplement déclencher des événements à l'aide d'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 Vous pouvez également utiliser a JTextFieldcomme indiqué dans cette réponse .
Andrew Thompson
1
Même le texte qui ne fait pas partie du lien peut être cliqué pour suivre le lien.
neuralmer
28
Je voudrais proposer encore une autre solution. Il est similaire à ceux déjà proposés car il utilise du code HTML dans un JLabel et enregistre un MouseListener dessus, mais il affiche également un HandCursor lorsque vous déplacez la souris sur le lien, de sorte que l'apparence est exactement ce que la plupart des utilisateurs attendent. . Si la navigation n'est pas prise en charge par la plate-forme, aucun lien HTML bleu souligné n'est créé qui pourrait induire l'utilisateur en erreur. Au lieu de cela, le lien est simplement présenté sous forme de texte brut. Cela pourrait être combiné avec la classe SwingLink proposée par @ 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 Vous êtes les bienvenus :) Il semble que vous ne puissiez pas reproduire le comportement de blocage de Desktop.browse - sur ma machine lente, il bloque à coup sûr, surtout si le navigateur n'est pas encore ouvert.
Stefan
bon point! a ajouté votre commentaire au problème - a presque tendance à se fermer car ne résout pas, votre commentaire m'a sauvé :-)
kleopatra
C'est une solution intéressante. J'aime la façon dont il étend JLabel - cela signifie que GroupLayout est plus susceptible de le positionner comme une étiquette, pas comme un bouton. J'ai remarqué que l'utilisation des boutons semble augmenter l'espacement entre les composants ...
Trejkaz
17
J'ai écrit un article sur la façon de définir un lien hypertexte ou un mailto sur un jLabel.
La réponse de @ McDowell est excellente, mais il y a plusieurs choses qui pourraient être améliorées. Notamment, le texte autre que le lien hypertexte est cliquable et il ressemble toujours à un bouton même si une partie du style a été modifiée / masquée. Bien que l'accessibilité soit importante, une interface utilisateur cohérente l'est également.
J'ai donc mis en place une classe étendant JLabel basée sur le code de McDowell. Il est autonome, gère correctement les erreurs et ressemble plus à un lien:
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);}}}
Vous pouvez également, par exemple, changer la couleur du lien en violet après avoir cliqué dessus, si cela vous semble utile. Tout est autonome, vous appelez simplement:
SwingLink link =newSwingLink("Java","http://java.sun.com");
mainPanel.add(link);
Je viens d'ajouter une nouvelle demande de tirage pour ajouter uri setter
boly38
Si la souris devient une main, ce sera encore mieux!
Leon
@Leon jetez un oeil à la version liée en haut de ma réponse, elle utilise setCursor(new Cursor(Cursor.HAND_CURSOR));et a quelques autres améliorations par rapport à la variante en ligne dans cette réponse.
dimo414
14
Peut-être utiliser JXHyperlinkà la place de SwingX . Il s'étend JButton. Quelques liens utiles:
Vous pouvez essayer d'utiliser un JEditorPane au lieu d'un JLabel. Cela comprend le HTML de base et enverra un événement HyperlinkEvent au HyperlinkListener que vous enregistrez auprès de JEditPane.
C'est la meilleure solution si vous avez du texte contenant des hyperliens (éventuellement modifiés à la volée). La plupart des autres solutions nécessitent de placer le lien hypertexte dans un contrôle séparé.
user149408
5
Si <a href="link"> ne fonctionne pas, alors:
Créez un JLabel et ajoutez un MouseListener (décorez l'étiquette pour qu'elle ressemble à un lien hypertexte)
Réponses:
Vous pouvez le faire en utilisant a
JLabel
, mais une alternative serait de styliser aJButton
. De cette façon, vous n'avez pas à vous soucier de l' accessibilité et pouvez simplement déclencher des événements à l'aide d'unActionListener
.la source
JTextField
comme indiqué dans cette réponse .Je voudrais proposer encore une autre solution. Il est similaire à ceux déjà proposés car il utilise du code HTML dans un JLabel et enregistre un MouseListener dessus, mais il affiche également un HandCursor lorsque vous déplacez la souris sur le lien, de sorte que l'apparence est exactement ce que la plupart des utilisateurs attendent. . Si la navigation n'est pas prise en charge par la plate-forme, aucun lien HTML bleu souligné n'est créé qui pourrait induire l'utilisateur en erreur. Au lieu de cela, le lien est simplement présenté sous forme de texte brut. Cela pourrait être combiné avec la classe SwingLink proposée par @ dimo414.
la source
J'ai écrit un article sur la façon de définir un lien hypertexte ou un mailto sur un jLabel.
Alors essayez- le :
Je pense que c'est exactement ce que vous recherchez.
Voici l'exemple de code complet:
la source
Mise à jour J'ai rangé
SwingLink
davantage la classe et ajouté plus de fonctionnalités; une copie à jour de celui-ci peut être trouvée ici: https://bitbucket.org/dimo414/jgrep/src/tip/src/grep/SwingLink.javaLa réponse de @ McDowell est excellente, mais il y a plusieurs choses qui pourraient être améliorées. Notamment, le texte autre que le lien hypertexte est cliquable et il ressemble toujours à un bouton même si une partie du style a été modifiée / masquée. Bien que l'accessibilité soit importante, une interface utilisateur cohérente l'est également.
J'ai donc mis en place une classe étendant JLabel basée sur le code de McDowell. Il est autonome, gère correctement les erreurs et ressemble plus à un lien:
Vous pouvez également, par exemple, changer la couleur du lien en violet après avoir cliqué dessus, si cela vous semble utile. Tout est autonome, vous appelez simplement:
la source
setCursor(new Cursor(Cursor.HAND_CURSOR));
et a quelques autres améliorations par rapport à la variante en ligne dans cette réponse.Peut-être utiliser
JXHyperlink
à la place de SwingX . Il s'étendJButton
. Quelques liens utiles:la source
Vous pouvez essayer d'utiliser un JEditorPane au lieu d'un JLabel. Cela comprend le HTML de base et enverra un événement HyperlinkEvent au HyperlinkListener que vous enregistrez auprès de JEditPane.
la source
Si <a href="link"> ne fonctionne pas, alors:
Jetez un œil à l' API java.awt.Desktop pour ouvrir un lien à l'aide du navigateur par défaut (cette API n'est disponible qu'à partir de Java6).
la source
Je sais que je suis un peu en retard à la fête mais j'ai fait une petite méthode que d'autres pourraient trouver cool / utile.
Cela vous donnera un JLabel qui agit comme un lien approprié.
En action:
Si vous ne souhaitez aucune info-bulle, envoyez simplement un null.
J'espère que quelqu'un trouvera cela utile! (Si vous le faites, assurez-vous de me le faire savoir, je serais heureux de l'entendre.)
la source
Utilisez a
JEditorPane
avec aHyperlinkListener
.la source
Autrement dit
window.open(website url)
, cela fonctionne à chaque fois.la source
Le code suivant doit
JHyperLink
être ajouté à votre chemin de génération.Notez que vous pouvez remplir le
JComponent
tableau avec plus deSwing
composants.Résultat:
la source
Vous pouvez l'utiliser sous un
ou si vous souhaitez utiliser Internet Explorer ou Firefox, remplacez
chrome
pariexplore
oufirefox
la source