JLabel에 하이퍼 링크를 추가하는 방법은 무엇입니까?


답변:


97

를 사용하여이 작업을 수행 할 수 JLabel있지만 대안은 JButton. 그런 식으로, 당신은 걱정하지 않아도 접근성 과 단지를 사용하여 이벤트를 해고 할 수 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 이 답변에JTextField 표시된대로 또는 a 를 사용합니다 .
Andrew Thompson

1
링크의 일부가 아닌 텍스트도 클릭하여 링크를 따라갈 수 있습니다.
neuralmer

28

또 다른 솔루션을 제공하고 싶습니다. JLabel에서 HTML 코드를 사용하고 MouseListener를 등록한다는 점에서 이미 제안 된 것과 비슷하지만 링크 위로 마우스를 이동하면 HandCursor도 표시되므로 대부분의 사용자가 기대하는 것과 똑같습니다. . 플랫폼에서 브라우징을 지원하지 않는 경우 사용자를 오도 할 수있는 파란색 밑줄이 그어진 HTML 링크가 생성되지 않습니다. 대신 링크는 일반 텍스트로 표시됩니다. 이것은 @ dimo414가 제안한 SwingLink 클래스와 결합 될 수 있습니다.

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
EDT에서 연결하지 않는 것은 훌륭한 캐치입니다! 필요는 :-)뿐만 아니라 그 일을하지 않도록 SwingX HyperlinkAction를 해결하기
클레오 파트라

SwingX에 문제를 제기 : java.net/jira/browse/SWINGX-1530 - :-)이 최대을 가져 주셔서 감사합니다
클레오 파트라

@kleopatra 천만에요 :) Desktop.browse의 차단 동작을 재현 할 수없는 것 같습니다. 느린 컴퓨터에서는 확실히 차단됩니다. 특히 브라우저가 아직 열리지 않은 경우 가장 두드러집니다.
Stefan 2011

좋은 지적! 해결되지 않습니다, 당신의 의견은 나를 구원으로 거의 :-) 가까이 경향 -이 문제에 대한 당신의 코멘트를 추가
클레오 파트라

이것은 흥미로운 해결책입니다. JLabel을 확장하는 방법이 마음에 듭니다. 즉, GroupLayout이 버튼이 아닌 레이블처럼 배치 할 가능성이 더 높습니다. 나는 버튼을 사용하여 ... 당신이 구성 요소 사이에 도착 간격 증가 할 것으로 보인다 것으로 나타났습니다
Trejkaz

17

jLabel에 하이퍼 링크 또는 mailto를 설정하는 방법에 대한 기사를 썼습니다.

그러니 그냥 시도 :

나는 그것이 정확히 당신이 찾고있는 것이라고 생각합니다.

다음은 전체 코드 예제입니다.

/**
 * 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

업데이트 나는 SwingLink수업을 더 정리하고 더 많은 기능을 추가했습니다. 최신 사본은 여기에서 찾을 수 있습니다 : https://bitbucket.org/dimo414/jgrep/src/tip/src/grep/SwingLink.java


@McDowell의 대답은 훌륭하지만 개선 할 수있는 몇 가지 사항이 있습니다. 특히 하이퍼 링크 이외의 텍스트는 클릭 할 수 있으며 일부 스타일이 변경 / 숨겨져 있어도 여전히 단추처럼 보입니다. 접근성도 중요하지만 일관된 UI도 중요합니다.

그래서 McDowell의 코드를 기반으로 JLabel을 확장하는 클래스를 구성했습니다. 자체 포함되어 있고 오류를 올바르게 처리하며 링크처럼 느껴집니다.

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

예를 들어 유용하다고 생각되면 클릭 한 후 링크 색상을 보라색으로 변경할 수도 있습니다. 모두 자체 포함되어 있으며 다음과 같이 호출하면됩니다.

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

1
난 그냥 URI 세터 추가하는 새로운 풀 요청을 추가
boly38

마우스가 손이되면 더욱 좋아질 것입니다!
Leon

@Leon은 내 답변 상단에 링크 된 버전을 살펴보면 setCursor(new Cursor(Cursor.HAND_CURSOR));이 답변의 변형 인라인을 사용 하고 다른 개선 사항이 있습니다.
dimo414


13

JLabel 대신 JEditorPane을 사용해 볼 수 있습니다. 이것은 기본 HTML을 이해하고 JEditPane에 등록한 HyperlinkListener에 HyperlinkEvent 이벤트를 보냅니다.


1
하이퍼 링크가있는 텍스트 (즉시 변경 될 수 있음)가있는 경우 가장 좋은 솔루션입니다. 대부분의 다른 솔루션은 별도의 컨트롤에 하이퍼 링크를 배치해야합니다.
user149408 2015-09-05

5

<a href="link">가 작동하지 않는 경우 :

  1. JLabel을 만들고 MouseListener를 추가합니다 (레이블을 하이퍼 링크처럼 보이도록 장식).
  2. mouseClicked () 구현 이벤트
  3. mouseClicked () 이벤트 구현에서 작업을 수행하십시오.

기본 브라우저를 사용하여 링크를 여는 방법 은 java.awt.Desktop API를 참조하십시오 (이 API는 Java6에서만 사용 가능).


4

나는 내가 파티에 다소 늦었다는 것을 알고 있지만 다른 사람들이 멋지고 유용하다고 생각할 수있는 약간의 방법을 만들었다.

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

적절한 링크처럼 작동하는 JLabel을 제공합니다.

실행 중 :

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

툴팁이 필요하지 않으면 null을 보내십시오.

누군가가 유용하다고 생각하기를 바랍니다! (그렇다면 꼭 알려주세요. 기꺼이 듣고 싶습니다.)


4

를 사용 JEditorPane로모그래퍼 HyperlinkListener.



1

다음 코드 JHyperLink를 빌드 경로에 추가해야합니다.

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

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

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

JComponent더 많은 Swing구성 요소로 배열을 채울 수 있습니다 .

결과:


0

아래에서 사용할 수 있습니다.

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

당신이 사용하려는 경우 또는 Internet Explorer 또는 Firefox 교체 chrome와 함께 iexplore또는firefox

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.