我正在尝试编写一个代码,将使用JFileChooser选择的图像显示到另一个JFrame中。我尝试了下面的代码,但只是出现了以下错误。
Exception in thread "main" java.lang.NullPointerException
at javax.swing.ImageIcon.<init>(ImageIcon.java:228)
at power.<init>(fCGUI.java:53)
at fCGUI.main(fCGUI.java:11)
以下是代码:
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class fCGUI
{
public static void main(String []args)
{
power p=new power();
p.setVisible(true);
}
}
class power extends JFrame
{
JFileChooser chooser;
BufferedImage img;
JButton button,button2;
JFrame comp;
String filename;
File file ;
public power()
{
setSize(450,450);
panel.setLayout(new BorderLayout());
JPanel panel=new JPanel();
getContentPane().add(panel);
button =new JButton("press");
panel.add(button,BorderLayout.NORTH);
chooser = new JFileChooser();
ActionListener action=new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
if (e.getSource()==button)
{
chooser.showOpenDialog(null);
file = chooser.getSelectedFile();
try
{
img=ImageIO.read(file);
}
catch(IOException e1) {}
}
if (e.getSource()==button2)
{
comp.setVisible(true);
}
}
};
ImageIcon icon=new ImageIcon(img);
JLabel label=new JLabel(icon);
JPanel secpanel=new JPanel();
comp=new JFrame();
comp.setSize(650,500);
comp.setLayout(new BorderLayout());
comp.setTitle("View Report");
JRootPane compPane=comp.getRootPane();
Container contePane=compPane.getContentPane();
contePane.add(secpanel);
secpanel.add(label,BorderLayout.CENTER);
button2=new JButton("access");
button2.addActionListener(action);
button.addActionListener(action);
panel.add(button2,BorderLayout.SOUTH);
}
}
答案 0 :(得分:3)
在用户单击按钮并选择要显示的文件后,img
的值将只有实际值。在此之前,img
的值为null
,因此当它继续通过您的方法并调用行ImageIcon icon=new ImageIcon(img);
时,它会尝试为ImageIcon
创建一个null
对象{1}}。
要解决此问题,您应该只在用户选择文件时创建ImageIcon
。这是一个应该更接近正常工作的变化。 (请参阅以下代码中的评论//ADDED
和//REMOVED
,以查看更改...
...
class power extends JFrame {
JFileChooser chooser;
BufferedImage img;
JButton button,button2;
JFrame comp;
String filename;
File file ;
JLabel label; // ADDED
public power() {
...
public void actionPerformed(ActionEvent e) {
if (e.getSource()==button) {
chooser.showOpenDialog(null);
file = chooser.getSelectedFile();
try {
img=ImageIO.read(file);
ImageIcon icon=new ImageIcon(img); // ADDED
label.setIcon(icon); // ADDED
Dimension imageSize = new Dimension(icon.getIconWidth(),icon.getIconHeight()); // ADDED
label.setPreferredSize(imageSize); // ADDED
label.revalidate(); // ADDED
label.repaint(); // ADDED
}
catch(IOException e1) {}
}
if (e.getSource()==button2){
comp.setVisible(true);
}
}
};
//ImageIcon icon=new ImageIcon(img); // REMOVED
//JLabel label=new JLabel(icon); // REMOVED
label = new JLabel(); // ADDED
JPanel secpanel=new JPanel();
...
解释我改变了什么......
label
现在将创建为空JLabel
。它也存储为全局变量,以便我们以后可以访问它img
,然后使用label
setIcon();
revalidate()
和repaint()
以确保图片在设置后绘制。答案 1 :(得分:1)
ImageIO.read
仅在按下特定JButton
时执行。那是因为它在ActionListener
内。因此,img
为空,导致执行NullPointerException
时出现ImageIcon icon=new ImageIcon(img)
。