使用 AWT/Swing 構建桌面應用,輸入目錄路徑,點擊按鈕遞歸列出所有文件/子目錄名稱。
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
public class DirectoryExplorer extends JFrame {
private final JTextField pathField = new JTextField(30);
private final JTextArea resultArea = new JTextArea(25, 70);
private final JButton searchBtn = new JButton("查詢");
public DirectoryExplorer() {
initUI();
bindEvents();
}
private void initUI() {
setTitle("目錄查詢器");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
setSize(600, 500);
setLocationRelativeTo(null); // 居中
add(new JLabel("目錄路徑:"));
add(pathField);
add(searchBtn);
add(new JScrollPane(resultArea)); // 加滾動條
resultArea.setEditable(false);
resultArea.setFont(new Font("Monospaced", Font.PLAIN, 14));
}
private void bindEvents() {
searchBtn.addActionListener(e -> doSearch());
pathField.addActionListener(e -> doSearch()); // Enter 鍵觸發
}
private void doSearch() {
String path = pathField.getText().trim();
if (path.isEmpty()) {
JOptionPane.showMessageDialog(this, "請輸入目錄路徑");
return;
}
File dir = new File(path);
if (!dir.exists() || !dir.isDirectory()) {
JOptionPane.showMessageDialog(this, "路徑不存在或非目錄: " + path);
return;
}
// 清空舊結果
resultArea.setText("");
// 遞歸列舉(這裡簡單演示,大目錄建議用 SwingWorker 異步)
listFiles(dir, "");
}
private void listFiles(File file, String indent) {
resultArea.append(indent + file.getName() + (file.isDirectory() ? "/" : "") + "\n");
if (file.isDirectory()) {
File[] children = file.listFiles();
if (children != null) {
for (File child : children) {
listFiles(child, indent + " ");
}
}
}
}
public static void main(String[] args) {
// EDT 執行緒啟動 GUI
SwingUtilities.invokeLater(() -> new DirectoryExplorer().setVisible(true));
}
}
| 技術點 | 說明 |
|---|---|
| EDT (Event Dispatch Thread) | Swing 所有 UI 操作必須在 EDT 執行,使用 SwingUtilities.invokeLater() 啟動。 |
| JScrollPane | 包裝 JTextArea 提供滾動條,防止內容超出可視區域。 |
| 遞歸遍歷 | File.listFiles() 返回 null 時需判空(權限不足或非目錄)。 |
| 大目錄阻塞 UI | 生產環境必須用 SwingWorker 或 ExecutorService 異步執行,完成後 SwingUtilities.invokeLater() 更新 UI。 |
| 編碼問題 | 文件名含中文時,控制台輸出可能亂碼,GUI 組件通常正常(依賴字體)。 |
private void doSearchAsync() {
String path = pathField.getText().trim();
File dir = new File(path);
resultArea.setText("掃描中...\n");
searchBtn.setEnabled(false);
new SwingWorker<Void, String>() {
@Override
protected Void doInBackground() throws Exception {
scanAndPublish(dir, "");
return null;
}
private void scanAndPublish(File file, String indent) {
publish(indent + file.getName() + (file.isDirectory() ? "/" : ""));
if (file.isDirectory()) {
File[] kids = file.listFiles();
if (kids != null) for (File k : kids) scanAndPublish(k, indent + " ");
}
}
@Override
protected void process(java.util.List<String> chunks) {
for (String line : chunks) resultArea.append(line + "\n");
}
@Override
protected void done() {
searchBtn.setEnabled(true);
resultArea.append("\n掃描完成。\n");
}
}.execute();
}