javaFX tableview中的错误

时间:2014-03-21 08:11:40

标签: java javafx

我在包含两个TableView的javaFX中创建TableColumns。 TableView Span的宽度超过了所有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)

enter image description here

这是我的代码:(顺便说一下这段代码基于javaFX默认样本,并且在该示例中也会出现错误)

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

}

2 个答案:

答案 0 :(得分:2)

该错误仍然存​​在于Java 8u11中,但有一种解决方法:

table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);

这可以防止所有列的区域都可见,因此不再有堆栈跟踪。 这样做的缺点是所有列都将调整大小以适应表格宽度。

答案 1 :(得分:1)

我相信我发现了一个现有的错误报告:

https://javafx-jira.kenai.com/browse/RT-35338