java如何抓取空指针异常,获取空指针异常,并且不明白为什么

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.

Main

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

{

private final ListView 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 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);

}

}

DataModel

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 getMainListViewData()

{

ObservableList observableList = FXCollections.observableArrayList();

for (int i = 0; i < 250; i++) {

MainListViewCellData mainListViewCellData = new MainListViewCellData();

List 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 notes;

public MainListViewCellData(List notes)

{

this.notes = notes;

}

public MainListViewCellData()

{

this.notes = FXCollections.observableArrayList();

}

public List getNotes()

{

return notes;

}

public void setNotes(List notes)

{

this.notes = notes;

}

@Override

public String toString()

{

return '{' + "notes=" + notes + '}';

}

}

Note

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

{

TextArea textArea = new TextArea();

TitledPane titledPane = new TitledPane("", textArea);

ObservableList 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);

}

}

}

Error Message

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

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

解决方案

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

happens only when scrolling with mouse wheel

happens only when scrolling down

happens only if a Node in the inner cell (here a simple Button) is focused when scrolling

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

The example:

public class NPEDiggingSO extends Application {

private static class InnerListCell extends ListCell {

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 {

private ListView 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 model = FXCollections.observableArrayList(

"item1", "item2", "item3", "item4", "item5");

ListView 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);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值