保存到.txt文件并从.txt文件导入会导致数据被覆盖

时间:2017-09-20 09:37:34

标签: java listview javafx save overwrite

我希望能够将我的Card对象保存到“CardsColleciton.txt”文件中(通过键入或硬编码),然后将这些对象加载到我的列表testingList中,以便我可以正确显示它们。但是,我尝试过很多东西,但我似乎无法弄清楚为什么会出现以下两个问题:

1)每当我通过硬编码或输入来写入.txt文件时,我的代码加载它们就好了但是在关闭程序之后,数据被删除了,我必须重新开始。

2)如果我对对象进行硬编码,它们确实显示在我的列表中,但是当我正常写入.txt文件时,代码表明它们已被加载(并且它们是,测试列表的大小确实增加了)但它没有不要在listView上显示它们。

希望有人能帮助我找出这两个。

PS:我已经阅读了很多关于第一个问题的其他类似帖子,但没有一个解决了我的问题。

以下是我的.java文件:

Card.java:

package com.spdesigns.dokkancardspreview.model;

 import javafx.scene.image.Image;

public class Card {

private String mName;
private String mDescription;
private Image mMainImage;
private Image mSecondaryImage;

public Card(String name, String description, String mainImagePath, String secondaryImagePath) {
    mName = name;
    mDescription = description;
    mMainImage = new Image(mainImagePath);
    mSecondaryImage = new Image(secondaryImagePath);
}

@Override
public String toString() {
    return mName + " | " + mDescription;
}

public Image getmMainImage() {
    return mMainImage;
}

public Image getmSecondaryImage() {
    return mSecondaryImage;
}

public String getName() {
    return mName;
}

public String getDescription() {
    return mDescription;
}
}

控制器 - > home.java:

package com.spdesigns.dokkancardspreview.controllers;

import com.spdesigns.dokkancardspreview.model.Card;

import javafx.beans.property.ListProperty;
import javafx.beans.property.SimpleListProperty;
 import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;

import java.io.*;
import java.util.List;
import java.net.URL;
import java.util.ArrayList;
import java.util.ResourceBundle;

public class home implements Initializable {

/*private Card hit = new Card("Hit","Expanding Possibility",
        "/images/hit_main.jpg", "/images/hit_secondary.jpg");*/
// This is how I "hard-code" the object so that the 2nd issue does not occur
  private Card goku = new Card("Goku SSJ3","Everlasting Legend",
             "/images/gokussj3_main.jpg", "/images/gokussj3_secondary.jpg");

private boolean clickedAgain = false;

@FXML
private Button arrowButton;
@FXML
private ImageView imageView;

@FXML
private ImageView arrow;

@FXML
private ListView listView;

protected List<Card> testingList = new ArrayList<Card>();

protected ListProperty<Card> listProperty = new SimpleListProperty<Card>();


@Override
public void initialize(URL location, ResourceBundle resources) {
    //addCard(hit);
      addCard(goku);
    //testingList.add("test2");

    listView.itemsProperty().bind(listProperty);
    // wrapping our list in an observable list and then pass that observableList to the ListProperty isntance
    listProperty.set(FXCollections.observableArrayList(testingList));

    // Handle listView selection changes
    listView.getSelectionModel().selectedItemProperty().addListener(((observable, oldValue, newValue) -> {
        Card currentlySelectedCard = listProperty.get(listView.getSelectionModel().getSelectedIndex());
        System.out.printf("ListView item clicked! Value retrieved: %s\n", currentlySelectedCard);
        imageView.setImage(new Image(currentlySelectedCard.getmMainImage().impl_getUrl()));
        arrow.setVisible(true);
        arrowButton.setVisible(true);
    }));

    arrow.translateYProperty().set(283f);
    arrowButton.translateYProperty().set(283f);
    arrow.setRotate(180);
    arrow.setVisible(false);
    arrowButton.setVisible(false);
}

public void handleShowDetails(ActionEvent actionEvent) {
    System.out.println("Button Clicked!");
    Card currentlySelectedCard = listProperty.get(listView.getSelectionModel().getSelectedIndex());
    if (clickedAgain) {
        imageView.setImage(new Image(currentlySelectedCard.getmMainImage().impl_getUrl()));
        arrow.setRotate(180);
        clickedAgain = false;
    } else {
        imageView.setImage(new Image(currentlySelectedCard.getmSecondaryImage().impl_getUrl()));
        arrow.setRotate(360);
        clickedAgain = true;
    }
}

// Saving
public void exportTo(String fileName) {
    try (
            FileOutputStream fos = new FileOutputStream(fileName);
            PrintWriter writer = new PrintWriter(fos);
    ) {
        for (int i = 0; i < testingList.size() - 1; i++) {
            writer.printf("%s|%s|%s|%s\n", testingList.get(i).getName(), testingList.get(i).getDescription(),
                    testingList.get(i).getmMainImage().impl_getUrl(), testingList.get(i).getmSecondaryImage().impl_getUrl());
            System.out.println(testingList.get(i).toString());
        }
    } catch (IOException ioe) {
        System.out.printf("Problem saving: %s/n", fileName);
        ioe.printStackTrace();
    }
}

// Loading
public void importFrom(String fileName) {
    try (
            FileInputStream fis = new FileInputStream(fileName);
            BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
    ) {
        String line;
        while ((line = reader.readLine()) != null) {
            String[] args = line.split("\\|");
            this.addCard(new Card(args[0], args[1], args[2], args[3]));
        }
    } catch (IOException ioe) {
        System.out.printf("Problem loading: %S\n", fileName);
        ioe.printStackTrace();
    }
    int i = 0;
    for (Card card : testingList) {
        System.out.printf("%s loaded\n", testingList.get(i).toString());
        i++;
    }
    System.out.println("Loading Successful!");
}

public void addCard(Card card) {
    testingList.add(card);
}

// DEBUG purposes
public void printTestingList() {
    for (Card card : testingList) {
        System.out.println(card.toString());
    }
}
}

