Javafx TableView自定义CellFactory

时间:2012-12-04 07:54:16

标签: javafx

我是java的新手,老老实实地编程。我正在研究一个小工具。其中一个功能是伪ftp客户端显示ftp主机上的内容,也允许在不同的文件夹之间切换。对于文件/文件夹列表我正在使用TableView。现在我想调整视觉内容,并根据文件或文件夹的内容将一些图形添加到单元格中。但是当我在我的CellFactory中使用以下代码时,它不仅在完全填充语句的单元格上设置Graphic,进一步向上和向下滚动TableView时,图形会随机出现在不同的单元格上,几秒钟后它就会崩溃。

    public BorderPane addFTPBorderPane(){

    ftpBorderpane = new BorderPane();
    ftpBorderpane.setPadding(new Insets(0));
    GridPane grid = new GridPane();
    grid.setPadding(new Insets(10));
    grid.setHgap(20);
    grid.setId("simplebluegradient");
    Button getFTPButton = new Button("Verbinden");
    grid.add(getFTPButton, 1, 0);
    ftpBorderpane.setTop(grid);

    VBox vbox = new VBox();
    final TableView<MyFTPFile> ftpTable = new TableView<MyFTPFile>();

    Callback<TableColumn<MyFTPFile,String>, TableCell<MyFTPFile,String>> cellFactory =
            new Callback<TableColumn<MyFTPFile,String>, TableCell<MyFTPFile,String>>() {
                public TableCell<MyFTPFile,String> call(TableColumn<MyFTPFile,String> p) {
                    cell = new TableCell<MyFTPFile, String>() {
                        @Override
                        public void updateItem(String item, boolean empty) {
                            super.updateItem(item, empty);
                            setText(item);
                            if(item.equals("test")){
                                Image folderIcon = new Image(imagesPath+"folder.png");
                                setGraphic(new ImageView(folderIcon));
                            }

                        }

                    };

                    cell.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
                        @Override
                        public void handle(MouseEvent event) {
                            if (event.getClickCount() > 1) {
                                cell = (TableCell<MyFTPFile,String>) event.getSource();
                                System.out.println(cell.getTableRow().getItem());
                                try {
                                    MyFTPClient.getInstance().changeFTPdir(cell.getTableRow().getItem());
                                } catch (IOException e) {
                                    // TODO Auto-generated catch block
                                    e.printStackTrace();
                                }
                                ftpObservablelist = MyFTPClient.getInstance().getFtpObservableList(); 
                                ftpTable.setItems(ftpObservablelist);

                            }
                        }
                    });

                    return cell;
                }
            };


    ftpTable.setEditable(true);

    TableColumn<MyFTPFile,String> nameColumn = new TableColumn<MyFTPFile,String>("Dateiname");
    nameColumn.setMinWidth(200);
    nameColumn.setCellFactory(cellFactory);
    nameColumn.setCellValueFactory(new PropertyValueFactory<MyFTPFile,String>("name"));

    TableColumn<MyFTPFile,String> sizeColumn = new TableColumn<MyFTPFile,String>("Grösse");
    sizeColumn.setCellValueFactory(new PropertyValueFactory<MyFTPFile,String>("size"));

    TableColumn<MyFTPFile,String> dateColumn = new TableColumn<MyFTPFile,String>("Änderungsdatum");
    dateColumn.setMinWidth(140);
    dateColumn.setCellValueFactory(new PropertyValueFactory<MyFTPFile,String>("date"));

    TableColumn<MyFTPFile,String> rightsColumn = new TableColumn<MyFTPFile,String>("Berechtigungen");
    rightsColumn.setCellValueFactory(new PropertyValueFactory<MyFTPFile,String>("rights"));

    TableColumn<MyFTPFile,String> userColumn = new TableColumn<MyFTPFile,String>("User");
    userColumn.setCellValueFactory(new PropertyValueFactory<MyFTPFile,String>("owner"));

    TableColumn<MyFTPFile,String> groupColumn = new TableColumn<MyFTPFile,String>("Group");
    groupColumn.setCellValueFactory(new PropertyValueFactory<MyFTPFile,String>("group"));

    ftpTable.getColumns().addAll(nameColumn,sizeColumn, dateColumn, rightsColumn, userColumn, groupColumn);

    vbox.getChildren().add(ftpTable);
    ftpBorderpane.setCenter(vbox);

    getFTPButton.setOnAction(new EventHandler<ActionEvent>() {
        public void handle(ActionEvent e){
            try {
                MyFTPClient.getInstance().doConnection(kunde);
                MyFTPClient.getInstance().reqFTPdir();


            } catch (Exception e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            ftpObservablelist = MyFTPClient.getInstance().getFtpObservableList(); 
            ftpTable.setItems(ftpObservablelist);


        }   
    });



    return ftpBorderpane;       

}

