示範在 `JApplet` 中使用 Swing `JTree`,從外部文字配置檔 (以 `|` 分隔層級與 URL) 動態構建樹節點,並實現節點點擊跳轉瀏覽器頁面。
網站導航 新聞|https://news.example.com 國內|https://news.example.com/domestic 國際|https://news.example.com/world 技術|https://tech.example.com Java|https://tech.example.com/java Python|https://tech.example.com/python 聯繫我們|https://contact.example.com
縮進空格數表示層級,`|` 後為目標 URL。
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;
import java.applet.*;
import java.awt.*;
import java.io.*;
import java.net.*;
import java.util.*;
public class PageTree extends JApplet implements TreeSelectionListener {
private DefaultMutableTreeNode[] nodesAtDepth = new DefaultMutableTreeNode[256];
private Hashtable links = new Hashtable<>();
private AppletContext context;
@Override
public void init() {
context = getAppletContext();
String fileParam = getParameter("file");
String targetParam = getParameter("target"); // 可選 target frame
if (fileParam == null) return;
try {
URL url = new URL(getDocumentBase(), fileParam);
try (BufferedReader br = new BufferedReader(
new InputStreamReader(url.openStream(), "UTF-8"))) {
String line = br.readLine();
if (line == null) return;
DefaultMutableTreeNode root = new DefaultMutableTreeNode(line.trim());
nodesAtDepth[0] = root;
int level = 0;
while ((line = br.readLine()) != null) {
StringTokenizer st = new StringTokenizer(line, "|");
String token = st.nextToken();
int depth = countLeadingSpaces(token);
token = token.trim();
// 處理層級跳躍 (插入空節點補齊)
for (int i = level + 1; i < depth; i++) {
DefaultMutableTreeNode dummy = new DefaultMutableTreeNode("");
nodesAtDepth[i].add(dummy);
nodesAtDepth[i + 1] = dummy;
}
level = depth;
DefaultMutableTreeNode node = new DefaultMutableTreeNode(token);
nodesAtDepth[depth].add(node);
nodesAtDepth[depth + 1] = node;
if (st.hasMoreTokens()) {
String link = st.nextToken().trim();
try {
links.put(node, new URL(link));
} catch (MalformedURLException ignored) {}
}
}
}
JTree tree = new JTree(root);
tree.addTreeSelectionListener(this);
getContentPane().add(new JScrollPane(tree), BorderLayout.CENTER);
} catch (IOException e) {
e.printStackTrace();
}
}
private int countLeadingSpaces(String s) {
int i = 0;
while (i < s.length() && s.charAt(i) == ' ') i++;
return i;
}
@Override
public void valueChanged(TreeSelectionEvent e) {
TreePath path = e.getPath();
Object node = path.getLastPathComponent();
URL url = links.get(node);
if (url != null) {
// 瀏覽器環境下跳轉
context.showDocument(url, getParameter("target"));
}
}
}
<applet code="PageTree.class" width="300" height="400"> <param name="file" value="data.txt"> <param name="target" value="_blank"> </applet>
| 技術點 | 說明 |
|---|---|
| JApplet vs Applet | `JApplet` 提供 `getContentPane()`、`JComponent` 支援,可直接放置 Swing 元件 |
| 樹模型構建 | `DefaultMutableTreeNode` 陣列 `nodesAtDepth` 追蹤各層級最新節點,O(1) 插入子節點 |
| 資料來源 | `getDocumentBase()` + 相對路徑 → `URL`,支援網路載入配置檔 |
| 編碼處理 | `InputStreamReader(url.openStream(), "UTF-8")` 明確指定 UTF-8,避免中文亂碼 |
| 超連結跳轉 | `AppletContext.showDocument(URL, target)` 委派瀏覽器開啟連結 |
教學價值:掌握「樹形資料結構構建」「外部配置驅動 UI」「事件監聽與瀏覽器互動」三大核心模式。