Main.java:

package com.spdesigns.dokkancardspreview;

import com.spdesigns.dokkancardspreview.controllers.home;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.io.File;

public class Main extends Application {

private home controller;
private File file = new File("CardsCollection.txt");

@Override
public void start(Stage primaryStage) throws Exception{
    FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/home.fxml"));
    Parent root = loader.load();
    controller = loader.getController();
    primaryStage.setTitle("Dokkan Battle Card Preview");
    primaryStage.setScene(new Scene(root, 900, 700));
    primaryStage.setResizable(false);
    // Loading cards
    primaryStage.show();
    try {
        if(!file.exists()) {
            file.createNewFile();
        }
        controller.importFrom("CardsCollection.txt");
    } catch (NullPointerException npe) {
        System.out.println("Error loading file!");
        npe.printStackTrace();
    }
}

//TODO:sp Fix when closisng the app-saving, the .txt file gets reseted
@Override
public void stop() {
    System.out.println("App is closing!");
    // Saving before exiting
    try {
        controller.exportTo("CardsCollection.txt");
        System.out.println("Saving was successful!\n");
    } catch (NullPointerException npe) {
        System.out.println("Problem saving file!");
        npe.printStackTrace();
    }
    controller.printTestingList();
   // System.out.println(file.);
}

public static void main(String[] args) {
    launch(args);
}
}

2 个答案:

答案 0 :(得分:0)

