Java Swing 文件上传实现指南
在Java Swing中实现文件上传功能,通常需要结合文件选择对话框和文件处理逻辑,下面我将提供一个完整的实现方案。
基本实现步骤
创建文件选择对话框
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
public class FileUploadDemo {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("文件上传示例");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 200);
frame.setLayout(new FlowLayout());
JButton uploadButton = new JButton("选择文件");
JLabel fileLabel = new JLabel("未选择文件");
uploadButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setDialogTitle("选择要上传的文件");
int userSelection = fileChooser.showOpenDialog(frame);
if (userSelection == JFileChooser.APPROVE_OPTION) {
File selectedFile = fileChooser.getSelectedFile();
fileLabel.setText("已选择: " + selectedFile.getName());
// 这里可以添加文件上传逻辑
uploadFile(selectedFile);
}
}
});
frame.add(uploadButton);
frame.add(fileLabel);
frame.setVisible(true);
});
}
private static void uploadFile(File file) {
// 这里实现文件上传逻辑
System.out.println("准备上传文件: " + file.getAbsolutePath());
// 示例:模拟上传过程
SwingWorker<Void, Integer> worker = new SwingWorker<Void, Integer>() {
@Override
protected Void doInBackground() throws Exception {
// 模拟上传进度
for (int i = 0; i <= 100; i += 10) {
Thread.sleep(200); // 模拟网络延迟
publish(i); // 发布进度更新
}
return null;
}
@Override
protected void process(List<Integer> chunks) {
// 更新进度条或标签
System.out.println("上传进度: " + chunks.get(chunks.size() - 1) + "%");
}
@Override
protected void done() {
System.out.println("文件上传完成!");
}
};
worker.execute();
}
}
更完整的实现(带进度条)
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class AdvancedFileUpload {
private JFrame frame;
private JButton uploadButton;
private JLabel fileLabel;
private JProgressBar progressBar;
private JTextArea logArea;
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new AdvancedFileUpload().createAndShowGUI();
});
}
private void createAndShowGUI() {
frame = new JFrame("高级文件上传");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 400);
frame.setLayout(new BorderLayout(10, 10));
// 上传面板
JPanel uploadPanel = new JPanel(new FlowLayout());
uploadButton = new JButton("选择文件");
fileLabel = new JLabel("未选择文件");
progressBar = new JProgressBar(0, 100);
progressBar.setStringPainted(true);
uploadPanel.add(uploadButton);
uploadPanel.add(fileLabel);
uploadPanel.add(progressBar);
// 日志面板
logArea = new JTextArea(10, 40);
logArea.setEditable(false);
JScrollPane scrollPane = new JScrollPane(logArea);
frame.add(uploadPanel, BorderLayout.NORTH);
frame.add(scrollPane, BorderLayout.CENTER);
uploadButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
selectAndUploadFile();
}
});
frame.setVisible(true);
}
private void selectAndUploadFile() {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setDialogTitle("选择要上传的文件");
int userSelection = fileChooser.showOpenDialog(frame);
if (userSelection == JFileChooser.APPROVE_OPTION) {
File selectedFile = fileChooser.getSelectedFile();
fileLabel.setText("已选择: " + selectedFile.getName());
log("准备上传文件: " + selectedFile.getAbsolutePath());
// 在后台线程中执行上传
new SwingWorker<Void, Integer>() {
@Override
protected Void doInBackground() throws Exception {
// 模拟上传到服务器
URL url = new URL("http://example.com/upload");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
try (OutputStream os = connection.getOutputStream();
FileInputStream fis = new FileInputStream(selectedFile)) {
byte[] buffer = new byte[4096];
int bytesRead;
long totalBytes = selectedFile.length();
long bytesWritten = 0;
while ((bytesRead = fis.read(buffer)) != -1) {
os.write(buffer, 0, bytesRead);
bytesWritten += bytesRead;
int progress = (int) ((bytesWritten * 100) / totalBytes);
publish(progress);
}
}
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
log("文件上传成功!");
} else {
log("文件上传失败,服务器响应: " + responseCode);
}
return null;
}
@Override
protected void process(List<Integer> chunks) {
progressBar.setValue(chunks.get(chunks.size() - 1));
}
@Override
protected void done() {
try {
get(); // 检查是否有异常
} catch (Exception e) {
log("上传过程中发生错误: " + e.getMessage());
e.printStackTrace();
}
}
}.execute();
}
}
private void log(String message) {
logArea.append(message + "\n");
}
}
关键点说明
- 文件选择:使用
JFileChooser让用户选择文件 - 后台处理:使用
SwingWorker在后台线程执行文件上传,避免阻塞UI - 进度反馈:通过
publish()方法更新进度条 - 错误处理:捕获并显示上传过程中的异常
- 日志记录:使用
JTextArea显示操作日志
实际应用注意事项
- 服务器端:上述代码中的URL("http://example.com/upload")是示例,你需要替换为实际的上传接口
- 文件大小限制:大文件上传可能需要分块处理
- 认证:如果需要认证,可以在
HttpURLConnection中添加头部信息 - 取消上传:可以添加取消按钮来中断上传过程
- 多文件上传:可以扩展为支持多文件选择
替代方案
如果不想自己实现,可以考虑使用以下库:
- Apache HttpClient
- OkHttp
- Jersey Client
这些库提供了更完善的HTTP客户端功能,可以简化文件上传的实现。
