gpt4 book ai didi

JavaFX 自定义 CellFactory 包装器抛出空指针

转载 作者:行者123 更新时间:2023-12-01 21:13:11 24 4
gpt4 key购买 nike

我创建了一个单元工厂包装器来启用 JavaFX 表格单元的自定义配置。请参阅下面的代码。

package idmas.controller.modules.tableview;

import idmas.model.Cml;
import idmas.model.CmlDAO;
import idmas.model.Damageloop;
import idmas.model.modules.general.dateMethods;
import java.util.Date;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.util.Callback;

/**
* Generic cell factory that can be used to override specific properties of cells, such as formatting (text size, color etc.) and even values.
* @author Joshua Adams
* @param <S> = Data type of table view to be modified. E.g. Damageloop, Equipment, CML, Inspection etc.
* @param <T> = Data type of specific cell being overridden. E.g. Date, Integer, Double etc.
*/
public class CellFactoryCustom<S, T> implements Callback<TableColumn<S, T>, TableCell<S, T>> {

//Represents the name of the column for the specific tableview, i.e. Last Internal Inspection Date etc.
String colname;

//Constructors for class wide objects
CmlDAO cmldao = new CmlDAO();

/**
* Class constructor requires a column name to be passed so the specific formatting for that column's cells can be applied.
* @param colname = Name of column to apply formatting to.
*/
public CellFactoryCustom (String colname) {
this.colname = colname;
}

/**
* Main method to override the properties of the cells for a table column.
* @param arg
* @return
*/
@Override
public TableCell<S, T> call(TableColumn<S, T> arg) {
TableCell<S, T> cell = new TableCell<S, T>() {
@Override
protected void updateItem(T item, boolean empty) {
//super allows reffering to methods in superclass
super.updateItem(item, empty);
//recommended syntax for overridding the updateItem method - Refer to update item javadoc.
if (empty || item == null) {
setText(null);
setGraphic(null);
getStyleClass().removeAll("highlightCellBlack");
getStyleClass().add(getTableRow().getStyleClass().toString());
} else {
setConditionalFormatting(this,item);
}
}
};
return cell;
}

/**
* Specific formatting rules which are applied to a columns cells based on its column name.
* @param cell
* @param item
*/
public void setConditionalFormatting (TableCell<S,T> cell, T item) {
//Constructors for reference classes
dateMethods datemethods = new dateMethods();
Date currentdateplus60 = new Date();
Date date;
Damageloop damageloop;
Cml cml;
ComboBox combobox;
//Current styles need to be removed to ensure all specific styles for each cell are applied correctly
cell.getStyleClass().removeAll("highlightCellBlack");
//Switch statement selected over if statement to improve performance of code and readibility
switch (colname) {
case "colNextExternalInspectionDate":
damageloop = (Damageloop) cell.getTableRow().getItem();
cell.setText(datemethods.getDateToString((Date) item,"dd/MM/yyyy"));
currentdateplus60 = datemethods.getDatePlusDays(currentdateplus60, 60);
date = (Date) item;
if(date.before(currentdateplus60) && damageloop.getErrorcode() != 2 & damageloop.getErrorcode() != 3) {
cell.getStyleClass().add("highlightCellBlack");
} else {
cell.getStyleClass().add(cell.getTableRow().getStyleClass().toString());
}
break;
case "colNextInternalInspectionDate":
damageloop = (Damageloop) cell.getTableRow().getItem();
cell.setText(datemethods.getDateToString((Date) item,"dd/MM/yyyy"));
currentdateplus60 = datemethods.getDatePlusDays(currentdateplus60, 60);
date = (Date) item;
if(date.before(currentdateplus60) && damageloop.getErrorcode() != 1 && damageloop.getErrorcode() != 3) {
cell.getStyleClass().add("highlightCellBlack");
} else {
cell.getStyleClass().add(cell.getTableRow().getStyleClass().toString());
}
break;
case "colCmlStatus":
cml = (Cml) cell.getTableRow().getItem();
String[] fieldsArray = new String[]{"C = Continue to Monitor", "S = Scoped", "X = Redundant"};
String[] disabledFieldsArray = new String[]{"S = Scoped"};
String SQLString = "UPDATE IDMAS.CML SET CMLSTATUS = '<NEW_STATUS>' WHERE EQUIPMENT_ID = '" + cml.getEquipmentId() + "' AND CML_NO = " + cml.getCmlNo();
String replacestring = "<NEW_STATUS>";
String defaultvalue = item.toString();
ComboBoxCustom comboboxcustom = new ComboBoxCustom (fieldsArray, disabledFieldsArray, SQLString, replacestring, defaultvalue);
comboboxcustom.setPrefWidth(10);
cell.setGraphic(comboboxcustom);
break;
case "colCmlStatusRemediation":
ObservableList<String> options = FXCollections.observableArrayList(
"A = Approved for Remediation",
"C = Continue to Monitor",
"F = Fit for Service",
"R = Recommend Remediation"
);
cml = (Cml) cell.getTableRow().getItem();
combobox = new ComboBox(options);
combobox.setValue(item.toString());
combobox.setPrefWidth(10);
combobox.valueProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue ov, String oldvalue, String newvalue) {
cml.setCmlstatusremediation(newvalue.charAt(0));
cmldao.updateCml(cml);
//Platform runlater required to update the combox with the new value
Platform.runLater(() -> {
combobox.setValue(String.valueOf(newvalue.charAt(0)));
});
}
});
cell.setGraphic(combobox);
break;
case "colTemporaryrepairinstalled":
cml = (Cml) cell.getTableRow().getItem();
CheckBox checkbox = new CheckBox();
checkbox.setSelected(Boolean.valueOf(item.toString()));
checkbox.selectedProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
cml.setTemporaryrepairinstalled(newValue);
cmldao.updateCml(cml);
checkbox.setSelected(newValue);
}
});
cell.setGraphic(checkbox);
break;
default:
break;
}
}
}