这是我几个月前编写的程序的一部分,尝试使用这些方法访问您的csv文件:

    // Writes to CSV File
    private void writeCSV(ArrayList<String[]> newContent){

        CSVWriter writer;

        try {
            writer = new CSVWriter(new FileWriter(this.path), ';', CSVWriter.NO_QUOTE_CHARACTER);
            writer.writeAll(newContent);
            writer.flush();
            writer.close();
        } catch (IOException ex) {
            Logger.getLogger(CSVFile.class.getName()).log(Level.SEVERE, null, ex);
        }  
    }

    // Reads from CSV File
    private ArrayList<String> readCSV(){
        BufferedReader br = null;
        String line = "";
        ArrayList<String> ret = new ArrayList();

        try {

            br = new BufferedReader(new FileReader(this.path));
            while ((line = br.readLine()) != null) {
                ret.add(line);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return ret;
    }

这用于编写,API openCSV和用于读取普通的BufferedReader(不需要特殊导入)。

writeCSV()能够覆盖.csv文件的全部内容。每个String []表示一行,该Array中的每个元素都是该行的一列。如果您只想修改文件中的内容,则需要先读取.CSV文件,然后修改ArrayList。

注意:readCSV()只返回字符串的ArrayList,因此您需要将字符串拆分为“;”为了访问每一列。

我希望这不会太混乱^^

答案 1 :(得分:0)

您的addCard()方法正在添加到基础列表,而不是ListProperty。正如您在documentation中所述,用于创建可观察列表的方法

  

创建一个新的可观察数组列表,并向其添加集合col的内容。

换句话说,创建一个新列表,该列表最初包含提供列表中的元素。对您传递的集合的后续更改不会更改可观察列表。

你可能只需要一个可观察的列表:没有必要创建一个额外的&#34; plain&#34;列表,不需要ListProperty

public class Home implements Initializable {

    private Card goku = new Card("Goku SSJ3","Everlasting Legend",
                 "/images/gokussj3_main.jpg", "/images/gokussj3_secondary.jpg");

    private boolean clickedAgain = false;

    @FXML
    private Button arrowButton;
    @FXML
    private ImageView imageView;

    @FXML
    private ImageView arrow;

    @FXML
    private ListView listView;

    private ObservableList<Card> cards = FXCollections.observableArrayList();


    @Override
    public void initialize(URL location, ResourceBundle resources) {
        addCard(goku);

        listView.setItems(cards);

        // Handle listView selection changes
        listView.getSelectionModel().selectedItemProperty().addListener(((observable, oldCard, newCard) -> {

            System.out.printf("ListView item clicked! Value retrieved: %s\n", newCard);
            imageView.setImage(newCard.getmMainImage());
            arrow.setVisible(true);
            arrowButton.setVisible(true);
        }));

        arrow.translateYProperty().set(283f);
        arrowButton.translateYProperty().set(283f);
        arrow.setRotate(180);
        arrow.setVisible(false);
        arrowButton.setVisible(false);
    }

    public void handleShowDetails(ActionEvent actionEvent) {
        System.out.println("Button Clicked!");
        Card currentlySelectedCard = listView.getSelectionModel().getSelectedItem();
        if (clickedAgain) {
            imageView.setImage(currentlySelectedCard.getmMainImage());
            arrow.setRotate(180);
            clickedAgain = false;
        } else {
            imageView.setImage(currentlySelectedCard.getmSecondaryImage());
            arrow.setRotate(360);
            clickedAgain = true;
        }
    }

    // Saving
    public void exportTo(String fileName) {
        try (
                FileOutputStream fos = new FileOutputStream(fileName);
                PrintWriter writer = new PrintWriter(fos);
        ) {
            for (Card card : cards) {
                // TODO should make image locations properties of card
                // to implement this properly
                writer.printf("%s|%s|%s|%s\n", card.getName(), card.getDescription(),
                        card.getmMainImage().impl_getUrl(), card.getmSecondaryImage().impl_getUrl());
                System.out.println(card.toString());
            }
        } catch (IOException ioe) {
            System.out.printf("Problem saving: %s/n", fileName);
            ioe.printStackTrace();
        }
    }

    // Loading
    public void importFrom(String fileName) {
        try (
                FileInputStream fis = new FileInputStream(fileName);
                BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
        ) {
            String line;
            while ((line = reader.readLine()) != null) {
                String[] args = line.split("\\|");
                this.addCard(new Card(args[0], args[1], args[2], args[3]));
            }
        } catch (IOException ioe) {
            System.out.printf("Problem loading: %S\n", fileName);
            ioe.printStackTrace();
        }
        int i = 0;
        for (Card card : testingList) {
            System.out.printf("%s loaded\n", testingList.get(i).toString());
            i++;
        }
        System.out.println("Loading Successful!");
    }

    public void addCard(Card card) {
        cards.add(card);
    }

    // DEBUG purposes
    public void printTestingList() {
        for (Card card : cards) {
            System.out.println(card.toString());
        }
    }

}

你的第一个问题对我来说并不是很清楚。如果您的意思是在保存时想要将卡附加到现有文件,则需要替换

FileOutputStream fos = new FileOutputStream(fileName);

FileOutputStream fos = new FileOutputStream(fileName, true);