JavaFXTableView中出现错误

JavaFXTableView中出现错误,java,javafx,Java,Javafx,我在javaFX中创建了TableView,其中包含两个TableColumns。TableView的宽度大于所有TableColumn的宽度,但这不是问题所在。我不明白的是,当我在包含数据的行的外部区域和列的外部区域(红色区域)中单击时,我得到了一个错误。有人能解释一下为什么会发生这种错误吗 run: Exception in thread "JavaFX Application Thread" java.lang.NullPointerException at javafx.scene.co

我在javaFX中创建了
TableView
,其中包含两个
TableColumns
。TableView的宽度大于所有
TableColumn
的宽度,但这不是问题所在。我不明白的是,当我在包含数据的行的外部区域和列的外部区域(红色区域)中单击时,我得到了一个错误。有人能解释一下为什么会发生这种错误吗

run:
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at javafx.scene.control.TableView$TableViewArrayListSelectionModel.handleSelectedCellsListChangeEvent(TableView.java:2657)
at javafx.scene.control.TableView$TableViewArrayListSelectionModel.clearAndSelect(TableView.java:2180)
at javafx.scene.control.TableView$TableViewArrayListSelectionModel.clearAndSelect(TableView.java:2140)
at com.sun.javafx.scene.control.behavior.TableRowBehavior.doSelect(TableRowBehavior.java:196)
at com.sun.javafx.scene.control.behavior.TableRowBehavior.mousePressed(TableRowBehavior.java:88)
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.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:204)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3689)
at javafx.scene.Scene$MouseHandler.access$1800(Scene.java:3414)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1676)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2467)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:314)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:243)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:345)
at com.sun.glass.ui.View.handleMouseEvent(View.java:526)
at com.sun.glass.ui.View.notifyMouse(View.java:898)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$300(WinApplication.java:39)
at com.sun.glass.ui.win.WinApplication$4$1.run(WinApplication.java:112)
at java.lang.Thread.run(Thread.java:744)
BUILD SUCCESSFUL (total time: 5 seconds)

这是我的代码:(顺便说一句,这段代码基于javaFX默认示例,在该示例中也会发生错误)

