重新填充TreeTableView后单击TreeTableCell时出现Javafx异常 [英] Javafx exception when clicking TreeTableCell after repopulating TreeTableView

查看:148
本文介绍了重新填充TreeTableView后单击TreeTableCell时出现Javafx异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前收到一条我不明白的错误。抛出的异常在我的代码中指向什么,但只有在我通过清除根项目的子项并向其添加一个新的集合och子项重新填充TreeTableView之后才会抛出它。

I am currently getting an error that I do not understand. The exception that is thrown points to nothing in my code, yet it is only thrown after I repopulate a TreeTableView by clearing the root item's children and adding a new set och children to it.

这是例外:

Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at javafx.scene.control.TreeTableView$TreeTableViewArrayListSelectionModel.handleSelectedCellsListChangeEvent(TreeTableView.java:3056)
at javafx.scene.control.TreeTableView$TreeTableViewArrayListSelectionModel.clearAndSelect(TreeTableView.java:2527)
at com.sun.javafx.scene.control.behavior.TableCellBehaviorBase.simpleSelect(TableCellBehaviorBase.java:209)
at com.sun.javafx.scene.control.behavior.TableCellBehaviorBase.doSelect(TableCellBehaviorBase.java:148)
at com.sun.javafx.scene.control.behavior.CellBehaviorBase.mousePressed(CellBehaviorBase.java:132)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:95)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3724)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3452)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1728)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2461)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:348)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:273)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:382)
at com.sun.glass.ui.View.handleMouseEvent(View.java:553)
at com.sun.glass.ui.View.notifyMouse(View.java:925)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$141(WinApplication.java:102)
at com.sun.glass.ui.win.WinApplication$$Lambda$37/1798286609.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)

小MCVE(按 - 以重新填充TreeTableView,然后编辑单元格以获取异常):

A small MCVE (press "-" in order to repopulate the TreeTableView, then edit a cell to get the exception):

package test;

import javafx.application.Application;
import javafx.beans.value.ObservableValue;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.TitledPane;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableColumn.CellDataFeatures;
import javafx.scene.control.TreeTableColumn.CellEditEvent;
import javafx.scene.control.TreeTableView;
import javafx.scene.control.cell.TextFieldTreeTableCell;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.stage.Stage;
import javafx.util.Callback;

public class BillingTableTest extends Application {

    private Stage stage;
    private Scene scene;
    private TitledPane pane;

    private TreeTableView<String> table;
    private TreeItem<String> root;

    /**
     * Start the program from scratch.
     * 
     * @param args
     *            Input arguments. Leave empty.
     */
    public static void main(String[] args) {
        launch(args);
    }

    /**
     * Start the program. Not usually called by the user, but by JavaFX. Nothing
     * fancy here, but setting up a basic TreeTableView with one column.
     */
    public void start(Stage stage) {
        this.stage = stage;
        pane = new TitledPane();
        scene = new Scene(pane);

        pane.setOnKeyReleased(new EventHandler<KeyEvent>() {

            @Override
            public void handle(KeyEvent event) {
                // TODO Auto-generated method stub
                if (event.getCode() == KeyCode.SUBTRACT) {
                    repopulate();
                }
            }
        });

        table = new TreeTableView<>();

        root = new TreeItem<>("Root");
        root.setExpanded(true);

        table.setRoot(root);
        table.setShowRoot(false);
        table.setEditable(true);

        TreeTableColumn<String, String> column = new TreeTableColumn<String, String>("String");

        column.setCellValueFactory(new Callback<TreeTableColumn.CellDataFeatures<String, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(CellDataFeatures<String, String> param) {
                // TODO Auto-generated method stub
                return param.getValue().valueProperty();
            }
        });
        column.setCellFactory(TextFieldTreeTableCell.forTreeTableColumn());
        column.setOnEditCommit(new EventHandler<TreeTableColumn.CellEditEvent<String, String>>() {
            @Override
            public void handle(CellEditEvent<String, String> t) {
                t.getTreeTablePosition().getTreeItem().setValue(t.getNewValue());
            }
        });

        table.getColumns().add(column);

        populate();

        pane.setContent(table);

        stage.setScene(scene);
        stage.show();

        System.out.println("TreeTableView has not been repopulated. Editing will not throw an exception.");
        System.out.println("Press - to repopulate it and break it.");
    }

    /**
     * Populate the TreeTableView with some dummy data.
     */
    private void populate() {
        for (int i = 1; i <= 10; i++) {
            String string = "String " + i;
            TreeItem<String> treeItem = new TreeItem<String>(string);
            root.getChildren().add(treeItem);
        }
    }

    /**
     * Clear root children (clears the TreeTableView). Cell editing is most
     * likely broken by this.
     */
    private void clear() {
        root.getChildren().clear(); // <- Most likely the problem.
    }

    /**
     * Repopulate the root node (repopulate the TreeTableView). After this
     * method is called, cell editing will throw an excetion.
     */
    private void repopulate() {
        clear(); // <- Most likely the problem.
        populate();
        System.out.println("TreeTableView has been repopulated. Editing will now throw an exception");
    }

}

我理解错误是相关的选择TreeTableCells,并在首次重新填充表格后选择一个。否则,在重新填充之前,一切都按预期工作,并且不会抛出任何异常。

I understand that the error is related to selecting TreeTableCells, and it occurs when selecting one after first repopulating the table. Otherwise, before repopulating, everything works as expected, and no exceptions are thrown whatsoever.

有什么问题?您是否不允许清除TreeTableRoow中的子ObservableList,还是应该以其他方式完成?

What is the problem? Are you not allowed to clear the children ObservableList in the TreeTableRoow, or should it be done in another way?

推荐答案

    private void populate() {
    root.getChildren().clear()
    for (int i = 1; i <= 10; i++) {
        String string = "String " + i;
        TreeItem<String> treeItem = new TreeItem<String>(string);
        root.getChildren().add(treeItem);

        // --------------Clear the selection -------------
        table.getSelectionModel().clearSelection();
        // -----------------------------------------------

    }
}

这篇关于重新填充TreeTableView后单击TreeTableCell时出现Javafx异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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