JDK 6 引入 `java.awt.Desktop` 類,提供統一的跨平台桌面集成能力:啟動默認瀏覽器、郵件客戶端、編輯/打印文件。本文以 JLabel 模擬超鏈接為例,展示 Desktop API 核心用法、鼠標交互增強、異常處理與現代替代方案。
package org.anthrax;
import java.awt.Cursor;
import java.awt.Desktop;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import javax.swing.JLabel;
public class DesktopRunner {
private final Desktop desktop;
private final String targetUrl;
public DesktopRunner(String targetUrl) {
this.desktop = Desktop.getDesktop();
this.targetUrl = targetUrl;
}
// 檢查是否支援 BROWSE 動作
public boolean isBrowserSupported() {
return desktop.isDesktopSupported()
&& desktop.isSupported(Desktop.Action.BROWSE);
}
// 啟動默認瀏覽器打開目標 URL
public void browse() {
if (!isBrowserSupported()) {
System.err.println("當前平台不支援 Desktop API 瀏覽器啟動");
return;
}
try {
URI uri = new URI(targetUrl);
desktop.browse(uri);
} catch (URISyntaxException | IOException e) {
e.printStackTrace();
// 降級處理:嘗試 Runtime.exec 或提示用戶手動複製鏈接
}
}
// 為 JLabel 添加超鏈接視覺與交互效果
public void enhanceAsHyperlink(JLabel label) {
// 1. 手型游標
label.setCursor(new Cursor(Cursor.HAND_CURSOR));
// 2. 底線字體 (模擬超鏈接)
label.setFont(label.getFont().deriveFont(java.awt.Font.PLAIN)
.deriveFont(new java.awt.font.TextAttribute[] {
java.awt.font.TextAttribute.UNDERLINE,
java.awt.font.TextAttribute.UNDERLINE_ON
}));
// 3. 滑鼠進入/退出變色 (可選)
label.addMouseListener(new java.awt.event.MouseAdapter() {
@Override
public void mouseEntered(java.awt.event.MouseEvent e) {
label.setForeground(java.awt.Color.BLUE);
}
@Override
public void mouseExited(java.awt.event.MouseEvent e) {
label.setForeground(java.awt.Color.BLACK);
}
@Override
public void mouseClicked(java.awt.event.MouseEvent e) {
if (e.getButton() == java.awt.event.MouseEvent.BUTTON1) {
browse();
}
}
});
// 4. 工具提示
label.setToolTipText("點擊打開: " + targetUrl);
}
}
public class HyperlinkDemo {
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("JLabel 超鏈接 Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new java.awt.FlowLayout());
JLabel linkLabel = new JLabel("訪問我的部落格");
new DesktopRunner("https://mybass.china-pub.com").enhanceAsHyperlink(linkLabel);
frame.add(linkLabel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
| Action | 功能 | 典型用途 |
|---|---|---|
| BROWSE | 啟動默認瀏覽器打開 URI | 超鏈接、幫助文檔、官網跳轉 |
| 啟動默認郵件客戶端 (mailto:) | 聯繫我們、反饋郵件、預填主體/內容 | |
| OPEN | 用關聯應用打開文件 | 打開 PDF/圖片/文檔、臨時文件預覽 |
| EDIT | 用編輯器打開文件 | 編輯配置文件、源碼、文本 |
| 打印文件 | 報表打印、標籤打印、文檔輸出 |
public void sendEmail(String to, String subject, String body) {
if (desktop.isSupported(Desktop.Action.MAIL)) {
try {
String mailto = String.format("mailto:%s?subject=%s&body=%s",
to,
java.net.URLEncoder.encode(subject, "UTF-8"),
java.net.URLEncoder.encode(body, "UTF-8"));
desktop.mail(new URI(mailto));
} catch (Exception e) { e.printStackTrace(); }
}
}
import javafx.application.HostServices;
// 獲取 HostServices (需 Application 子類或注入)
hostServices.showDocument("https://example.com");
優勢:更豐富的 UI 控件、WebView 內嵌瀏覽器、CSS 樣式、動畫
// 使用 JEditorPane 顯示 HTML 超鏈接
JEditorPane pane = new JEditorPane("text/html",
"點擊訪問");
pane.setEditable(false);
pane.addHyperlinkListener(e -> {
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
try { Desktop.getDesktop().browse(e.getURL().toURI()); }
catch (Exception ex) { ex.printStackTrace(); }
}
});
瀏覽器環境直接使用 ``、JS `window.open()`、Thymeleaf/React/Vue 鏈接組件。