英文:
showOpenDialog() of JFileChooser doesn't open dialog box for opening files
问题
我正在编写一个用于合并PDF文件的GUI实用程序,但是JFileChooser的showOpenDialog()方法不会打开用于打开文件的对话框。单击“文件”菜单中的“打开”项目时没有任何反应。为了您的方便,Apache pdfbox库的下载链接如下:
https://pdfbox.apache.org/download.cgi
我尝试将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 {
// ...(后续代码未翻译)
}
英文:
I'm writing a GUI utility for merging pdf files but the showOpenDialog() method of JFileChooser doesn't open the dialog box for opening files. There is no response when the "Open" item in the File menu is clicked. For your convenience, the download link for the Apache pdfbox library is:
https://pdfbox.apache.org/download.cgi
I tried to move the guts of the openFiles() method into the corresponding location in the actionPerformed() method, but it still didn't work. However, in the code of another person for a different purpose, the showOpenDialog() method works in a method called from within the actionPerformed method. The code is as follows:
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
}
}
Thank you for your help.
答案1
得分: 1
我修复了你的代码并成功打开了 JFileChooser。
我所做的主要更改包括:
-
我使用了调用 SwingUtilities 的 invokeLater 方法来启动 Swing GUI。这个方法确保 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
}
}
英文:
I fixed your code and got the JFileChooser to open.
The major changes I made are:
-
I started the Swing GUI with a call to the SwingUtilities invokeLater method. This method ensures that the Swing components are created and executed on the Event Dispatch Thread.
-
I used a JFrame. I did not extend a JFrame. You only extend Swing components when you intend to override one or more of the class methods.
-
Your code was confusing to read. I divided the code into logical methods. I left your confusing code alone, but when you create Swing layouts, you really should create the components in row, column order. You should also group all of the method calls for a particular component together. It makes finding and solving problems easier.
-
You shouldn't have just one action listener for everything. You should have separate action listeners for each button or menu item.
Anyway, here's your code. Once I separated things logically, it was easier to find the mistakes which prevented your JFileChooser from displaying.
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
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论