2016-12-08 2 views
1

У меня есть 2 TableView s (tableProduct, tableProduct2). Первая заполняется базой данных, вторая заполняется выбранными пользователем элементами из первого (addMeal метод, который также преобразует их в простые ArrayList). После добавления/удаления нескольких объектов пользователь может сохранять текущие данные из второй таблицы в файл txt. Кажется, что все работает отлично. Но проблема начинает показаться немного случайным образом ... Я добавляю несколько элементов, сохраняю их, удаляю несколько элементов, сохраняю их, все в порядке. Затем после нескольких таких действий один последний объект остается в txt-файле, хотя TableView пуст. Я просто ничего не могу сделать, чтобы удалить его, и я не получаю ошибок ...Проблемы с JavaFX с удалением предметов из ArrayList

Любые идеи о том, что происходит?

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 заявление выглядит страшно, но не против, что часть Allright все-таки ...

+0

Возможным источником является метод getName() '' productData' и 'productSimpleData'. Вы не предоставляете код для этого, но из кода создания в 'addMeal()' похоже, что ваше исходное имя конкатенируется с результатом 'Float.parseFloat (weightField.getText()) для создания нового имени.Это может привести к разным результатам при каждом вызове, поэтому имена/объекты, которые, по вашему мнению, должны быть равны, не являются. Попробуйте использовать целочисленные идентификаторы на объектах или отделите поля имени и веса. (Названия классов должны также соответствовать соглашениям, например «ProductData», «ProductSimpleData») – Geoff

ответ

2

Вы только когда-либо проверить первый элемент в списке productlist определить, должен ли элемент быть удален. Поскольку вы, кажется, не пишите в List в любом месте, не делая аналогичной модификации items из tableProduct2, вы можете просто сделать то же самое в этом случае.

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

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

Таким образом, вы также предотвратить проблемы, если есть 2 одинаковых элементов в списке, что может привести к первой удаляемой при выборе второй один ...


и да, я понимаю, addMethod [...] выглядит страшно

Да, это делает, так что пора переписать так:

Измените свойства в 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); 
} 

Кроме того, что этот вид цикла может быть переписан улучшенным цикл:

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.

Смежные вопросы