javaFX tableview中的错误 [英] Error in javaFX tableview

查看:144
本文介绍了javaFX tableview中的错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在javaFX中创建 TableView ,其中包含两个 TableColumns 。 TableView Span的宽度超过了所有 TableColumn 的宽度,但它不是问题。我不明白的是当我点击包含数据的行外的区域以及列的外部区域(红色区域)时,我收到错误。谁能解释为什么会出现这种错误?

I make TableView in javaFX that contain two TableColumns. The width of TableView Span more than the width Of all TableColumn, but its not the problem. What I did not understand Is when I click in area outside the row that contain data, and outside area of column (red area), I get an error. Can anyone explain to me why this error occur?

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默认样本,并且在该示例中错误也是发生)

This is my code: (btw this code based on javaFX default sample, and in that sample the error also occur)

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

}


推荐答案

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

The bug is still present in Java 8u11, but there is a workaround:

table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);

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

this prevents the area right to all the columns from being visible, thus no more stack traces. The downside of this is that all columns will be resized to fit the table width.

这篇关于javaFX tableview中的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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