Java JFileChooser的showOpenDialog()不';t打开用于打开文件的对话框

Java JFileChooser的showOpenDialog()不';t打开用于打开文件的对话框,java,swing,jfilechooser,Java,Swing,Jfilechooser,我正在编写一个用于合并pdf文件的GUI实用程序,但是JFileChooser的showOpenDialog()方法无法打开打开文件的对话框。单击“文件”菜单中的“打开”项时没有响应。为方便起见,Apache pdfbox库的下载链接为: 我试图将openFiles()方法的核心移动到actionPerformed()方法中相应的位置,但仍然不起作用。但是,在另一个人出于不同目的编写的代码中,showOpenDialog()方法在actionPerformed方法中调用的方法中工作。代码如下:

我正在编写一个用于合并pdf文件的GUI实用程序,但是JFileChooser的showOpenDialog()方法无法打开打开文件的对话框。单击“文件”菜单中的“打开”项时没有响应。为方便起见,Apache pdfbox库的下载链接为:

我试图将openFiles()方法的核心移动到actionPerformed()方法中相应的位置,但仍然不起作用。但是,在另一个人出于不同目的编写的代码中,showOpenDialog()方法在actionPerformed方法中调用的方法中工作。代码如下:

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import org.apache.pdfbox.multipdf.PDFMergerUtility;

public class PDFMerger extends JFrame implements ActionListener {
    private static final int DEFAULT_WIDTH = 500;
    private static final int DEFAULT_HEIGHT = 500;
    private JMenuItem openItem;
    private JMenuItem saveItem;
    private JMenuItem exitItem;
    private JTextArea textArea;
    private JTextField textField;
    private JButton bindButton;
    private File[] files;
    private File mergedFile;

    public static void main(String[] args) {
        PDFMerger pdfMerger = new PDFMerger();
        pdfMerger.setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
        pdfMerger.setDefaultCloseOperation(EXIT_ON_CLOSE);
        pdfMerger.setVisible(true);
    }

    public PDFMerger () {
        JMenu menu = new JMenu("File");
        JMenuItem openItem = new JMenuItem("Open");
        openItem.addActionListener(this);
        saveItem = new JMenuItem("Save");
        saveItem.setEnabled(false);
        saveItem.addActionListener(this);
        exitItem = new JMenuItem("Exit");
        exitItem.addActionListener(this);
        menu.add(openItem);
        menu.add(saveItem);
        menu.add(exitItem);
        JMenuBar menuBar = new JMenuBar();
        menuBar.add(menu);
        setJMenuBar(menuBar);
        textArea = new JTextArea(40, 50);
        JScrollPane scrollPane = new JScrollPane(textArea);
        add(scrollPane, BorderLayout.CENTER);
        JPanel operationPanel = new JPanel();
        BoxLayout layout = new BoxLayout(operationPanel, BoxLayout.LINE_AXIS);
        operationPanel.setLayout(layout);
        JLabel label = new JLabel("Result: ");
        textField = new JTextField(30);
        textField.setEditable(false);
        bindButton = new JButton("Bind");
        bindButton.addActionListener(this);
        bindButton.setEnabled(false);
        operationPanel.add(label);
        operationPanel.add(textField);
        operationPanel.add(bindButton);
        add(operationPanel, BorderLayout.NORTH);
    }

    public void actionPerformed (ActionEvent event) {

        if (event.getSource() == exitItem) 
            System.exit(0);
        else if (event.getSource() == openItem) {
            files = openFiles();
            bindButton.setEnabled(false);
        }
        else if (event.getSource() == bindButton) {
            mergedFile = mergeFiles();
            saveItem.setEnabled(true);
        }
        else if (event.getSource() == saveItem)
            saveFile();
    }

    public File[] openFiles () {
        File[] selectedFiles = null;
        JFileChooser chooser = new JFileChooser();
        chooser.setCurrentDirectory(new File("."));
        chooser.setMultiSelectionEnabled(true);
        int option = chooser.showOpenDialog(PDFMerger.this);

        if (option == JFileChooser.APPROVE_OPTION) 
            selectedFiles = chooser.getSelectedFiles();
        return selectedFiles;
    }

    public File mergeFiles () {
        File merged = null;
        // TODO

        return merged;
    }
    public void saveFile () {
        //TODO
    }
}

谢谢您的帮助。

我修复了您的代码并打开了JFileChooser