包fjr.java.proyek.tex;
//导入java.awt.TextField;
导入javafx.application.application;
导入javafx.beans.property.BooleanProperty;
导入javafx.beans.property.SimpleBoleAnProperty;
导入javafx.beans.property.SimpleStringProperty;
导入javafx.beans.property.StringProperty;
导入javafx.beans.value.ChangeListener;
导入javafx.beans.value.observeValue;
导入javafx.collections.FXCollections;
导入javafx.collections.ObservableList;
导入javafx.event.EventHandler;
导入javafx.geometry.Pos;
导入javafx.scene.Group;
导入javafx.scene.scene;
导入javafx.scene.control.CheckBox;
导入javafx.scene.control.TableCell;
导入javafx.scene.control.TableColumn;
导入javafx.scene.control.TableColumn.CellEditEvent;
导入javafx.scene.control.TableView;
导入javafx.scene.control.TextField;
导入javafx.scene.control.cell.PropertyValueFactory;
导入javafx.scene.input.KeyCode;
导入javafx.scene.input.KeyEvent;
导入javafx.stage.stage;
导入javafx.util.Callback;
公共类ChangeCurrentFrame扩展了应用程序{
双倍宽度=400;
双倍高度=400;
public void start(Stage)引发异常{
组根=新组();
舞台场景(新场景(根、宽、高);
root.getChildren().add(getTable());
stage.show();
}
公共表视图getTable(){
TableView选项卡=新建TableView();
TableColumn stateColumn=新建TableColumn();
stateColumn.setText(“是编译的”);
stateColumn.setMinWidth(60);
stateColumn.setCellValueFactory(新属性ValueFactory(“启用”);
stateColumn.setCellFactory(新回调(){
@凌驾
公用电话(
TableColumnp){
返回新的TableCell(){
私有复选框;
私有可观测值ov;
{
复选框=新复选框();
复选框。设置对齐(位置中心);
设置对齐(位置中心);
设置图形(复选框);
}
@重写公共void updateItem(布尔项,布尔空){
super.updateItem(项,空);
if(空){
setText(空);
设置图形(空);
}否则{
设置图形(复选框);
if(ov instanceof BooleanProperty){
复选框.selectedProperty().unbindBidirectional((BooleanProperty)ov);
}
ov=getTableColumn().getCellObservableValue(getIndex());
if(ov instanceof BooleanProperty){
复选框.selectedProperty().bindBidirectional((BooleanProperty)ov);
}
}
}
};
}
}); 
TableColumn name column=新建TableColumn();
nameColumn.setText(“标签”);
nameColumn.setMinWidth(80);
nameColumn.setCellValueFactory(新属性ValueFactory(“名称”);
nameColumn.setCellFactory(新回调(){
@凌驾
公用电话(
表(列arg0){
返回新的TableCell(){
私有文本字段文本字段;
@覆盖公共void startEdit(){
super.startEdit();
if(textField==null){
createTextField();
}
setText(空);
设置图形(文本字段);
textField.selectAll();
}
@覆盖公共作废取消编辑(){
super.cancelEdit();
setText((字符串)getItem());
设置图形(空);
}
@重写公共void updateItem(字符串项,布尔值为空){
super.updateItem(项,空);
if(空){
setText(空);
设置图形(空);
}否则{
if(isEditing()){
if(textField!=null){
setText(getString());
}
setText(空);
设置图形(文本字段);
}否则{
setText(getString());
设置图形(空);
}
}
}
私有字符串getString(){
返回getItem()==null?”:getItem().toString();
}
普里瓦特
package fjr.java.proyek.tex;

//import java.awt.TextField;

import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellEditEvent;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.stage.Stage;
import javafx.util.Callback;

public class ChangeCurrentFrame  extends Application{

    double width = 400; 
    double height = 400; 

    public void start(Stage stage) throws Exception {
        Group root = new Group(); 
        stage.setScene(new Scene (root , width, height)); 
        root.getChildren().add(getTable()); 
        stage.show();
    }

    public TableView<CurrentFrame > getTable(){
        TableView<CurrentFrame> tabel = new TableView<CurrentFrame>(); 
        TableColumn<CurrentFrame, Boolean> stateColumn = new TableColumn<CurrentFrame, Boolean>(); 
        stateColumn.setText("Is Compile"); 
        stateColumn.setMinWidth(60);        
        stateColumn.setCellValueFactory(new PropertyValueFactory<CurrentFrame, Boolean>("enable")) ; 
        stateColumn.setCellFactory(new Callback<TableColumn<CurrentFrame, Boolean>, 
                TableCell<CurrentFrame, Boolean>>(){
            @Override
            public TableCell<CurrentFrame, Boolean> call(
                    TableColumn< CurrentFrame, Boolean> p ){
                return new TableCell<CurrentFrame, Boolean>(){
                    private CheckBox checkBox; 
                    private ObservableValue<Boolean>  ov; 

                    {
                        checkBox = new CheckBox(); 
                        checkBox.setAlignment(Pos.CENTER); 
                        setAlignment(Pos.CENTER); 
                        setGraphic(checkBox);
                    }

                    @Override public void updateItem(Boolean item, boolean empty){
                        super.updateItem(item, empty); 
                        if(empty){
                            setText(null);
                            setGraphic(null);
                        }else{
                            setGraphic(checkBox);
                            if(ov instanceof BooleanProperty){
                                checkBox.selectedProperty(). unbindBidirectional((BooleanProperty) ov);
                            }
                            ov = getTableColumn().getCellObservableValue(getIndex()); 
                            if(ov instanceof BooleanProperty){
                                checkBox.selectedProperty(). bindBidirectional((BooleanProperty) ov);
                            }
                        }
                    }
                };
            }
        }); 

        TableColumn<CurrentFrame, String> nameColumn = new TableColumn<CurrentFrame, String>(); 
        nameColumn.setText("Label"); 
        nameColumn.setMinWidth(80); 
        nameColumn.setCellValueFactory(new PropertyValueFactory<CurrentFrame, String>("name"));
        nameColumn.setCellFactory(new Callback<TableColumn<CurrentFrame, String>, 
                TableCell<CurrentFrame, String>>() {
                    @Override
                    public TableCell<CurrentFrame, String> call(
                            TableColumn<CurrentFrame, String> arg0) {
                        return new TableCell<CurrentFrame,String>(){

                            private TextField textField; 

                            @Override public void startEdit(){
                                super.startEdit();
                                if(textField == null){
                                    createTextField();
                                }
                                setText(null);
                                setGraphic(textField);
                                textField.selectAll();
                            }

                            @Override public void cancelEdit(){
                                super.cancelEdit(); 
                                setText((String) getItem()); 
                                setGraphic(null); 
                            }

                            @Override public void updateItem(String item, boolean empty){
                                super.updateItem(item, empty);
                                if(empty){
                                    setText(null); 
                                    setGraphic(null);
                                }else{
                                    if(isEditing()){
                                        if(textField != null){
                                            textField.setText(getString());
                                        }
                                        setText(null);
                                        setGraphic(textField);
                                    }else{
                                        setText(getString()); 
                                        setGraphic(null);
                                    }
                                }
                            }

                            private String getString(){
                                return getItem() == null ? "" : getItem().toString(); 
                            }

                            private void createTextField(){
                                textField = new TextField(getString()); 
                                textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
                                textField.setOnKeyReleased(new EventHandler<KeyEvent>() {
                                    @Override
                                    public void handle(KeyEvent t) {
                                        if(t.getCode() == KeyCode.ENTER){
                                            commitEdit(textField.getText());
                                        }else if(t.getCode() == KeyCode.ESCAPE){
                                            cancelEdit();
                                        }
                                    }
                                });
                            }

                        };
                    }
        });

        nameColumn.setOnEditCommit(new EventHandler<CellEditEvent<CurrentFrame, String >>() {
            @Override
            public void handle(CellEditEvent<CurrentFrame, String> t) {
                   ((CurrentFrame) t.getTableView().getItems().get(
                            t.getTablePosition().getRow())).setName(t.getNewValue());
            }
        });


        tabel.setItems(getData());
        tabel.setEditable(true); 
        tabel.getColumns().addAll(stateColumn, nameColumn);  

        return tabel ; 
    }

    public  ObservableList<CurrentFrame> getData(){
        return FXCollections.observableArrayList(
                new CurrentFrame(true, "makan"), 
                new CurrentFrame(false, "siang"), 
                new CurrentFrame(false, "jangan"), 
                new CurrentFrame(true, "suka"), 
                new CurrentFrame(false, "ribut")) ; 
    }

    public static  class CurrentFrame { // ini harus publik ya.... 
        private BooleanProperty  isEnable; 
        private StringProperty framename; 

        private  CurrentFrame(boolean enable, String name){
            this.isEnable = new SimpleBooleanProperty(enable); 
            this.framename = new SimpleStringProperty(name);    
            isEnable.addListener(new ChangeListener<Boolean>() {
                @Override
                public void changed(ObservableValue<? extends Boolean> arg0,
                        Boolean t2, Boolean t1) {
                    System.out.println(nameProperty().get()+" enable "+ t1 ); 
                }
            });
        }

        public void setEnable(boolean state){
            isEnable.set(state);
        }

        public void setName(String name){
            this.framename.set(name);
        }

        public BooleanProperty enableProperty(){
            return isEnable; 
        }

        public StringProperty nameProperty(){
            return framename; 
        }
    }   

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

}
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);