获取空指针异常,并且不明白为什么 [英] Getting Null Pointer exception and Can't understand why

查看:87
本文介绍了获取空指针异常,并且不明白为什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在主ListView中向上和向下滚动时,我的程序似乎运行良好.当我打开TitledPane并使用鼠标滚轮快速向下或向上滚动时,会发生问题.我还注意到,如果在打开TitledPane后使用鼠标拖动滚动条,则一切正常.我想认为我非常擅长发现并修复我的NullPointer错误,但这使我感到困惑.我如何查明错误原因以及如何解决.如果我能理解发生了什么,我大概可以弄清楚第二部分.

My program seems to work fine when scrolling up and down in the main ListView. The problem happens when I open a TitledPane and scroll down or up fast using the mouse scroll-wheel. I also noticed that if I use the mouse to drag the scrollbar after opening a TitledPane, everything works fine. I would like to think that I am very good a spotting and fixing my NullPointer errors, but this one has me baffled. How do I pinpoint the cause of the error and how do I fix it. I can probably figure the second part out if I could understand what is going on.

主要

import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class NPEDiggingSO extends Application
{

    private static class OuterListCell extends ListCell<MainListViewCellData>
    {
        private final ListView<Note> cellListView;

        public OuterListCell()
        {
            setPrefHeight(300);
            setPrefWidth(300);

            cellListView = new ListView<>();
            cellListView.setCellFactory(v -> new NoteCell());
        }

        @Override
        protected void updateItem(MainListViewCellData item, boolean empty)
        {
            super.updateItem(item, empty);
            if (item == null || empty) {
                setText(null);
                setGraphic(null);
            }
            else {
                cellListView.getItems().setAll(item.getNotes());
                setGraphic(cellListView);
            }
        }

    }

    private Parent createContent()
    {
        DataModel model = new DataModel();
        ListView<MainListViewCellData> outer = new ListView<>(model.getMainListViewData());
        outer.setCellFactory(c -> new OuterListCell());
        BorderPane content = new BorderPane(outer);
        return content;
    }

    @Override
    public void start(Stage stage) throws Exception
    {
        stage.setScene(new Scene(createContent(), 700, 500));
        //stage.setTitle(FXUtils.version());
        stage.show();
    }

    public static void main(String[] args)
    {
        launch(args);
    }

}

数据模型

import java.util.ArrayList;
import java.util.List;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

/**
 *
 * @author blj0011
 */
public class DataModel
{
    public DataModel()
    {
    }

    public ObservableList<MainListViewCellData> getMainListViewData()
    {
        ObservableList<MainListViewCellData> observableList = FXCollections.observableArrayList();

        for (int i = 0; i < 250; i++) {
            MainListViewCellData mainListViewCellData = new MainListViewCellData();
            List<Note> notes = new ArrayList();
            notes.add(new Note("note title " + i, "note text " + 1));
            mainListViewCellData.setNotes(notes);
            observableList.add(mainListViewCellData);
        }

        return observableList;
    }
}

MainListViewCellData

    import java.util.List;
    import javafx.collections.FXCollections;

    /**
     *
     * @author blj0011
     */
    public class MainListViewCellData
    {
        private List<Note> notes;

        public MainListViewCellData(List<Note> notes)
        {
            this.notes = notes;
        }

        public MainListViewCellData()
        {
            this.notes = FXCollections.observableArrayList();
        }

        public List<Note> getNotes()
        {
            return notes;
        }

        public void setNotes(List<Note> notes)
        {
            this.notes = notes;
        }

        @Override
        public String toString()
        {
            return '{' + "notes=" + notes + '}';
        }
    }

注意

public class Note
{
    private String title;
    private String text;

    public Note(String title, String text)
    {
        this.title = title;
        this.text = text;
    }

    public String getText()
    {
        return text;
    }

    public void setText(String text)
    {
        this.text = text;
    }

    public String getTitle()
    {
        return title;
    }

    public void setTitle(String title)
    {
        this.title = title;
    }

    @Override
    public String toString()
    {
        StringBuilder sb = new StringBuilder();
        sb.append(", title=").append(title);
        sb.append(", text=").append(text);
        sb.append('}');
        return sb.toString();
    }
}