崩溃时出现以下错误:

java.lang.NullPointerException
at ch.trusted.java.hcst.gui.GuiTest$19$1.updateItem(GuiTest.java:972)
at ch.trusted.java.hcst.gui.GuiTest$19$1.updateItem(GuiTest.java:1)
at javafx.scene.control.TableCell.updateItem(TableCell.java:539)
at javafx.scene.control.TableCell.indexChanged(TableCell.java:105)
at javafx.scene.control.TableCell$1.invalidated(TableCell.java:93)
at com.sun.javafx.binding.ExpressionHelper$SingleInvalidation.fireValueChangedEvent(ExpressionHelper.java:155)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:100)
at javafx.beans.property.ReadOnlyIntegerWrapper$ReadOnlyPropertyImpl.fireValueChangedEvent(ReadOnlyIntegerWrapper.java:195)
at javafx.beans.property.ReadOnlyIntegerWrapper.fireValueChangedEvent(ReadOnlyIntegerWrapper.java:161)
at javafx.beans.property.IntegerPropertyBase.markInvalid(IntegerPropertyBase.java:130)
at javafx.beans.property.IntegerPropertyBase.set(IntegerPropertyBase.java:163)
at javafx.scene.control.IndexedCell.updateIndex(IndexedCell.java:112)
at com.sun.javafx.scene.control.skin.TableRowSkin.updateCells(TableRowSkin.java:251)
at com.sun.javafx.scene.control.skin.TableRowSkin.doUpdateCheck(TableRowSkin.java:151)
at com.sun.javafx.scene.control.skin.TableRowSkin.layoutChildren(TableRowSkin.java:157)
at javafx.scene.Parent.layout(Parent.java:1018)
at com.sun.javafx.scene.control.skin.TableRowSkin.handleControlPropertyChanged(TableRowSkin.java:110)
at com.sun.javafx.scene.control.skin.SkinBase$3.changed(SkinBase.java:282)
at javafx.beans.value.WeakChangeListener.changed(WeakChangeListener.java:107)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:196)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:100)
at javafx.beans.property.ObjectPropertyBase.fireValueChangedEvent(ObjectPropertyBase.java:123)
at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:130)
at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:163)
at javafx.scene.control.Cell.setItem(Cell.java:333)
at javafx.scene.control.Cell.updateItem(Cell.java:557)
at javafx.scene.control.TableRow.updateItem(TableRow.java:246)
at javafx.scene.control.TableRow.indexChanged(TableRow.java:92)
at javafx.scene.control.TableRow$1.invalidated(TableRow.java:85)
at com.sun.javafx.binding.ExpressionHelper$SingleInvalidation.fireValueChangedEvent(ExpressionHelper.java:155)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:100)
at javafx.beans.property.ReadOnlyIntegerWrapper$ReadOnlyPropertyImpl.fireValueChangedEvent(ReadOnlyIntegerWrapper.java:195)
at javafx.beans.property.ReadOnlyIntegerWrapper.fireValueChangedEvent(ReadOnlyIntegerWrapper.java:161)
at javafx.beans.property.IntegerPropertyBase.markInvalid(IntegerPropertyBase.java:130)
at javafx.beans.property.IntegerPropertyBase.set(IntegerPropertyBase.java:163)
at javafx.scene.control.IndexedCell.updateIndex(IndexedCell.java:112)
at com.sun.javafx.scene.control.skin.VirtualFlow.setCellIndex(VirtualFlow.java:1596)
at com.sun.javafx.scene.control.skin.VirtualFlow.addLeadingCells(VirtualFlow.java:1049)
at com.sun.javafx.scene.control.skin.VirtualFlow.layoutChildren(VirtualFlow.java:1005)
at javafx.scene.Parent.layout(Parent.java:1018)
at javafx.scene.Scene.layoutDirtyRoots(Scene.java:513)
at javafx.scene.Scene.doLayoutPass(Scene.java:484)
at javafx.scene.Scene.access$3900(Scene.java:169)
at javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2199)
at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:363)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:460)
at com.sun.javafx.tk.quantum.QuantumToolkit$9.run(QuantumToolkit.java:329)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:76)

如果我只删除包含setGraphic的if语句,它就会起作用,并且不会出现崩溃。

任何想法这里的问题是什么?

1 个答案:

答案 0 :(得分:3)

项可以为null(例如在空单元格中)。

写:

if (item != null && item.equals("test")) 

或者另一种进行测试的方法,因为常量字符串永远不会为null也不等于null:

if ("test".equals(item))  

您的代码中可能存在其他错误,但在快速审核中,这似乎很明显。

您可能也对custom cell factory for row based processing in this question感兴趣。写得很好。

相关问题