You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Swing应用生成文件时触发ClassCastException错误求助

PDF合并Swing应用ClassCastException问题解决

错误原因分析

错误栈显示在projet1.Pdf$5.actionPerformed(Pdf.java:156)行,将JLabel强制转换为JTextField失败。核心问题是获取动态添加的文本框时组件索引计算错误:

每次点击"Ajouter"按钮,会向contentPane依次添加三个组件:JLabel、JTextField、JButton。但合并逻辑的循环中,直接用contentPane.getComponent(i-1)获取组件,该位置对应的是JLabel而非JTextField,导致类型转换异常。

解决方案

不要依赖组件索引获取文本框,而是维护一个专门存储JTextField的列表,每次添加新文本框时存入列表,合并时直接遍历列表即可。

修改后的完整代码

package projet1;

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;

import org.apache.pdfbox.multipdf.PDFMergerUtility;

public class Pdf extends JFrame {

    private JPanel contentPane;
    private JTextField textpdf;
    private JFileChooser fileChooser;
    private JTextField destField;
    private String destPath;
    private int count = 1;
    // 存储所有PDF路径文本框的列表
    private List<JTextField> pdfTextFields = new ArrayList<>();

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Pdf frame = new Pdf();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public Pdf() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 497, 447);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));

        setContentPane(contentPane);
        contentPane.setLayout(null);
        
        textpdf = new JTextField();
        textpdf.setBounds(98, 21, 239, 20);
        contentPane.add(textpdf);
        textpdf.setColumns(10);
        // 将初始文本框加入列表
        pdfTextFields.add(textpdf);
        
        JLabel lblNewLabel = new JLabel("PDF File");
        lblNewLabel.setFont(new java.awt.Font("Tahoma", java.awt.Font.BOLD, 14));
        lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER);
        lblNewLabel.setBounds(10, 24, 66, 14);
        contentPane.add(lblNewLabel);
        
        JButton btnParcourir = new JButton("Parcourir");
        btnParcourir.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                fileChooser = new JFileChooser();
                fileChooser.setCurrentDirectory(new File(System.getProperty("user.home")));
                int result = fileChooser.showOpenDialog(contentPane);
                if (result == JFileChooser.APPROVE_OPTION) {
                    File selectedFile = fileChooser.getSelectedFile();
                    textpdf.setText(selectedFile.getAbsolutePath());
                }
            }
        });
        btnParcourir.setBounds(347, 20, 89, 23);
        contentPane.add(btnParcourir);
        
        JButton destButton = new JButton("Destination");
        destButton.setBounds(10, 343, 116, 23);
        destButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                fileChooser = new JFileChooser();
                fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                int result = fileChooser.showOpenDialog(contentPane);
                if (result == JFileChooser.APPROVE_OPTION) {
                    File selectedFile = fileChooser.getSelectedFile();
                    destPath = selectedFile.getAbsolutePath();
                    destField.setText(destPath);
                }
            }
        });
        contentPane.add(destButton);
        
        JButton btnAjouter = new JButton("Ajouter");
        btnAjouter.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                count++;
                // 添加新标签
                JLabel label = new JLabel("PDF File " + count);
                label.setFont(new java.awt.Font("Tahoma", java.awt.Font.BOLD, 14));
                label.setHorizontalAlignment(SwingConstants.CENTER);
                label.setBounds(10, 24 + (count-1) * 30, 66, 14);
                contentPane.add(label);
                // 添加新文本框
                final JTextField textField = new JTextField();
                textField.setBounds(98, 21 + (count-1) * 30, 239, 20);
                textField.setColumns(10);
                contentPane.add(textField);
                // 将新文本框加入列表
                pdfTextFields.add(textField);
                // 添加新浏览按钮
                JButton browseButton = new JButton("Parcourir");
                browseButton.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        fileChooser = new JFileChooser();
                        fileChooser.setCurrentDirectory(new File(System.getProperty("user.home")));
                        int result = fileChooser.showOpenDialog(contentPane);
                        if (result == JFileChooser.APPROVE_OPTION) {
                            File selectedFile = fileChooser.getSelectedFile();
                            textField.setText(selectedFile.getAbsolutePath());
                        }
                    }
                });
                browseButton.setBounds(347, 20 + (count-1) * 30, 89, 23);
                contentPane.add(browseButton);
                // 调整窗口大小适配新行
                contentPane.setPreferredSize(
                    new java.awt.Dimension(contentPane.getWidth(), contentPane.getHeight() + 30));
                pack();
                
            }
        });
        btnAjouter.setBounds(10, 374, 89, 23);
        contentPane.add(btnAjouter);
        
        JButton btnGenerer = new JButton("Generer");
        btnGenerer.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                List<File> filesToMerge = new ArrayList<>();
                
                // 遍历所有文本框获取有效PDF文件
                for(JTextField field : pdfTextFields) {
                    String path = field.getText().trim();
                    if(!path.isEmpty()) {
                        File file = new File(path);
                        if(file.exists() && file.isFile() && file.getName().toLowerCase().endsWith(".pdf")) {
                            filesToMerge.add(file);
                        }
                    }
                }
                
                // 合并PDF文件
                if(filesToMerge.size() > 1) {
                    if(destPath == null || destPath.isEmpty()) {
                        JOptionPane.showMessageDialog(contentPane, "请选择目标文件夹。");
                        return;
                    }
                    
                    try {
                        PDFMergerUtility merger = new PDFMergerUtility();
                        for(File file : filesToMerge) {
                            merger.addSource(file);
                        }
                        merger.setDestinationFileName(destPath + File.separator + "merged.pdf");
                        merger.mergeDocuments(null);
                        
                        JOptionPane.showMessageDialog(contentPane, "合并成功!文件已保存至:" + destPath + File.separator + "merged.pdf");
                    } catch (Exception ex) {
                        ex.printStackTrace();
                        JOptionPane.showMessageDialog(contentPane, "合并过程中出错:" + ex.getMessage());
                    }
                } else {
                    JOptionPane.showMessageDialog(contentPane, "请至少选择两个PDF文件进行合并。");
                }
            }
        });
        btnGenerer.setBounds(185, 374, 89, 23);
        contentPane.add(btnGenerer);
        
        JButton btnFermer = new JButton("Fermer");
        btnFermer.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        btnFermer.setBounds(347, 374, 89, 23);
        contentPane.add(btnFermer);
        
        destField = new JTextField();
        destField.setBounds(136, 344, 217, 20);
        contentPane.add(destField);
        destField.setColumns(10);
    }
}

关键修改点

  1. 新增List<JTextField> pdfTextFields列表,专门存储所有PDF路径输入框
  2. 初始化时将初始文本框textpdf加入列表
  3. 点击"Ajouter"添加新文本框时,同步将其加入列表
  4. 合并逻辑改为遍历列表获取所有有效路径,彻底规避组件索引错误

额外优化

  • 增加路径非空校验和PDF格式验证
  • 增加目标路径为空的提示,避免空指针异常

内容的提问来源于stack exchange,提问作者Mohamed hilali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 07:54:54