如何避免java可执行jar中的nullpointerexception?

lokaqttq  于 2021-07-14  发布在  Java
关注(0)|答案(1)|浏览(296)

我最小化应用程序以再现错误。我使用java8和intellijswing设计器来制作这个最小的gui应用程序。

public class MyGui {
private JList<String> docList;
private JPanel mainPanel;
private DefaultListModel<String> listDocModel;

public MyGui(){

    listDocModel = new DefaultListModel<>();

    try (InputStream resource = MyGui.class.getResourceAsStream("/data.csv");
         BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(resource, StandardCharsets.UTF_8))) {
        String line = "";
        while ((line = bufferedReader.readLine()) != null) {
            listDocModel.addElement(line);
        }
    } catch (IOException e) {
        System.out.println(e.getMessage());
    }
    docList.setModel(listDocModel); // I didn't initialize docList. But it works when run from the IDE.  
}

public static void main(String[] args) {
    JFrame frame = new JFrame("MyGui");
    frame.setContentPane(new MyGui().mainPanel);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setPreferredSize( new Dimension( 800, 800));
    frame.pack();
    frame.setVisible(true);
}
}

后来我用maven汇编插件做了一个jar。当我以 java -jar myap.jar 我得到一个空指针异常:-
线程中出现异常

"main" java.lang.NullPointerException
        at org.example.MyGui.<init>(MyGui.java:30)
        at org.example.MyGui.main(MyGui.java:38)

第30行是 docList.setModel(listDocModel); 所以我的问题是,为什么它可以通过ide工作,但不能通过jar工作呢。通过ide,我的列表中充满了如下数据:-

为了解决这个问题,我试着update:-

docList = new JList<>(listDocModel);
   mainPanel = new JPanel();
   mainPanel.add(docList);

在这之后,我的名单不再是空的data:-

那么,我该如何用数据制作列表并制作一个可执行文件呢 jar ?
完全更新project:-
https://github.com/masiboo/swinggui

pprl5pva

pprl5pva1#

// I didn't initialize docList. But it works when run from the IDE.

在这种情况下,ide才是问题所在。可能做一个“清理和构建”会把小精灵们甩出去,但是我不能提供对ide的支持。
这个 docList ( mainPanel 等等)都需要在使用前示例化。
除此之外,列表需要放在gui上可见的容器中,最好 Package 在滚动窗格中(如本例所示)。

最后一点注意:它在评论中指出,“文件加载很好”。这是一个很好的时机,将其从示例中排除,并使用硬编码数据,如下所示。下面的mre就是这样做的——所以任何人都可以运行它来查看它的工作(或者失败)。准备并张贴一个最小的可复制的例子,像这样的最好的帮助。

import java.awt.*;
import javax.swing.*;

public class MyGui {

    // what happens in the IDE is irrelevant, this needs to be instantiated
    private JList<String> docList = new JList<>();
    // .. as does this
    private JPanel mainPanel = new JPanel(new BorderLayout());
    private DefaultListModel<String> listDocModel;
    // if the problem is not I/O related, factor it out by hard coding data
    private String[] data = {
        "Apples,are,Crunchy",
        "Oranges,are,Orange",
        "Bananas,are,Bent",};

    public MyGui() {
        listDocModel = new DefaultListModel<>();

        for (String line : data) {
            listDocModel.addElement(line);
        }
        // I didn't initialize docList. But it works when run from the IDE.
        // THEN THE IDE IS THE PROBLEM. Possibly fixed with a 'clean and build'.
        docList.setModel(listDocModel); 

        // now add the list to the panel! 
        mainPanel.add(new JScrollPane(docList));
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("MyGui");
        frame.setContentPane(new MyGui().mainPanel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // Avoid guesses, pack will produce the min size needed to display GUI
        //frame.setPreferredSize(new Dimension(..));
        frame.pack();
        frame.setVisible(true);
    }
}

相关问题