这个 cellfactory 包装器通常可以在我的所有表格 View 中导航。但是,一旦我在系统中执行其他功能,例如添加新记录、编辑记录等,就会抛出以下错误。

Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at idmas.controller.modules.tableview.CellFactoryCustom.setConditionalFormatting(CellFactoryCustom.java:110)
at idmas.controller.modules.tableview.CellFactoryCustom$1.updateItem(CellFactoryCustom.java:60)
at javafx.scene.control.TableCell.updateItem(TableCell.java:663)
at javafx.scene.control.TableCell.indexChanged(TableCell.java:468)
at javafx.scene.control.IndexedCell.updateIndex(IndexedCell.java:116)
at com.sun.javafx.scene.control.skin.TableRowSkinBase.requestCellUpdate(TableRowSkinBase.java:659)
at com.sun.javafx.scene.control.skin.TableRowSkinBase.handleControlPropertyChanged(TableRowSkinBase.java:234)
at com.sun.javafx.scene.control.skin.TableRowSkin.handleControlPropertyChanged(TableRowSkin.java:70)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase.lambda$registerChangeListener$61(BehaviorSkinBase.java:197)
at com.sun.javafx.scene.control.MultiplePropertyChangeListenerHandler$1.changed(MultiplePropertyChangeListenerHandler.java:55)
at javafx.beans.value.WeakChangeListener.changed(WeakChangeListener.java:89)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:182)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
at javafx.beans.property.ReadOnlyIntegerPropertyBase.fireValueChangedEvent(ReadOnlyIntegerPropertyBase.java:72)
at javafx.beans.property.ReadOnlyIntegerWrapper.fireValueChangedEvent(ReadOnlyIntegerWrapper.java:102)
at javafx.beans.property.IntegerPropertyBase.markInvalid(IntegerPropertyBase.java:113)
at javafx.beans.property.IntegerPropertyBase.set(IntegerPropertyBase.java:147)
at javafx.scene.control.IndexedCell.updateIndex(IndexedCell.java:115)
at com.sun.javafx.scene.control.skin.VirtualFlow.setCellIndex(VirtualFlow.java:1957)
at com.sun.javafx.scene.control.skin.VirtualFlow.addTrailingCells(VirtualFlow.java:1344)
at com.sun.javafx.scene.control.skin.VirtualFlow.layoutChildren(VirtualFlow.java:1197)
at javafx.scene.Parent.layout(Parent.java:1087)
at javafx.scene.Parent.layout(Parent.java:1093)
at javafx.scene.Parent.layout(Parent.java:1093)
at javafx.scene.Parent.layout(Parent.java:1093)
at javafx.scene.Parent.layout(Parent.java:1093)
at javafx.scene.Parent.layout(Parent.java:1093)
at javafx.scene.Parent.layout(Parent.java:1093)
at javafx.scene.Parent.layout(Parent.java:1093)
at javafx.scene.Parent.layout(Parent.java:1093)
at javafx.scene.Parent.layout(Parent.java:1093)
at javafx.scene.Parent.layout(Parent.java:1093)
at javafx.scene.Parent.layout(Parent.java:1093)
at javafx.scene.Parent.layout(Parent.java:1093)
at javafx.scene.Parent.layout(Parent.java:1093)
at javafx.scene.Parent.layout(Parent.java:1093)
at javafx.scene.Scene.doLayoutPass(Scene.java:552)
at javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2397)
at com.sun.javafx.tk.Toolkit.lambda$runPulse$30(Toolkit.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:354)
at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:381)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:510)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:490)
at com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$404(QuantumToolkit.java:319)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:745)

我似乎无法弄清楚为什么这个包装器认为我的 CML 类中有空值。有人知道为什么会抛出这个空指针异常吗?

最佳答案

无法保证TableCell已与 TableRow 关联或者 TableRowupdateItem 时已经填满方法第一次被调用。

在你的情况下可能 getTableRow()返回null (但这意味着 cml = (Cml) cell.getTableRow().getItem(); 是引发异常的行,而不是 String SQLString = "UPDATE IDMAS.CML SET CMLSTATUS = '<NEW_STATUS>' WHERE EQUIPMENT_ID = '" + cml.getEquipmentId() + "' AND CML_NO = " + cml.getCmlNo(); );至少当我尝试重现该错误时发生了这种情况。

但是如果

String SQLString = "UPDATE IDMAS.CML SET CMLSTATUS = '<NEW_STATUS>' WHERE EQUIPMENT_ID = '" + cml.getEquipmentId() + "' AND CML_NO = " + cml.getCmlNo();

确实是导致错误的行,那么导致出现这样的堆栈跟踪的唯一方法是 if cmlnull .

解决此问题的一种方法是根据索引从表中获取项目:

cml = (Cml) cell.getTableView().getItems().get(getIndex());

关于JavaFX 自定义 CellFactory 包装器抛出空指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40776652/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com