Моя программа работает нормально при прокрутке вверх и вниз в главном ListView
. Проблема возникает, когда я открываю TitledPane
и быстро прокручиваю вниз или вверх с помощью колесика прокрутки мыши. Я также заметил, что если я перетаскиваю полосу прокрутки мышью после открытия TitledPane
, все работает нормально. Я хотел бы думать, что я очень хорошо обнаруживаю и исправляю свои NullPointer
ошибки, но это меня сбило с толку. Как определить причину ошибки и как ее исправить. Я мог бы, вероятно, понять вторую часть, если бы мог понять, что происходит.
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<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);
}
}
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<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 перед У меня тоже есть шанс.