如何访问 ObservableList (JavaFX) 类型 class 中的方法
How to access a method in the type class of an ObservableList (JavaFX)
我有一个 ObservableList
类型的 Part,它包含多个 Part 对象。当向 ObservableList 添加一个新的 Part 时,我想检查一个变量 partID 的值是否等于其他 Parts 中相同变量 partID 的值。这是我现在设置代码的方式:
public class Inventory {
public static ObservableList<Part> allParts =
FXCollections.observableArrayList();
public static ObservableList<Part> getAllParts() {
return allParts;
}
}
public abstract class Part {
public final IntegerProperty partID;
public Part(int partID) {
this.partID = new SimpleIntegerProperty(partID);
}
public void setPartID(int partID) {
this.partID.set(partID);
}
public int getPartID() {
return partID.get();
}
}
现在,在我的 FXML 控制器中,我有以下代码,我尝试获取新 partID 的文本字段并检查是否有任何其他现有 partID 已经包含相同的值,以便我可以通知如果有,用户选择一个新的 partID,如果没有,则添加新的零件。
@FXML
void AddPartSaveButtonHandler(ActionEvent event) {
if(partIDTextField.getText() != null) {
String partIDString = partIDTextField.getText();
int partID = Integer.parseInt(partIDString);
if(partID != Inventory.getAllParts().getPartID() {
//getPartID() is redlined
Inventory.getAllParts().add(newPart);
}
}
}
当尝试从 getAllParts() 调用 getPartID() 时显然会出现编译错误,因为它不是它的一个实例。那么如何从 allParts 访问所有现有的 partID?
PS - partID 不是 ObservableList 中保存的唯一变量。我还有很多其他的(如 partName、partPrice 等),但我认为它们与问题的核心无关。
你唯一真正的选择是遍历列表并查看是否有任何现有的部分 ID 匹配(注意我已经更改了一些变量和方法的名称以符合正确的命名约定):
@FXML
void addPartSaveButtonHandler(ActionEvent event) {
if(partIDTextField.getText() != null) {
String partIDString = partIDTextField.getText();
int partID = Integer.parseInt(partIDString);
boolean hasMatch = false ;
for (Part part : inventory.getAllParts()) {
if (part.getPartID() == partID) {
hasMatch = true ;
break ;
}
}
if (! hasMatch) {
//getPartID() is redlined
Inventory.getAllParts().add(newPart);
}
}
}
您可以使用流使这段代码更流畅(尽管它本质上做的是完全相同的事情):
@FXML
void addPartSaveButtonHandler(ActionEvent event) {
if(partIDTextField.getText() != null) {
String partIDString = partIDTextField.getText();
int partID = Integer.parseInt(partIDString);
boolean noneMatch = inventory.getAllParts().stream()
.mapToInt(Part::getPartID)
.noneMatch(id -> id == partID);
if (noneMatch) {
//getPartID() is redlined
Inventory.getAllParts().add(newPart);
}
}
}
如果性能是个问题(每次添加新元素时都会遍历整个列表,如果添加很多元素可能会出现问题),那么您应该将 ID 保存在单独的数据结构中搜索速度更快。例如:
private Set<Integer> partIDs = new HashSet<>();
// ...
inventory.getAllParts().addListener((Change<? extends Part> c) -> {
while (c.next()) {
if (c.wasAdded()) {
for (Part part : c.getAddedSubList()) {
partIDs.add(part.getPartID());
}
}
if (c.wasRemoved()) {
for (Part part : c.getRemoved()) {
partIDs.remove(part.getPartID());
}
}
}
});
然后
@FXML
void addPartSaveButtonHandler(ActionEvent event) {
if(partIDTextField.getText() != null) {
String partIDString = partIDTextField.getText();
int partID = Integer.parseInt(partIDString);
if (! partIDs.contains(partID)) {
//getPartID() is redlined
Inventory.getAllParts().add(newPart);
}
}
}
我有一个 ObservableList
类型的 Part,它包含多个 Part 对象。当向 ObservableList 添加一个新的 Part 时,我想检查一个变量 partID 的值是否等于其他 Parts 中相同变量 partID 的值。这是我现在设置代码的方式:
public class Inventory {
public static ObservableList<Part> allParts =
FXCollections.observableArrayList();
public static ObservableList<Part> getAllParts() {
return allParts;
}
}
public abstract class Part {
public final IntegerProperty partID;
public Part(int partID) {
this.partID = new SimpleIntegerProperty(partID);
}
public void setPartID(int partID) {
this.partID.set(partID);
}
public int getPartID() {
return partID.get();
}
}
现在,在我的 FXML 控制器中,我有以下代码,我尝试获取新 partID 的文本字段并检查是否有任何其他现有 partID 已经包含相同的值,以便我可以通知如果有,用户选择一个新的 partID,如果没有,则添加新的零件。
@FXML
void AddPartSaveButtonHandler(ActionEvent event) {
if(partIDTextField.getText() != null) {
String partIDString = partIDTextField.getText();
int partID = Integer.parseInt(partIDString);
if(partID != Inventory.getAllParts().getPartID() {
//getPartID() is redlined
Inventory.getAllParts().add(newPart);
}
}
}
当尝试从 getAllParts() 调用 getPartID() 时显然会出现编译错误,因为它不是它的一个实例。那么如何从 allParts 访问所有现有的 partID?
PS - partID 不是 ObservableList 中保存的唯一变量。我还有很多其他的(如 partName、partPrice 等),但我认为它们与问题的核心无关。
你唯一真正的选择是遍历列表并查看是否有任何现有的部分 ID 匹配(注意我已经更改了一些变量和方法的名称以符合正确的命名约定):
@FXML
void addPartSaveButtonHandler(ActionEvent event) {
if(partIDTextField.getText() != null) {
String partIDString = partIDTextField.getText();
int partID = Integer.parseInt(partIDString);
boolean hasMatch = false ;
for (Part part : inventory.getAllParts()) {
if (part.getPartID() == partID) {
hasMatch = true ;
break ;
}
}
if (! hasMatch) {
//getPartID() is redlined
Inventory.getAllParts().add(newPart);
}
}
}
您可以使用流使这段代码更流畅(尽管它本质上做的是完全相同的事情):
@FXML
void addPartSaveButtonHandler(ActionEvent event) {
if(partIDTextField.getText() != null) {
String partIDString = partIDTextField.getText();
int partID = Integer.parseInt(partIDString);
boolean noneMatch = inventory.getAllParts().stream()
.mapToInt(Part::getPartID)
.noneMatch(id -> id == partID);
if (noneMatch) {
//getPartID() is redlined
Inventory.getAllParts().add(newPart);
}
}
}
如果性能是个问题(每次添加新元素时都会遍历整个列表,如果添加很多元素可能会出现问题),那么您应该将 ID 保存在单独的数据结构中搜索速度更快。例如:
private Set<Integer> partIDs = new HashSet<>();
// ...
inventory.getAllParts().addListener((Change<? extends Part> c) -> {
while (c.next()) {
if (c.wasAdded()) {
for (Part part : c.getAddedSubList()) {
partIDs.add(part.getPartID());
}
}
if (c.wasRemoved()) {
for (Part part : c.getRemoved()) {
partIDs.remove(part.getPartID());
}
}
}
});
然后
@FXML
void addPartSaveButtonHandler(ActionEvent event) {
if(partIDTextField.getText() != null) {
String partIDString = partIDTextField.getText();
int partID = Integer.parseInt(partIDString);
if (! partIDs.contains(partID)) {
//getPartID() is redlined
Inventory.getAllParts().add(newPart);
}
}
}