Wie füge ich einen Hyperlink in JLabel hinzu?


Antworten:


97

Sie können dies mit a tun JLabel, aber eine Alternative wäre, a zu stylen JButton. Auf diese Weise müssen Sie sich keine Sorgen um die Barrierefreiheit machen und können Ereignisse einfach mit einem auslösen 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 */ }
  }

2
+1 Verwenden Sie alternativ a JTextFieldwie in dieser Antwort gezeigt .
Andrew Thompson

1
Sogar Text, der nicht Teil des Links ist, kann angeklickt werden, um dem Link zu folgen.
Neuralmer

28

Ich möchte noch eine andere Lösung anbieten. Es ähnelt den bereits vorgeschlagenen, da es HTML-Code in einem JLabel verwendet und einen MouseListener darauf registriert, aber es zeigt auch einen HandCursor an, wenn Sie die Maus über den Link bewegen, sodass das Erscheinungsbild genau dem entspricht, was die meisten Benutzer erwarten würden . Wenn das Surfen von der Plattform nicht unterstützt wird, wird kein blauer, unterstrichener HTML-Link erstellt, der den Benutzer irreführen könnte. Stattdessen wird der Link nur als einfacher Text dargestellt. Dies könnte mit der von @ dimo414 vorgeschlagenen SwingLink-Klasse kombiniert werden.

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
Das Nicht-Anschließen am EDT ist ein ausgezeichneter Fang! Müssen SwingX HyperlinkAction so beheben, dass es nicht so gut
läuft

hat ein Problem in SwingX eingereicht: java.net/jira/browse/SWINGX-1530 - danke, dass
du das angesprochen hast

@kleopatra Gern geschehen :) Es scheint, dass Sie das Blockierungsverhalten von Desktop.browse nicht reproduzieren konnten - auf meinem langsamen Computer blockiert es mit Sicherheit, insbesondere wenn der Browser noch nicht geöffnet ist.
Stefan

guter Punkt! fügte Ihren Kommentar zu dem Problem hinzu - fast geschlossen, da nicht
behoben werden kann

Dies ist eine interessante Lösung. Mir gefällt, wie es JLabel erweitert - dies bedeutet, dass GroupLayout es eher wie ein Label und nicht wie eine Schaltfläche positioniert. Ich habe festgestellt, dass die Verwendung von Tasten den Abstand zwischen den Komponenten zu vergrößern scheint ...
Trejkaz

17

Ich habe einen Artikel darüber geschrieben, wie man einen Hyperlink oder ein Mailto auf einem jLabel setzt.

Probieren Sie es einfach aus :

Ich denke, genau das suchen Sie.

Hier ist das vollständige Codebeispiel:

/**
 * 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
                }
            }
        });
    }
}

15

Update Ich habe die SwingLinkKlasse weiter aufgeräumt und weitere Funktionen hinzugefügt. Eine aktuelle Kopie finden Sie hier: https://bitbucket.org/dimo414/jgrep/src/tip/src/grep/SwingLink.java


@ McDowell's Antwort ist großartig, aber es gibt einige Dinge, die verbessert werden könnten. Insbesondere anderer Text als der Hyperlink kann angeklickt werden und sieht immer noch wie eine Schaltfläche aus, obwohl ein Teil des Stils geändert / ausgeblendet wurde. Barrierefreiheit ist wichtig, aber auch eine kohärente Benutzeroberfläche.

Also habe ich eine Klasse zusammengestellt, die JLabel basierend auf McDowell's Code erweitert. Es ist in sich geschlossen, behandelt Fehler richtig und fühlt sich eher wie ein Link an:

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

Sie können beispielsweise auch die Linkfarbe nach dem Klicken in Lila ändern, wenn dies nützlich erscheint. Es ist alles in sich geschlossen, Sie nennen einfach:

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

1
Ich habe gerade eine neue Pull-Anfrage hinzugefügt, um Uri Setter hinzuzufügen
boly38

Wenn die Maus zur Hand wird, ist es noch besser!
Leon

@Leon werfen Sie einen Blick auf die Version, die oben in meiner Antwort verlinkt ist. Sie verwendet setCursor(new Cursor(Cursor.HAND_CURSOR));und hat einige andere Verbesserungen gegenüber der Variante inline in dieser Antwort.
dimo414


13

Sie können versuchen, ein JEditorPane anstelle eines JLabels zu verwenden. Dies versteht das grundlegende HTML und sendet ein HyperlinkEvent-Ereignis an den HyperlinkListener, den Sie beim JEditPane registrieren.


1
Dies ist die beste Lösung, wenn Sie Text mit einigen Hyperlinks enthalten (möglicherweise im laufenden Betrieb geändert). Bei den meisten anderen Lösungen muss der Hyperlink in einem separaten Steuerelement platziert werden.
user149408

5

Wenn <a href="link"> nicht funktioniert, dann:

  1. Erstellen Sie ein JLabel und fügen Sie einen MouseListener hinzu (dekorieren Sie das Label so, dass es wie ein Hyperlink aussieht).
  2. Implementieren mouseClicked () Ereignis
  3. Führen Sie in der Implementierung des Ereignisses mouseClicked () Ihre Aktion aus

Schauen Sie sich die java.awt.Desktop- API an, um einen Link mit dem Standardbrowser zu öffnen (diese API ist nur in Java6 verfügbar).


4

Ich weiß, dass ich etwas spät zur Party komme, aber ich habe eine kleine Methode entwickelt, die andere vielleicht cool / nützlich finden.

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

Sie erhalten ein JLabel, das sich wie ein richtiger Link verhält.

In Aktion:

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

Wenn Sie keinen Tooltip wünschen, senden Sie einfach eine Null.

Hoffe jemand findet das nützlich! (Wenn Sie dies tun, lassen Sie es mich wissen, ich würde mich freuen zu hören.)


4

Verwenden Sie a JEditorPanemit a HyperlinkListener.



1

Der folgende Code muss JHyperLinkIhrem Erstellungspfad hinzugefügt werden.

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

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

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

Beachten Sie, dass Sie das JComponentArray mit weiteren SwingKomponenten füllen können .

Ergebnis:


0

Sie können dies unter einem verwenden

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

oder wenn Sie Internet Explorer oder Firefox verwenden möchten, ersetzen Sie chromedurch iexploreoderfirefox

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.