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); } }
关键修改点
- 新增
List<JTextField> pdfTextFields列表,专门存储所有PDF路径输入框 - 初始化时将初始文本框
textpdf加入列表 - 点击"Ajouter"添加新文本框时,同步将其加入列表
- 合并逻辑改为遍历列表获取所有有效路径,彻底规避组件索引错误
额外优化
- 增加路径非空校验和PDF格式验证
- 增加目标路径为空的提示,避免空指针异常
内容的提问来源于stack exchange,提问作者Mohamed hilali
相关产品推荐
相关产品推荐

