好的,我会尽量让这个变得可以理解。
我创建了一个带有“打开”按钮和textArea的简单GUI(以及其他东西,但现在并不重要)。基本上我正在创建一个方法,当我单击“打开”按钮时,它会在textArea中显示文件的内容。
我相信我编写的99%的方法是正确的,但我一直得到一个NullPointerException,我不太明白为什么。希望我的代码能够清除我所要求的任何混淆,我会评论我得到异常的代码行。这是我的代码:
应用程序类(我的GUI的基本设置):
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
public class Application extends JFrame {
public OutputPanel outPanel = new OutputPanel();
public BarcodePanel barPanel = new BarcodePanel();
public ButtonPanel btnPanel = new ButtonPanel();
public ReferencePanel refPanel = new ReferencePanel();
public Application() {
super("Book Processor");
this.setLayout(new BorderLayout());
btnPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
outPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
refPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
add(btnPanel, BorderLayout.NORTH);
add(outPanel, BorderLayout.WEST);
add(refPanel,BorderLayout.SOUTH);
}//end constructor
public static void main(String[] args) {
Application frame = new Application();
frame.setSize(1000,500);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}//end main
}//end class
下一组代码是我的ButtonPanel类(这是我遇到问题的地方)所以我有一个openFile method
,当我点击按钮时它应该在textArea中显示文件的内容。我再次收到NullPointerException,我不明白为什么。以下是此类的代码:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.Closeable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Scanner;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class ButtonPanel extends JPanel{
JButton btnOpen = new JButton("Open");
OutputPanel outPanel = new OutputPanel();
Scanner input;
public ButtonPanel() {
ButtonHandler handler = new ButtonHandler();
add(btnOpen);
btnOpen.addActionListener(handler);
}//end constructor
/**
* Method for displaying the file onto the textArea.
*
*/
private void openFile() {
JFileChooser chooser = new JFileChooser();
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
int result = chooser.showOpenDialog(this);
String fileName;
fileName = chooser.getSelectedFile().getAbsolutePath();
try {
Scanner input = new Scanner(Paths.get(fileName));
StringBuilder sb = new StringBuilder();
while(input.hasNextLine()) {
sb.append(input.nextLine()+ "\n");
}
outPanel.txtOutput.setText(sb.toString());//my issue is with this line right here
} catch (IOException e) {
e.printStackTrace();
}
finally {
input.close();
}
}//end readFile
private class ButtonHandler implements ActionListener{
public void actionPerformed(ActionEvent e) {
if(e.getSource()== btnOpen) {
openFile();
}
}//end actionPerformed
}//end actionlistener
}//end class
这是我的最后一个类OutputPanel
,这个类包含JTextArea:
import java.awt.BorderLayout;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class OutputPanel extends JPanel{
public JTextArea txtOutput = new JTextArea(20,50);
public OutputPanel() {
add(txtOutput);
}//end constructor
}//end class
如何让textArea显示文件的内容?更重要的是,为什么我得到这个例外,我该怎么做才能解决它?希望这有尽可能的意义,我非常感谢你们的任何和所有的意见。
答案 0 :(得分:1)
您的NullPointerException
实际上是由
} finally {
input.close();
}
因为input
是null
(很明显)。这是因为您正在隐藏try-catch
块
try {
Scanner input = new Scanner(Paths.get(fileName));
//...
} finally {
// This is null because the instance field has not been initialised
input.close();
}
更好的解决方案是使用try-with-resources
statement
try (Scanner input = new Scanner(Paths.get(fileName))) {
StringBuilder sb = new StringBuilder();
while (input.hasNextLine()) {
sb.append(input.nextLine() + "\n");
}
outPanel.txtOutput.setText(sb.toString());//my issue is with this line right here
} catch (IOException e) {
e.printStackTrace();
}
更好的解决方案是利用JTextArea
的能力来阅读Reader
的内容,例如......
try (FileReader reader = new FileReader(chooser.getSelectedFile())) {
outPanel.txtOutput.read(reader, fileName);
} catch (IOException e) {
e.printStackTrace();
}
现在,在您问为什么文本区域中没有内容之前,原因是您在OutputPanel
类中创建了ButtonPanel
的新实例,这与您创建的实例没有任何关系在Application
中添加到屏幕中。
您需要将OutputPanel
的实例传递给ButtonPanel
(通过构造函数),以便引用匹配。
就个人而言,更好的解决方案是定义一个interface
,其read
方法采用File
。 OutputPanel
会实现此interface
,ButtonPanel
需要引用此interface
的实例。这会使代码分离并阻止ButtonPanel
对OutputPanel
进行不必要的更改 - 因为这样做并不是它的责任 - OutputPanel
负责加载文件并显示它< / p>