【问题标题】:JavaFX troubles with removing items from ArrayListJavaFX 从 ArrayList 中删除项目的麻烦
【发布时间】:2023-04-07 02:15:01
【问题描述】:

我有 2 个TableViews (tableProduct, tableProduct2)。第一个由数据库填充,第二个由第一个中的用户项选择填充(addMeal 方法,它也将这些转换为简单的ArrayList)。添加/删除几个对象后,用户可以将当前数据从第二个表保存到 txt 文件。一开始它似乎工作得很好。但是问题开始有点随机显示......我添加了一些项目,保存它,删除一些项目,保存它,一切都很好。然后经过几次这样的操作,即使TableView 为空,最后一个对象仍保留在 txt 文件中。我无法做任何事情来删除它,而且我没有收到任何错误...

有什么想法吗?

 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 语句看起来很吓人,但不要介意,毕竟那部分没关系......

【问题讨论】:

  • 一个可能的来源是productDataproductSimpleData 上的getName() 方法。您没有为此提供代码,但从 addMeal() 中的创建代码看来,您的原始名称与 Float.parseFloat(weightField.getText()) 结果连接以创建新名称。这可能会在每次调用时返回不同的结果,因此您认为应该相等的名称/对象不是。尝试在对象上使用整数标识符,或将名称和权重字段分开。 (类名也应该遵守约定,例如ProductDataProductSimpleData

标签: arraylist javafx bufferedwriter


【解决方案1】:

您只需要检查productlist 列表中的第一项来确定是否应该删除该项。由于您似乎不会在任何地方写信给List 而不对tableProduct2items 进行类似的修改,因此在这种情况下您可以这样做。

public void deleteMeal() {
    int selectedIndex = tableProduct2.getSelectionModel().getSelectedIndex();

    if(selectedIndex >= 0) {
        tableProduct2.getItems().remove(selectedIndex);
        productlist.remove(selectedIndex);
    }
    updateSummary();
}

这样您还可以防止出现问题,如果列表中有 2 个相等的项目,这可能导致在选择第二个项目时第一个项目被删除...


是的,我意识到addMethod [...] 看起来很吓人

是的,确实如此,所以是时候重写了:

productDataproductSimpleData 中的属性更改为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&lt;productSimpleData&gt; 或子类型,您可以这样做

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 的附加构造函数参数中指定时才附加数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-29
    • 2020-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    相关资源
    最近更新 更多