NoteCell

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.ListCell;
import javafx.scene.control.TextArea;
import javafx.scene.control.TitledPane;

public class NoteCell extends ListCell<Note>
{
    TextArea textArea = new TextArea();
    TitledPane titledPane = new TitledPane("", textArea);
    ObservableList<Note> observableList = FXCollections.observableArrayList();

    @Override
    public void updateItem(Note item, boolean empty)
    {
        super.updateItem(item, empty);
        if (item == null || empty) {
            setText(null);
            setGraphic(null);
        }
        else {
            titledPane.setExpanded(false);
            titledPane.setText(item.getTitle());
            titledPane.setAnimated(false);
            textArea.setText(item.getText());
            setGraphic(titledPane);
        }
    }
}

错误消息

Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
    at com.sun.javafx.scene.control.skin.VirtualFlow$4.findOwnerCell(VirtualFlow.java:848)
    at com.sun.javafx.scene.control.skin.VirtualFlow$4.select(VirtualFlow.java:822)
    at com.sun.javafx.scene.traversal.TraversalEngine.select(TraversalEngine.java:103)
    at com.sun.javafx.scene.traversal.TopMostTraversalEngine.trav(TopMostTraversalEngine.java:77)
    at javafx.scene.Scene.traverse(Scene.java:2005)
    at javafx.scene.Scene.focusIneligible(Scene.java:2024)
    at javafx.scene.Scene.access$3400(Scene.java:159)
    at javafx.scene.Scene$ScenePulseListener.focusCleanup(Scene.java:2370)
    at javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2385)
    at com.sun.javafx.tk.Toolkit.lambda$runPulse$2(Toolkit.java:398)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:397)
    at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:424)
    at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:561)
    at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:541)
    at com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromQueue(QuantumToolkit.java:534)
    at com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$11(QuantumToolkit.java:340)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$3(WinApplication.java:177)
    at java.lang.Thread.run(Thread.java:748)

PS

我要为自己的懒惰表示歉意,并感谢@kleopatra在我也有机会之前创建了MCVE.

I would like to apologize for being lazy and thank @kleopatra for creating the MCVE before I got the chance too.

推荐答案

没有解决方案,只是可以使用的MCVE和一些观察结果(我的情况是Win10,fx11).要查看错误,请单击最顶部单元格中的按钮,然后通过mouseWheel向下滚动.错误

No solution, just a MCVE to play with and some observations (my context is Win10, fx11). To see the error, click on the button in the top-most cell, then scroll down by mouseWheel. The error

  • 仅在使用鼠标滚轮滚动时发生
  • 仅在向下滚动时发生
  • 仅当滚动时内部单元格中的一个节点(这里是一个简单的Button)被聚焦时才发生

所以,是的,我想这是围绕focusTraversal的错误-但无法确定.

So, yeah, I would say it's a bug around focusTraversal - but unable to nail it.

示例:

public class NPEDiggingSO extends Application {

    private static class InnerListCell extends ListCell<String> {
        private Button button;

        public InnerListCell() {
            button = new Button();
        }

        @Override
        public void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);
            if (item == null || empty) {
                setText(null);
                setGraphic(null);
            } else {
                button.setText(item);
                setGraphic(button);
            }
        }

    }

    private static class OuterListCell extends ListCell<String> {
        private ListView<String> cellListView;

        public OuterListCell() {
            setPrefHeight(300);
            setPrefWidth(300);

            cellListView = new ListView<>();
            cellListView.setCellFactory(c -> new InnerListCell());
        }

        @Override
        protected void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);
            if (item == null || empty) {
                setText(null);
                setGraphic(null);
            } else {
                cellListView.getItems().setAll(item);
                setGraphic(cellListView);
            }
        }

    }

    private Parent createContent() {
        ObservableList<String> model = FXCollections.observableArrayList(
                "item1", "item2", "item3", "item4", "item5");
        ListView<String> outer = new ListView<>(model);
        outer.setCellFactory(c -> new OuterListCell());
        BorderPane content = new BorderPane(outer);
        return content;
    }

    @Override
    public void start(Stage stage) throws Exception {
        stage.setScene(new Scene(createContent()));
        stage.setTitle(FXUtils.version());
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

}

这篇关于获取空指针异常,并且不明白为什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