模擬作業系統打開文件夾:用戶選擇目錄 → 進度條滾動 → 文件逐行顯示於表格 → 隱藏文件標記「隱藏文件」 → 加載完成進度條停止。
File.listFiles()、構建表格模型數據、Thread.sleep(100) 模擬動態效果、通過 SwingUtilities.invokeLater 安全更新 UI。DefaultTableModel 動態增行,列為「序號、文件名、屬性」。import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
public class FileListFrame extends JFrame {
private JTextField pathField;
private JTable table;
private JProgressBar progressBar;
private File chosenDir;
public FileListFrame() {
setTitle("窗體動態加載磁盤文件");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(450, 300);
setLocationRelativeTo(null);
setLayout(new BorderLayout());
// 北部:路徑輸入 + 瀏覽按鈕 + 進度條
JPanel north = new JPanel(new FlowLayout(FlowLayout.LEFT));
pathField = new JTextField(20); pathField.setEditable(false);
JButton btnChoose = new JButton("選擇文件夾");
progressBar = new JProgressBar(); progressBar.setPreferredSize(new Dimension(150, 20));
progressBar.setIndeterminate(false);
north.add(new JLabel("路徑:")); north.add(pathField); north.add(btnChoose); north.add(progressBar);
add(north, BorderLayout.NORTH);
// 中部:表格
table = new JTable();
add(new JScrollPane(table), BorderLayout.CENTER);
// 初始化表頭
DefaultTableModel model = new DefaultTableModel(new Object[]{"序號", "文件名", "屬性"}, 0);
table.setModel(model);
btnChoose.addActionListener(e -> chooseDirectory());
}
private void chooseDirectory() {
JFileChooser fc = new JFileChooser();
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
if (fc.showOpenDialog(this) != JFileChooser.APPROVE_OPTION) return;
chosenDir = fc.getSelectedFile();
pathField.setText(chosenDir.getAbsolutePath());
progressBar.setIndeterminate(true); // 開始滾動
File[] files = chosenDir.listFiles();
DefaultTableModel model = (DefaultTableModel) table.getModel();
model.setRowCount(0); // 清空舊數據
new Thread(() -> {
if (files != null) {
for (int i = 0; i < files.length; i++) {
File f = files[i];
if (f.isFile()) {
Object[] row = {i + 1, f.getName(), f.isHidden() ? "隱藏文件" : ""};
// 必須在 EDT 更新模型
SwingUtilities.invokeLater(() -> model.addRow(row));
}
try { Thread.sleep(50); } catch (InterruptedException ignored) {}
}
}
SwingUtilities.invokeLater(() -> progressBar.setIndeterminate(false));
}).start();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new FileListFrame().setVisible(true));
}
}
| 技術點 | 代碼體現 | 說明 | 僅允許選目錄 |
|---|---|---|
| 不確定進度條 | setIndeterminate(true/false) | 不知總進度時的滾動動畫 |
| 後台線程更新 UI | SwingUtilities.invokeLater(() -> model.addRow(row)) | Swing 非線程安全,所有模型變更必須在 EDT |
| 隱藏文件檢測 | file.isHidden() | 跨平台:Windows 看屬性位,Linux 看以點開頭 |

SwingWorker 替代手動 Thread,內置 publish/process 更優雅地處理進度回調。setValue(i) 顯示百分比。