我所做的主要改变是:

  • 我通过调用SwingUtilities invokeLater方法启动了SwingGUI。此方法确保在上创建和执行Swing组件

  • 我用的是JFrame。我没有扩展JFrame。仅当您打算重写一个或多个类方法时才扩展Swing组件

  • 你的代码读起来很混乱。我将代码划分为逻辑方法。我没有理会您的混乱代码,但是当您创建Swing布局时,您确实应该按行、列顺序创建组件。您还应该将特定组件的所有方法调用分组在一起。它使发现和解决问题更容易

  • 你不应该每件事都只有一个动作监听器。每个按钮或菜单项都应该有单独的操作侦听器

  • 不管怎样,这是你的密码。一旦我按逻辑将事情分开,就更容易找到阻止JFileChooser显示的错误

    import java.awt.*;
    import java.awt.event.*;
    import java.io.*;
    import javax.swing.*;
    
    public class PDFMerger implements ActionListener {
    
        private JFrame frame;
        private JMenuItem openItem;
        private JMenuItem saveItem;
        private JMenuItem exitItem;
        private JTextArea textArea;
        private JTextField textField;
        private JButton bindButton;
        private File[] files;
        private File mergedFile;
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new PDFMerger();
                }
            });
        }
    
        public PDFMerger() {
            frame = new JFrame("PDF Merger");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            JMenuBar menuBar = createJMenuBar();
            frame.setJMenuBar(menuBar);
    
            JPanel operationPanel = createOperationPanel();
            frame.add(operationPanel, BorderLayout.NORTH);
            JPanel textPanel = createTextPanel();
            frame.add(textPanel, BorderLayout.CENTER);
    
            frame.pack();
            frame.setLocationByPlatform(true);
            frame.setVisible(true);
        }
    
        private JPanel createOperationPanel() {
            JPanel operationPanel = new JPanel();
            BoxLayout layout = new BoxLayout(operationPanel, BoxLayout.LINE_AXIS);
            operationPanel.setLayout(layout);
            JLabel label = new JLabel("Result: ");
            textField = new JTextField(30);
            textField.setEditable(false);
            bindButton = new JButton("Bind");
            bindButton.addActionListener(this);
            bindButton.setEnabled(false);
            operationPanel.add(label);
            operationPanel.add(textField);
            operationPanel.add(bindButton);
            return operationPanel;
        }
    
        private JPanel createTextPanel() {
            JPanel panel = new JPanel();
            panel.setLayout(new BorderLayout());
    
            textArea = new JTextArea(40, 50);
            JScrollPane scrollPane = new JScrollPane(textArea);
            panel.add(scrollPane, BorderLayout.CENTER);
            return panel;
        }
    
        private JMenuBar createJMenuBar() {
            JMenu menu = new JMenu("File");
            openItem = new JMenuItem("Open");
            openItem.addActionListener(this);
            saveItem = new JMenuItem("Save");
            saveItem.setEnabled(false);
            saveItem.addActionListener(this);
            exitItem = new JMenuItem("Exit");
            exitItem.addActionListener(this);
            menu.add(openItem);
            menu.add(saveItem);
            menu.add(exitItem);
            JMenuBar menuBar = new JMenuBar();
            menuBar.add(menu);
            return menuBar;
        }
    
        @Override
        public void actionPerformed (ActionEvent event) {
            if (event.getSource() == exitItem) {
                frame.dispose();
                System.exit(0);
            } else if (event.getSource() == openItem) {
                files = openFiles();
                bindButton.setEnabled(false);
            } else if (event.getSource() == bindButton) {
                mergedFile = mergeFiles();
                saveItem.setEnabled(true);
            } else if (event.getSource() == saveItem)
                saveFile();
        }
    
        public File[] openFiles () {
            File[] selectedFiles = null;
            JFileChooser chooser = new JFileChooser();
            chooser.setCurrentDirectory(new File("."));
            chooser.setMultiSelectionEnabled(true);
            int option = chooser.showOpenDialog(frame);
    
            if (option == JFileChooser.APPROVE_OPTION) 
                selectedFiles = chooser.getSelectedFiles();
            return selectedFiles;
        }
    
        public File mergeFiles () {
            File merged = null;
            // TODO
    
            return merged;
        }
        public void saveFile () {
            //TODO
        }
    }
    

    谢谢你,Gilbert Le Blanc。你说得对。我应该使用事件调度线程和单独的ActionListener线程。与我的意大利面代码相比,您的代码非常清晰紧凑。我想知道如何调试像我自己一样的代码。你能推荐一些工具和技术吗?谢谢大家!@MichaelMay:我的代码编辑器是Eclipse。我认真对待所有编译器警告,并努力消除它们。在您的代码中,一旦每个方法只有20行左右的代码,我就可以查看代码,并将我看到的与我知道的正确代码进行比较。不幸的是,这种能力来自于编码经验,尤其是创建和发现自己错误的经验。@MichaelMay:在阅读代码时,尽量少用空行分隔方法的各个部分会有所帮助。有时,您必须在不同的位置放置System.out.println语句,以确保代码正常运行。我使用调试器作为最后手段,因为隔离问题可能需要一段时间,特别是在Swing GUI之类的事件驱动代码中。尽量减少类字段。并非每个字段都需要是类字段。将所有字段都指定给某个方法,并将某个字段设置为类字段(当且仅当该字段在类中的其他地方是必需的)。感谢您提供的提示。我认为我需要编写更多的代码来获得经验,并从错误中学到更多。