Yesterday, one of my tasks was to display hyperlink to local file. When user clicks hyperlink, program have to open file in an associated application. Earlier I have been writing desktop applications on QT and I haven't had any problems. But it is not very simple in Java(Swing). First, I've created label and put html as text:
JLabel label = new JLabel("<html><a href=\"someurl.com\">link</a>");
When I launched an application, I turned to be very happy because I saw hyperlink. Furthermore, my delight was anticipatory :( Label was only looking like hyperlink :(
My colleagues told me to use jdic. This is a good library, but after some time I found the solution in JDK. JDK has the class java.awt.Desktop that was introduced in the version 1.6. The desktop has static method browse(URI uri). It opens the uri in a default browser on your system. Besides, you can use static method open(File f) to open file in an associated application.
When I solved trouble with URL browsing, I back to the problem with look'n'feel - label with html has underline text, always(but need underline only when cursor on hyperlink). Also, label returned text that was containing html tags which was not very good. I had some problems to underline the text in the label. I found solution on java.sun.com
When I've solved all problems I wrote two classes. One for the look'n'feel and the other(inherited from first) for browsing URLs.
public class HyperlinkView extends JLabel {
Font srcFont;
public HyperlinkView() {
this("");
}
public HyperlinkView(String text) {
super(text);
setForeground(Color.BLUE);
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
srcFont = HyperlinkView.this.getFont();
addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
Font font = HyperlinkView.this.getFont();
Hashtable<TextAttribute, Object> attributes = new Hashtable<TextAttribute, Object>();
attributes.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
HyperlinkView.this.setFont(font.deriveFont(attributes));
}
@Override
public void mouseExited(MouseEvent e) {
HyperlinkView.this.setFont(srcFont);
}
});
}
}
public class HyperlinkLabel extends HyperlinkView {
private String url;
public HyperlinkLabel(String text, String url) {
super(text);
this.url = url;
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
try {
Desktop.getDesktop().browse(URI.create(HyperlinkLabel.this.getUrl()));
} catch (IOException e1) {
JOptionPane.showMessageDialog(HyperlinkLabel.this, "Associated application not found", "Error", JOptionPane.ERROR_MESSAGE);
}
}
});
}
public HyperlinkLabel() {
this("", null);
}
public String getUrl() {
return url == null ? "" : url;
}
public void setUrl(String url) {
this.url = url;
}
}