使用JFileChooser将图像加载到JFrame中

我正在尝试编写一个代码,将使用JFileChooser选择的图像显示到另一个JFrame中。我尝试了下面的代码,但只得到以下错误。

Exception in thread "main" java.lang.NullPointerException at javax.swing.ImageIcon.(ImageIcon.java:228) at power.(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); } } 

在用户单击按钮并选择要显示的文件后, img的值将仅具有实际值。 在此之前, img值为null ,因此当它继续通过您的方法并调用行ImageIcon icon=new ImageIcon(img); ,它试图为null创建一个ImageIcon对象。

要解决此问题,您应该只在用户选择文件时创建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(); ... 

解释我改变了什么……

  1. 首次启动程序时, label现在将创建为空的JLabel 。 它也存储为全局变量,以便我们以后可以访问它
  2. 单击该按钮时,将像以前一样创建img ,然后使用setIcon();将其加载到label setIcon();
  3. 调整标签大小,然后revalidate()repaint()以确保在设置图像后绘制图像。

只有在按下特定的JButton时才会执行ImageIO.read 。 那是因为它在ActionListener 。 因此, img为null,当执行ImageIcon icon=new ImageIcon(img)时会导致NullPointerException