我对 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 语句,它就可以工作并且不会出现崩溃。
知道这里有什么问题吗?