【问题标题】:image loading using a JFileChooser into a JFrame使用 JFileChooser 将图像加载到 JFrame
【发布时间】:2012-05-24 11:56:19
【问题描述】:

我正在尝试编写一个代码,将使用 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);
    }
}

【问题讨论】:

  • catch(IOException e1) {} 永远不要在损坏的代码中这样做!取而代之的是catch(IOException e1) { e1.printStackTrace(); }

标签: java swing jpanel jlabel imageicon


【解决方案1】:

img 的值只有在用户单击按钮并选择要显示的文件后才具有实际值。直到此时,img 的值是null,所以当它继续通过你的方法并调用ImageIcon icon=new ImageIcon(img); 行时,它正在尝试为null 创建一个ImageIcon 对象。

要更正此问题,您应该仅在用户选择文件时创建ImageIcon。这是一个应该更接近正常工作的更改。 (请参阅下面代码中的 cmets //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
  3. 调整标签大小,然后调整revalidate()repaint() 以确保图像在设置后被绘制。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-04
      • 2016-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-05
      • 2014-02-07
      相关资源
      最近更新 更多