0

我对 java 比较陌生,对编程很老实。我正在研究一个小工具。其中一个功能是伪 ftp 客户端,显示 ftp 主机上的内容,还允许在不同文件夹之间切换。对于文件/文件夹列表,我使用的是 TableView。现在我想调整视觉内容并根据单元格的内容向单元格添加一些图形,如果它是文件还是文件夹。但是当我在 CellFactory 中使用以下代码时,它不仅在填充语句的单元格上设置图形,而且在上下滚动 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 语句,它就可以工作并且不会出现崩溃。

知道这里有什么问题吗?

4

1 回答 1

3

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

写:

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

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

if ("test".equals(item))  

您的代码中可能还有其他错误,但在快速查看时似乎很明显。

您可能还对此问题中的基于行的处理的自定义单元工厂感兴趣。它写得很好。

于 2012-12-04T08:56:36.157 回答