Cách tốt nhất để thêm siêu liên kết trong JLabel là gì? Tôi có thể xem bằng cách sử dụng các thẻ html, nhưng làm thế nào để mở trình duyệt khi người dùng nhấp vào nó?
Cách tốt nhất để thêm siêu liên kết trong JLabel là gì? Tôi có thể xem bằng cách sử dụng các thẻ html, nhưng làm thế nào để mở trình duyệt khi người dùng nhấp vào nó?
Câu trả lời:
Bạn có thể làm điều này bằng cách sử dụng a JLabel
, nhưng một cách thay thế sẽ là tạo kiểu a JButton
. Bằng cách đó, bạn không phải lo lắng về khả năng truy cập và chỉ có thể kích hoạt các sự kiện bằng cách sử dụng 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 */ }
}
JTextField
như được hiển thị trong câu trả lời này .
Tôi muốn đưa ra một giải pháp khác. Nó tương tự như những cái đã được đề xuất vì nó sử dụng mã HTML trong JLabel và đăng ký MouseListener trên đó, nhưng nó cũng hiển thị HandCursor khi bạn di chuyển chuột qua liên kết, vì vậy giao diện giống như những gì hầu hết người dùng mong đợi . Nếu tính năng duyệt không được nền tảng hỗ trợ, thì sẽ không tạo liên kết HTML có gạch chân màu xanh lam có thể gây hiểu lầm cho người dùng. Thay vào đó, liên kết chỉ được trình bày dưới dạng văn bản thuần túy. Điều này có thể được kết hợp với lớp SwingLink do @ dimo414 đề xuất.
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);
}
});
}
}
Tôi đã viết một bài báo về cách đặt một siêu liên kết hoặc một mailto trên jLabel.
Vì vậy, chỉ cần thử nó :
Tôi nghĩ đó chính xác là những gì bạn đang tìm kiếm.
Đây là ví dụ về mã hoàn chỉnh:
/**
* 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
}
}
});
}
}
Cập nhật Tôi đã thu dọn SwingLink
lớp hơn nữa và thêm nhiều tính năng hơn; bản sao cập nhật của nó có thể được tìm thấy tại đây: https://bitbucket.org/dimo414/jgrep/src/tip/src/grep/SwingLink.java
Câu trả lời của @ McDowell rất hay, nhưng có một số thứ có thể được cải thiện. Đáng chú ý là văn bản khác với siêu liên kết có thể nhấp được và nó vẫn trông giống như một nút mặc dù một số kiểu đã được thay đổi / ẩn. Mặc dù khả năng truy cập là quan trọng, nhưng giao diện người dùng nhất quán cũng vậy.
Vì vậy, tôi đã tập hợp một lớp mở rộng JLabel dựa trên mã của McDowell. Nó khép kín, xử lý lỗi đúng cách và giống như một liên kết hơn:
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);
}
}
}
Ví dụ, bạn cũng có thể thay đổi màu liên kết thành màu tím sau khi được nhấp vào, nếu điều đó có vẻ hữu ích. Tất cả đều khép kín, bạn chỉ cần gọi:
SwingLink link = new SwingLink("Java", "http://java.sun.com");
mainPanel.add(link);
setCursor(new Cursor(Cursor.HAND_CURSOR));
và có một số cải tiến khác so với biến thể nội dòng trong câu trả lời này.
Có thể sử dụng JXHyperlink
từ SwingX để thay thế. Nó mở rộng JButton
. Một số liên kết hữu ích:
Bạn có thể thử sử dụng JEditorPane thay vì JLabel. Điều này hiểu HTML cơ bản và sẽ gửi một sự kiện HyperlinkEvent tới HyperlinkListener mà bạn đăng ký với JEditPane.
Nếu <a href="link"> không hoạt động, thì:
Hãy xem API java.awt.Desktop để mở liên kết bằng trình duyệt mặc định (API này chỉ có sẵn từ Java6).
Tôi biết mình hơi muộn đến bữa tiệc nhưng tôi đã thực hiện một phương pháp nhỏ mà người khác có thể thấy hay / hữu ích.
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;
}
Nó sẽ cung cấp cho bạn một JLabel hoạt động giống như một liên kết thích hợp.
Trong hành động:
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);
}
Nếu bạn không muốn có chú giải công cụ, chỉ cần gửi giá trị rỗng.
Hy vọng ai đó thấy điều này hữu ích! (Nếu bạn làm vậy, hãy cho tôi biết, tôi rất vui được nghe.)
Chỉ cần đặt window.open(website url)
, nó hoạt động mọi lúc.
Mã sau yêu cầu JHyperLink
được thêm vào đường dẫn xây dựng của bạn.
JHyperlink stackOverflow = new JHyperlink("Click HERE!",
"https://www.stackoverflow.com/");
JComponent[] messageComponents = new JComponent[] { stackOverflow };
JOptionPane.showMessageDialog(null, messageComponents, "StackOverflow",
JOptionPane.PLAIN_MESSAGE);
Lưu ý rằng bạn có thể lấp đầy JComponent
mảng với nhiều Swing
thành phần hơn .
Kết quả:
Bạn có thể sử dụng điều này trong một
actionListener -> Runtime.getRuntime().exec("cmd.exe /c start chrome www.google.com")`
hoặc nếu bạn muốn sử dụng Internet Explorer hoặc Firefox, hãy thay thế chrome
bằng iexplore
hoặcfirefox