JavaFX 无法从 ArrayList 中删除项目
JavaFX troubles with removing items from ArrayList
我有 2 个 TableView
(tableProduct
、tableProduct2
)。第一个由数据库填充,第二个由用户从第一个中选择的项目填充(addMeal
方法,它也将这些转换为简单的 ArrayList
)。在 adding/deleting 个对象之后,用户可以将当前数据从第二个 Table 保存到 txt 文件。一开始似乎工作得很好。但是问题开始有点随机出现......我添加了一些项目,保存,删除了一些项目,保存,一切都很好。然后在这样的几次操作之后,最后一个对象保留在 txt 文件中,即使 TableView
是空的。我无法做任何事情来删除它,而且我没有收到任何错误...
有什么想法吗?
public void addMeal() {
productData selection = tableProduct.getSelectionModel().getSelectedItem();
if (selection != null) {
tableProduct2.getItems().add(new productData(selection.getName() + "(" + Float.parseFloat(weightField.getText()) + "g)", String.valueOf(Float.parseFloat(selection.getKcal())*(Float.parseFloat(weightField.getText())/100)), String.valueOf(Float.parseFloat(selection.getProtein())*(Float.parseFloat(weightField.getText())/100)), String.valueOf(Float.parseFloat(selection.getCarb())*(Float.parseFloat(weightField.getText())/100)), String.valueOf(Float.parseFloat(selection.getFat())*(Float.parseFloat(weightField.getText())/100))));
productlist.add(new productSimpleData(selection.getName() + "(" + Float.parseFloat(weightField.getText()) + "g)", String.valueOf(Float.parseFloat(selection.getKcal())*(Float.parseFloat(weightField.getText())/100)), String.valueOf(Float.parseFloat(selection.getProtein())*(Float.parseFloat(weightField.getText())/100)), String.valueOf(Float.parseFloat(selection.getCarb())*(Float.parseFloat(weightField.getText())/100)), String.valueOf(Float.parseFloat(selection.getFat())*(Float.parseFloat(weightField.getText())/100))));
}
updateSummary();
}
public void deleteMeal() {
productData selection = tableProduct2.getSelectionModel().getSelectedItem();
if(selection != null){
tableProduct2.getItems().remove(selection);
Iterator<productSimpleData> iterator = productlist.iterator();
productSimpleData psd = iterator.next();
if(psd.getName().equals(String.valueOf(selection.getName()))) {
iterator.remove();
}
}
updateSummary();
}
public void save() throws IOException {
File file = new File("C:\Users\Maciek\Desktop\test1.txt");
if(file.exists()){
file.delete();
}
FileWriter fw = null;
BufferedWriter bw = null;
try {
fw = new FileWriter(file);
bw = new BufferedWriter(fw);
Iterator iterator;
iterator = productlist.iterator();
while (iterator.hasNext()) {
productSimpleData pd;
pd = (productSimpleData) iterator.next();
bw.write(pd.toString());
bw.newLine();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
bw.flush();
bw.close();
}
}
是的,我意识到 addMethod
里面的 if
语句看起来很可怕,但不要介意,毕竟那部分没问题...
您只需检查 productlist
列表中的第一项以确定是否应删除该项。由于在不对 tableProduct2
的 items
进行类似修改的情况下,您似乎不会在任何地方写入 List
,因此在这种情况下您也可以这样做。
public void deleteMeal() {
int selectedIndex = tableProduct2.getSelectionModel().getSelectedIndex();
if(selectedIndex >= 0) {
tableProduct2.getItems().remove(selectedIndex);
productlist.remove(selectedIndex);
}
updateSummary();
}
如果列表中有 2 个相同的项目,这可能会导致在选择第二个项目时删除第一个项目,这样您还可以防止出现问题...
and yeah, I realize addMethod
[...] looks scary
是的,是的,所以是时候重写这个了:
将 productData
和 productSimpleData
中的属性更改为 float
,并且在需要 String
之前不要将数据转换为 String
。
if (selection != null) {
float weight = Float.parseFloat(weightField.getText());
float weight100 = weight / 100;
float calories = Float.parseFloat(selection.getKcal())*weight100;
float protein = Float.parseFloat(selection.getProtein())*weight100;
float carb = Float.parseFloat(selection.getCarb())*weight100;
float fat = Float.parseFloat(selection.getFat())*weight100;
ProductData product = new productData(
selection.getName() + "(" + weight + "g)",
calories,
protein,
carb,
fat);
productlist.add(new productSimpleData(product.getName(), calories, protein, carb, fat));
tableProduct2.getItems().add(product);
}
另外这种循环可以重写为增强的for循环:
Iterator iterator;
iterator = productlist.iterator();
while (iterator.hasNext()) {
productSimpleData pd;
pd = (productSimpleData) iterator.next();
bw.write(pd.toString());
bw.newLine();
}
假设您已将 productlist
声明为 List<productSimpleData>
或子类型,您可以只做
for (productSimpleData pd : productlist) {
bw.write(pd.toString());
bw.newLine();
}
此外,您可以依靠 try-with-resources
为您关闭编写器:
try (FileWriter fw = new FileWriter(file);
BufferedWriter bw = new BufferedWriter(fw)){
...
} catch (IOException e) {
e.printStackTrace();
}
也不需要删除该文件,因为 java 默认情况下会覆盖该文件,并且仅当您在 FileWriter
.
的附加构造函数参数中指定时才附加数据
我有 2 个 TableView
(tableProduct
、tableProduct2
)。第一个由数据库填充,第二个由用户从第一个中选择的项目填充(addMeal
方法,它也将这些转换为简单的 ArrayList
)。在 adding/deleting 个对象之后,用户可以将当前数据从第二个 Table 保存到 txt 文件。一开始似乎工作得很好。但是问题开始有点随机出现......我添加了一些项目,保存,删除了一些项目,保存,一切都很好。然后在这样的几次操作之后,最后一个对象保留在 txt 文件中,即使 TableView
是空的。我无法做任何事情来删除它,而且我没有收到任何错误...
有什么想法吗?
public void addMeal() {
productData selection = tableProduct.getSelectionModel().getSelectedItem();
if (selection != null) {
tableProduct2.getItems().add(new productData(selection.getName() + "(" + Float.parseFloat(weightField.getText()) + "g)", String.valueOf(Float.parseFloat(selection.getKcal())*(Float.parseFloat(weightField.getText())/100)), String.valueOf(Float.parseFloat(selection.getProtein())*(Float.parseFloat(weightField.getText())/100)), String.valueOf(Float.parseFloat(selection.getCarb())*(Float.parseFloat(weightField.getText())/100)), String.valueOf(Float.parseFloat(selection.getFat())*(Float.parseFloat(weightField.getText())/100))));
productlist.add(new productSimpleData(selection.getName() + "(" + Float.parseFloat(weightField.getText()) + "g)", String.valueOf(Float.parseFloat(selection.getKcal())*(Float.parseFloat(weightField.getText())/100)), String.valueOf(Float.parseFloat(selection.getProtein())*(Float.parseFloat(weightField.getText())/100)), String.valueOf(Float.parseFloat(selection.getCarb())*(Float.parseFloat(weightField.getText())/100)), String.valueOf(Float.parseFloat(selection.getFat())*(Float.parseFloat(weightField.getText())/100))));
}
updateSummary();
}
public void deleteMeal() {
productData selection = tableProduct2.getSelectionModel().getSelectedItem();
if(selection != null){
tableProduct2.getItems().remove(selection);
Iterator<productSimpleData> iterator = productlist.iterator();
productSimpleData psd = iterator.next();
if(psd.getName().equals(String.valueOf(selection.getName()))) {
iterator.remove();
}
}
updateSummary();
}
public void save() throws IOException {
File file = new File("C:\Users\Maciek\Desktop\test1.txt");
if(file.exists()){
file.delete();
}
FileWriter fw = null;
BufferedWriter bw = null;
try {
fw = new FileWriter(file);
bw = new BufferedWriter(fw);
Iterator iterator;
iterator = productlist.iterator();
while (iterator.hasNext()) {
productSimpleData pd;
pd = (productSimpleData) iterator.next();
bw.write(pd.toString());
bw.newLine();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
bw.flush();
bw.close();
}
}
是的,我意识到 addMethod
里面的 if
语句看起来很可怕,但不要介意,毕竟那部分没问题...
您只需检查 productlist
列表中的第一项以确定是否应删除该项。由于在不对 tableProduct2
的 items
进行类似修改的情况下,您似乎不会在任何地方写入 List
,因此在这种情况下您也可以这样做。
public void deleteMeal() {
int selectedIndex = tableProduct2.getSelectionModel().getSelectedIndex();
if(selectedIndex >= 0) {
tableProduct2.getItems().remove(selectedIndex);
productlist.remove(selectedIndex);
}
updateSummary();
}
如果列表中有 2 个相同的项目,这可能会导致在选择第二个项目时删除第一个项目,这样您还可以防止出现问题...
and yeah, I realize
addMethod
[...] looks scary
是的,是的,所以是时候重写这个了:
将 productData
和 productSimpleData
中的属性更改为 float
,并且在需要 String
之前不要将数据转换为 String
。
if (selection != null) {
float weight = Float.parseFloat(weightField.getText());
float weight100 = weight / 100;
float calories = Float.parseFloat(selection.getKcal())*weight100;
float protein = Float.parseFloat(selection.getProtein())*weight100;
float carb = Float.parseFloat(selection.getCarb())*weight100;
float fat = Float.parseFloat(selection.getFat())*weight100;
ProductData product = new productData(
selection.getName() + "(" + weight + "g)",
calories,
protein,
carb,
fat);
productlist.add(new productSimpleData(product.getName(), calories, protein, carb, fat));
tableProduct2.getItems().add(product);
}
另外这种循环可以重写为增强的for循环:
Iterator iterator;
iterator = productlist.iterator();
while (iterator.hasNext()) {
productSimpleData pd;
pd = (productSimpleData) iterator.next();
bw.write(pd.toString());
bw.newLine();
}
假设您已将 productlist
声明为 List<productSimpleData>
或子类型,您可以只做
for (productSimpleData pd : productlist) {
bw.write(pd.toString());
bw.newLine();
}
此外,您可以依靠 try-with-resources
为您关闭编写器:
try (FileWriter fw = new FileWriter(file);
BufferedWriter bw = new BufferedWriter(fw)){
...
} catch (IOException e) {
e.printStackTrace();
}
也不需要删除该文件,因为 java 默认情况下会覆盖该文件,并且仅当您在 FileWriter
.