使用CSV文件

时间:2015-06-06 21:58:35

标签: csv javafx tableview

此应用程序将在Person类的帮助下写入和读取csv文件。它不会使用数据填充表。我试图通过将相同的数据加载到plist = new ArrayList()然后将此plist传递给data = FXCollections.observableList,同时将csv文件加载到list = new ArrayList()来执行表的加载(plist中)

请说明此代码失败的位置。是否无法加载observableList 同时列表ArrayList被加载或是从列表转移到plist不工作​​? 我也不确定是否调用了CellValueFactory。建议的解决方案将不胜感激。 我不想使用第三方API,也不希望使用TableView来添加/删除数据。

MainClass
package appCSVFile;

import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.fxml.FXMLLoader;


public class CSVMain extends Application {
    @Override
    public void start(Stage pStage) {
        try {
            AnchorPane root = (AnchorPane)FXMLLoader.load(getClass().getResource("csv.fxml"));
            Scene scene = new Scene(root,1040,650);
            pStage.setScene(scene);
            pStage.setResizable(false);
            pStage.setTitle("CSV File Demo");
            pStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}
Controller Class
package appCSVFile;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.Optional;
import java.util.ResourceBundle;
import java.util.Scanner;


import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.TableColumn.CellEditEvent;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;

public class CSVController implements Initializable {

    @FXML private AnchorPane apCSV;
    @FXML private Pane paneONE;

    @FXML public TextField txfFName;
    @FXML public TextField txfLName;
    @FXML public TextField txfPNum;
    @FXML public TextField txfEMail;
    @FXML private VBox vbxDir;

    @FXML public TableView<Person> table;
    @FXML public TableColumn<Person, String> tblColFName;
    @FXML public TableColumn<Person, String> tblColLName;
    @FXML public TableColumn<Person, String> tblColPNum;
    @FXML public TableColumn<Person, String> tblColEMail;

    FileChooser fc = new FileChooser();
    public ArrayList<Contacts> list;
    private ListIterator<Contacts> LIT;
    private int i;

    public ArrayList<Person> plist;
    public ObservableList<Person> data;

    @FXML
    private void onDir(ActionEvent e) {
        vbxDir.setVisible(true);
        vbxDir.toFront();
    }
    @FXML
    private void onClose(ActionEvent e) {
        vbxDir.setVisible(false);
    }

    @FXML//Load CSV Data
    private void onLoad(ActionEvent e)throws IOException {

        File fileInfo = new File("C:/A_CSV/People.csv");
        if(fileInfo.length()==0) {
            Alert alert = new Alert(Alert.AlertType.WARNING);
            alert.setTitle("Information");
            alert.setHeaderText("");
            alert.setContentText("No Data in File at "+ fileInfo+"\n"+
            "Enter Data and Save");
            alert.showAndWait();
            return;  
        }

        fc.setTitle("Load Contacts Info");
        fc.setInitialDirectory(new File("C:/"));
        fc.setInitialDirectory(new File("C:/A_CSV"));
        fc.setInitialFileName("People.csv");
        File file = fc.showOpenDialog(null);
        if (file == null) {
        return;
        }

        String correctFile = file.getName();
        if(!(correctFile.matches("People.csv"))){
            Alert alert = new Alert(Alert.AlertType.ERROR);
            alert.setTitle("Information");
            alert.setHeaderText("");
            alert.setContentText("The File at " + file + "\n\n"+
            "is NOT accociated with this application\n\n"+
            "Select the File at "+fileInfo);
            alert.showAndWait();
            return;
        }

        Path dirP = Paths.get(String.valueOf(file));
        InputStream in = Files.newInputStream(dirP);
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));

        list = new ArrayList<Contacts>();
        plist = new ArrayList<Person>();
        Scanner scan = new Scanner(reader);
        scan.useDelimiter("\\s*,\\s*");

        while (scan.hasNext()){
           String fname = scan.next();
           String lname = scan.next();
           String pnum = scan.next();
           String email = scan.next();

           txfFName.setText(String.valueOf(fname));
           txfLName.setText(String.valueOf(lname));
           txfPNum.setText(String.valueOf(pnum));
           txfEMail.setText(String.valueOf(email));


           list.add(new Contacts(fname,lname,pnum,email));

           plist.add(new Person(fname,lname,pnum,email));
           data = FXCollections.observableList(plist);

           table = new TableView<>();
           table.setItems(data);

        TableColumn<Person,String> tblColFName = new TableColumn<>("First Name");
        tblColFName.setCellValueFactory(new PropertyValueFactory<>("vfname"));
        tblColFName.setCellFactory(TextFieldTableCell.forTableColumn());
        tblColFName.setOnEditCommit(new EventHandler<CellEditEvent<Person, String>>() {

            @Override
            public void handle(CellEditEvent<Person, String> t) {

                t.getTableView().getItems()
                    .get(t.getTablePosition().getRow())
                    .setFName(t.getNewValue());
            }

        });

        TableColumn<Person,String> tblColLName = new TableColumn<>("Last Name");
        tblColLName.setCellValueFactory(new PropertyValueFactory<>("vlname"));
        tblColLName.setCellFactory(TextFieldTableCell.forTableColumn());
        tblColLName.setOnEditCommit(new EventHandler<CellEditEvent<Person, String>>() {
            @Override
            public void handle(CellEditEvent<Person, String> t) {

                t.getTableView().getItems()
                    .get(t.getTablePosition().getRow())
                    .setLName(t.getNewValue());
            }
        });

        TableColumn<Person,String> tblColPNum = new TableColumn<>("Phone Number");
        tblColPNum.setCellValueFactory(new PropertyValueFactory<>("vpnum"));
        tblColPNum.setCellFactory(TextFieldTableCell.forTableColumn());
        tblColPNum.setOnEditCommit(new EventHandler<CellEditEvent<Person, String>>() {
            @Override
            public void handle(CellEditEvent<Person, String> t) {

                t.getTableView().getItems()
                    .get(t.getTablePosition().getRow())
                    .setPNum(t.getNewValue());
            }
        });

        TableColumn<Person,String> tblColEMail = new TableColumn<>("Email Address");
        tblColEMail.setCellValueFactory(new PropertyValueFactory<>("vemail"));
        tblColEMail.setCellFactory(TextFieldTableCell.forTableColumn());
        tblColEMail.setOnEditCommit(new EventHandler<CellEditEvent<Person, String>>() {
            @Override
            public void handle(CellEditEvent<Person, String> t) {

                t.getTableView().getItems()
                    .get(t.getTablePosition().getRow())
                    .setEMail(t.getNewValue());
            }
        });

//System.out.println(list.size());//2
//System.out.println(plist.containsAll(data));//true
//System.out.println(plist.size());//2

       }
       scan.close();

        LIT = list.listIterator();                  
        if (LIT.hasNext()){          
            Contacts p = LIT.next();
            getContacts(p); 
        } 
    }

    @FXML//This code removes data from the ArrayList and RE-Writes to the
     //People.csv file the file is deleted first then rewritten
    private void onRemove(ActionEvent e)throws IOException{

    if(txfFName.getText().isEmpty()||txfLName.getText().isEmpty()||txfPNum.getText().isEmpty()||txfEMail.getText().isEmpty()) {
        Alert alert = new Alert(Alert.AlertType.WARNING);
        alert.setTitle("Information");
        alert.setHeaderText("");
        alert.setContentText("No Data Present to REMOVE\n"+
        "Click LOAD to Obtain Data");
        alert.showAndWait();
        return; 
    }

    list.get(i);
    list.remove(i);

    if(0 == list.size()){
    Path path = FileSystems.getDefault().getPath("C:/A_CSV", "People.csv");
    Files.delete(path);
        onClear(e);
        list.clear();
    return;
    }else if(i == list.size()){     
        i = i - 1;
    }
    Contacts p = list.get(i);
        getContacts(p);
        Contacts dat;

        for(int r = 0; r <list.size(); r++){
        dat = list.get(r);  
        }  
       Path path = FileSystems.getDefault().getPath("C:/A_CSV", "People.csv");
       Files.delete(path);

       File file = new File("C:/A_CSV/People.csv");
            if(!file.exists()){
            file.createNewFile();
        }

        FileWriter fileWriter = new FileWriter(file.getPath(),true);
        BufferedWriter bufferWritter = new BufferedWriter(fileWriter);  
        Iterator<Contacts> LIT = list.iterator();
            while(LIT.hasNext()) {
                dat = LIT.next();
                String d = dat.toString();
                bufferWritter.write(d);
        }

        bufferWritter.close();
        onClear(e);
        //list.clear();//this is done by onClear(e)
        txfFName.requestFocus();
    }

    @FXML//Scroll forward through the ArrayList
    private void onNext(ActionEvent e) {

        if (list == null || list.size() == 0) {
        Alert alert = new Alert(Alert.AlertType.WARNING);
        alert.setTitle("Information");
        alert.setHeaderText("");
        alert.setContentText("Load Data First");
        alert.showAndWait();
        return;
        }

        if (i == list.size()- 1) {
        i = 0;
        Alert alert = new Alert(Alert.AlertType.WARNING);
        alert.setTitle("Information");
        alert.setHeaderText("");
        alert.setContentText("Last Record in File");
        alert.showAndWait();
        i= list.size()-1;
        return;
        }else {
        i = i + 1;
        }
            Contacts p = list.get(i);
            getContacts(p); 
    }

    @FXML//Scroll backwards through the ArrayList
    private void onPrevious(ActionEvent e) {

        if (list == null || list.size() == 0) {
        Alert alert = new Alert(Alert.AlertType.WARNING);
        alert.setTitle("Information");
        alert.setHeaderText("");
        alert.setContentText("Load Data First");
        alert.showAndWait();
        return;
        }

        if (i == 0) {
        i = list.size()-1;
        Alert alert = new Alert(Alert.AlertType.WARNING);
        alert.setTitle("Information");
        alert.setHeaderText("");
        alert.setContentText("First Record in File");
        alert.showAndWait();
        i=0;
        return;
        }else {
        i = i - 1 ;
        }
            Contacts p = list.get(i); 
            getContacts(p);
    }

    //Helper for Contacts Class
    private void getContacts(Contacts p){
        txfFName.setText("" + p.getFName());
        txfLName.setText("" + p.getLName());
        txfPNum.setText ("" + p.getPnum());
        txfEMail.setText("" + p.getEmail());    
    }

    @FXML
    private void oneSave(ActionEvent e) throws IOException{

    if(txfFName.getText().isEmpty() || txfLName.getText().isEmpty() || txfPNum.getText().isEmpty() || txfEMail.getText().isEmpty()) {
        Alert alert = new Alert(Alert.AlertType.WARNING);
        alert.setTitle("Information");
        alert.setHeaderText("");
        alert.setContentText("No DATA entered\n"+
        "ENTER new data and Alt + S to SAVE");
        alert.showAndWait();

        if(txfFName.getText().isEmpty()) {
            txfFName.requestFocus();
            return;
        }
        if(txfLName.getText().isEmpty()) {
            txfLName.requestFocus();
            return;
        }
        if(txfPNum.getText().isEmpty()) {
            txfPNum.requestFocus();
            return;
        }
        if(txfEMail.getText().isEmpty()) {
            txfEMail.requestFocus();
            return;
        }   
    }

    String fname = txfFName.getText().trim();
    String lname = txfLName.getText().trim();
    String pnum = txfPNum.getText().trim();
    String email = txfEMail.getText().trim();
    String data = (fname + "," + lname + "," + pnum + "," + email + "," + '\r');

    File dirPath = new File("C:/A_CSV");
    dirPath.mkdirs();//Make the directory

    File file = new File(dirPath,"People.csv");
    if(!file.exists()){
       file.createNewFile();//Create and empty text file
    }

    Alert alert1 = new Alert(AlertType.CONFIRMATION);
    alert1.setTitle("Confirm Save");
    alert1.setHeaderText("");
    alert1.setContentText("Select OK to Save Data");
    //Alert Do You Want to SAVE
    Optional<ButtonType> result = alert1.showAndWait();
    if (result.get() == ButtonType.OK){
        FileWriter fileWriter = new FileWriter(file.getPath(),true);
        try (BufferedWriter bufferWritter = new BufferedWriter(fileWriter)) {
            bufferWritter.write(data);

        //Alert that you did SAVE too many Alerts!          
        Alert alert = new Alert(AlertType.INFORMATION);
        alert.setTitle("Information Dialog");
        alert.setHeaderText(null);
        alert.setContentText("Data Saved");
        alert.showAndWait();
        txfFName.setText("");
        txfLName.setText("");
        txfPNum.setText("");
        txfEMail.setText("");
        txfFName.requestFocus();
    }

    } else {
        return;
        //if you did not save do we clear the entered data ?
        // ... user chose CANCEL or closed the dialog
    }
    }

    @FXML//Clear Fields and ArrayList
    private void onClear(ActionEvent e) {

    if(txfFName.getText().isEmpty()||txfLName.getText().isEmpty()||txfPNum.getText().isEmpty()||txfEMail.getText().isEmpty()) {
        Alert alert = new Alert(Alert.AlertType.WARNING);
        alert.setTitle("Information");
        alert.setHeaderText("");
        alert.setContentText("No Data Present to CLEAR\n"+
        "Click LOAD to Obtain Data");
        alert.showAndWait();
        return; 
    }
    i=0;
    list.clear();
    txfFName.setText("");
    txfLName.setText("");
    txfPNum.setText("");
    txfEMail.setText("");
    txfFName.requestFocus();
    }
    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {
        //table.setPlaceholder(new Label("No visible columns and/or data exist."));
    }

    }
Contacts Class
package appCSVFile;

public class Contacts {

    private String FName;
    private String LName;
    private String PNum;
    private String EMail;

    //public Contacts(String pFname, String pLname, String pPnum, String pEmail) {
        //super();
        //this.FName = pFname;
        //this.LName = pLname;
        //this.PNum  = pPnum;
        //this.EMail = pEmail;
    //}
    public Contacts(String pFname,String pLname, String pPnum, String pEmail){
        FName = pFname;
        LName = pLname;
        PNum =  pPnum;
        EMail = pEmail;
    }

    @Override
    public String toString(){
    return FName + "," + 
           LName + "," +
           PNum  + "," +
           EMail + "," + '\r' ;
}
    public String toFile(){
        return FName + "," + LName + "," + PNum + "," + EMail + "," +'\r';
    }
    public String getFName(){
        return FName;
    }
    public String getLName(){
        return LName;
    }
    public String getPnum(){
        return PNum;
    }
    public String getEmail(){
        return EMail;
    }
}

Person Class
package appCSVFile;

import javafx.beans.property.SimpleStringProperty;

public class Person  {

    private SimpleStringProperty vfname;
    private SimpleStringProperty vlname;
    private SimpleStringProperty vpnum;
    private SimpleStringProperty vemail;

    public Person () {
    }

    public Person (String s1, String s2, String s3, String s4) {

        vfname = new SimpleStringProperty(s1);
        vlname = new SimpleStringProperty(s2);
        vpnum  = new SimpleStringProperty(s3);
        vemail = new SimpleStringProperty(s4);
        //System.out.println(s1);//This produces data
        //System.out.println(vfname);//as does this StringProperty [value: what ever s1] 
    }

    public String getFName() {
        return vfname.get();
    }
    public void setFName(String s1) {   
        vfname.set(s1);
    }

    public String getLName() {
        return vlname.get();
    }
    public void setLName(String s2) {
        vlname.set(s2);
    }

    public String getPNum() {
        return vpnum.get();
    }
    public void setPNum(String s3) {
        vpnum.set(s3);
    }

    public String getEMail() {
        return vemail.get();
    }
    public void setEMail(String s4) {
        vemail.set(s4);
    }

}
FXML class
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.input.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane fx:id="apCSV" prefHeight="650.0" prefWidth="1040.0"
    xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
    fx:controller="appCSVFile.CSVController">
    <children>
        <Pane fx:id="paneONE" prefHeight="650.0" prefWidth="1040.0"
            style="-fx-background-color: lightgray;" AnchorPane.bottomAnchor="0.0"
            AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"
            AnchorPane.topAnchor="0.0">
            <children>
                <MenuBar style="-fx-background-color: lightgray;">
                    <menus>
                        <Menu mnemonicParsing="false" text="File">
                            <items>
                                <MenuItem mnemonicParsing="false" onAction="#onLoad"
                                    text="Load">
                                    <accelerator>
                                        <KeyCodeCombination alt="ANY" code="L"
                                            control="UP" meta="UP" shift="UP" shortcut="UP" />
                                    </accelerator>
                                </MenuItem>
                                <MenuItem mnemonicParsing="false" onAction="#oneSave"
                                    text="Save">
                                    <accelerator>
                                        <KeyCodeCombination alt="ANY" code="S"
                                            control="UP" meta="UP" shift="UP" shortcut="UP" />
                                    </accelerator>
                                </MenuItem>
                            </items>
                        </Menu>
                        <Menu mnemonicParsing="false" text="Edit">
                            <items>
                                <MenuItem mnemonicParsing="false" onAction="#onRemove"
                                    text="Remove">
                                    <accelerator>
                                        <KeyCodeCombination alt="ANY" code="R"
                                            control="UP" meta="UP" shift="UP" shortcut="UP" />
                                    </accelerator>
                                </MenuItem>
                                <MenuItem mnemonicParsing="false" onAction="#onClear"
                                    text="Clear">
                                    <accelerator>
                                        <KeyCodeCombination alt="ANY" code="C"
                                            control="UP" meta="UP" shift="UP" shortcut="UP" />
                                    </accelerator>
                                </MenuItem>
                            </items>
                        </Menu>
                        <Menu mnemonicParsing="false" text="Navigate">
                            <items>
                                <MenuItem mnemonicParsing="false" onAction="#onNext"
                                    text="Forward">
                                    <accelerator>
                                        <KeyCodeCombination alt="ANY" code="F"
                                            control="UP" meta="UP" shift="UP" shortcut="UP" />
                                    </accelerator>
                                </MenuItem>
                                <MenuItem mnemonicParsing="false" onAction="#onPrevious"
                                    text="Previous">
                                    <accelerator>
                                        <KeyCodeCombination alt="ANY" code="P"
                                            control="UP" meta="UP" shift="UP" shortcut="UP" />
                                    </accelerator>
                                </MenuItem>
                            </items>
                        </Menu>
                        <Menu mnemonicParsing="false" text="Help">
                            <items>
                                <MenuItem mnemonicParsing="false" onAction="#onDir"
                                    text="Directions" />
                                <MenuItem mnemonicParsing="false" text="About" />
                            </items>
                        </Menu>
                    </menus>
                </MenuBar>
                <Label focusTraversable="false" layoutX="50.0" layoutY="73.0"
                    text="First Name">
                    <font>
                        <Font size="18.0" />
                    </font>
                </Label>
                <TextField fx:id="txfFName" layoutX="150.0" layoutY="70.0"
                    style="-fx-font-weight: bold;" />
                <Label focusTraversable="false" layoutX="370.0" layoutY="73.0"
                    text="Last Name">
                    <font>
                        <Font size="18.0" />
                    </font>
                </Label>
                <TextField fx:id="txfLName" layoutX="470.0" layoutY="70.0"
                    prefHeight="28.0" prefWidth="230.0" style="-fx-font-weight: bold;" />
                <Label focusTraversable="false" layoutX="50.0" layoutY="113.0"
                    text="Phone Number">
                    <font>
                        <Font size="18.0" />
                    </font>
                </Label>
                <TextField fx:id="txfPNum" layoutX="179.0" layoutY="110.0"
                    prefHeight="28.0" prefWidth="164.0" style="-fx-font-weight: bold;"
                    text="505-412-7650" />
                <Label focusTraversable="false" layoutX="405.0" layoutY="113.0"
                    text="E-Mail">
                    <font>
                        <Font size="18.0" />
                    </font>
                </Label>
                <TextField fx:id="txfEMail" layoutX="470.0" layoutY="110.0"
                    prefHeight="28.0" prefWidth="230.0" style="-fx-font-weight: bold;" />
                <VBox fx:id="vbxDir" alignment="TOP_CENTER" layoutX="150.0"
                    layoutY="163.0" prefHeight="240.0" prefWidth="190.0" visible="false">
                    <children>
                        <Button focusTraversable="false" mnemonicParsing="false"
                            onAction="#onClose" style="-fx-font-weight: bold;" text="CLOSE" />
                        <TextArea focusTraversable="false" prefHeight="215.0"
                            prefWidth="190.0"
                            style="-fx-border-width: 2; -fx-border-color: blue; -fx-font-weight: bold;"
                            text="     Shortcut Directions&#10;&#10;Alt + L  to Load&#10;Alt + S  to Save&#10;&#10;Alt + R  to Remove&#10;Alt + C  to Clear&#10;&#10;Alt + F  Scroll Next&#10;Alt + P  Scroll Previous" />
                    </children>
                </VBox>
                <TableView fx:id="table" editable="true" layoutX="68.0"
                    layoutY="190.0" prefHeight="200.0" prefWidth="855.0">
                    <columns>
                        <TableColumn fx:id="tblColFName" maxWidth="200.0"
                            minWidth="200.0" prefWidth="200.0" text="First Name" />
                        <TableColumn fx:id="tblColLName" maxWidth="240.0"
                            minWidth="240.0" prefWidth="240.0" text="Last Name" />
                        <TableColumn fx:id="tblColPNum" maxWidth="175.0"
                            minWidth="175.0" prefWidth="175.0" text="Phone Number" />
                        <TableColumn fx:id="tblColEMail" maxWidth="240.0"
                            minWidth="240.0" prefWidth="240.0" text="Email Address" />
                    </columns>
                </TableView>
            </children>
        </Pane>
    </children>
</AnchorPane>

1 个答案:

答案 0 :(得分:0)

@James_Duh你的方向很好但是@James_D说了很多错误。我已经重新编写了代码,并提供了查看Book Learn JavaFX 8的建议,它非常完整。对于一个6年级的学生,你有完整的代码保持它

Main Class
package appCSVFile;

import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.fxml.FXMLLoader;


public class CSVMain extends Application {
    @Override
    public void start(Stage pStage) {
        try {
            AnchorPane root = (AnchorPane)FXMLLoader.load(getClass().getResource("csv.fxml"));
            Scene scene = new Scene(root,1040,650);
            pStage.setScene(scene);
            scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
            pStage.setResizable(false);
            pStage.setTitle("CSV File Demo");
            pStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

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

Controller Class

package appCSVFile;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.Optional;
import java.util.ResourceBundle;
import java.util.Scanner;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;

public class CSVController implements Initializable {

    @FXML private AnchorPane apCSV;
    @FXML private Pane paneONE;

    @FXML public TextField txfFName;
    @FXML public TextField txfLName;
    @FXML public TextField txfPNum;
    @FXML public TextField txfEMail;
    @FXML private VBox vbxDir;

    @FXML public TableView<Person> table;
    @FXML public TableColumn <Person,String> firstNameColumn;
    @FXML public TableColumn <Person,String> lastNameColumn;
    @FXML public TableColumn <Person,String> phoneNumberColumn;
    @FXML public TableColumn <Person,String> emailAddressColumn;

    FileChooser fc = new FileChooser();
    public ArrayList<Contacts> list;
    private ListIterator<Contacts> LIT;
    private int i;

    public ObservableList<Person> data;

    @FXML
    private void onDir(ActionEvent e) {
        vbxDir.setVisible(true);
        vbxDir.toFront();
    }
    @FXML
    private void onClose(ActionEvent e) {
        vbxDir.setVisible(false);
    }

    @FXML//Load CSV Data
    private void onLoad(ActionEvent e)throws IOException {

        data = FXCollections.observableArrayList();//Hold data for the table

        File fileInfo = new File("C:/A_CSV/People.csv");
        if(fileInfo.length()==0) {
            Alert alert = new Alert(Alert.AlertType.WARNING);
            alert.setTitle("Information");
            alert.setHeaderText("");
            alert.setContentText("No Data in File at "+ fileInfo+"\n"+
            "Enter Data and Save");
            alert.showAndWait();
            return;  
        }

        fc.setTitle("Load Contacts Info");
        fc.setInitialDirectory(new File("C:/"));
        fc.setInitialDirectory(new File("C:/A_CSV"));
        fc.setInitialFileName("People.csv");
        File file = fc.showOpenDialog(null);
        if (file == null) {
        return;
        }

        String correctFile = file.getName();
        if(!(correctFile.matches("People.csv"))){
            Alert alert = new Alert(Alert.AlertType.ERROR);
            alert.setTitle("Information");
            alert.setHeaderText("");
            alert.setContentText("The File at " + file + "\n\n"+
            "is NOT accociated with this application\n\n"+
            "Select the File at "+fileInfo);
            alert.showAndWait();
            return;
        }

        Path dirP = Paths.get(String.valueOf(file));
        InputStream in = Files.newInputStream(dirP);
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));

        list = new ArrayList<Contacts>();
        Scanner scan = new Scanner(reader);
        scan.useDelimiter("\\s*,\\s*");

        while (scan.hasNext()){
           String fname = scan.next();
           String lname = scan.next();
           String pnum = scan.next();
           String email = scan.next();

           txfFName.setText(String.valueOf(fname));
           txfLName.setText(String.valueOf(lname));
           txfPNum.setText(String.valueOf(pnum));
           txfEMail.setText(String.valueOf(email));

           list.add(new Contacts(fname,lname,pnum,email));
           data.add(new Person(fname,lname,pnum,email));
           table.setItems(data);

           firstNameColumn.setCellValueFactory(cellData -> cellData.getValue().firstNameProperty());
           lastNameColumn.setCellValueFactory(cellData -> cellData.getValue().lastNameProperty());
           phoneNumberColumn.setCellValueFactory(cellData -> cellData.getValue().phoneNumberProperty());
           emailAddressColumn.setCellValueFactory(cellData -> cellData.getValue().emailAddressProperty());

        }
        scan.close();

        LIT = list.listIterator();                  
        if (LIT.hasNext()){          
            Contacts p = LIT.next();
            getContacts(p); 
        } 
    }

    @FXML//This code removes data from the ArrayList and RE-Writes to the
     //People.csv file the file is deleted first then rewritten
    private void onRemove(ActionEvent e)throws IOException{

    if(txfFName.getText().isEmpty()||txfLName.getText().isEmpty()||txfPNum.getText().isEmpty()||txfEMail.getText().isEmpty()) {
        Alert alert = new Alert(Alert.AlertType.WARNING);
        alert.setTitle("Information");
        alert.setHeaderText("");
        alert.setContentText("No Data Present to REMOVE\n"+
        "Click LOAD to Obtain Data");
        alert.showAndWait();
        return; 
    }

    list.get(i);
    list.remove(i);

    if(0 == list.size()){
    Path path = FileSystems.getDefault().getPath("C:/A_CSV", "People.csv");
    Files.delete(path);
        onClear(e);
        list.clear();
    return;
    }else if(i == list.size()){     
        i = i - 1;
    }
    Contacts p = list.get(i);
        getContacts(p);
        Contacts dat;

        for(int r = 0; r <list.size(); r++){
        dat = list.get(r);  
        }  
       Path path = FileSystems.getDefault().getPath("C:/A_CSV", "People.csv");
       Files.delete(path);

       File file = new File("C:/A_CSV/People.csv");
            if(!file.exists()){
            file.createNewFile();
        }

        FileWriter fileWriter = new FileWriter(file.getPath(),true);
        BufferedWriter bufferWritter = new BufferedWriter(fileWriter);  
        Iterator<Contacts> LIT = list.iterator();
            while(LIT.hasNext()) {
                dat = LIT.next();
                String d = dat.toString();
                bufferWritter.write(d);
        }

        bufferWritter.close();
        onClear(e);
        //list.clear();//this is done by onClear(e)
        txfFName.requestFocus();
    }

    @FXML//Scroll forward through the ArrayList
    private void onNext(ActionEvent e) {

        if (list == null || list.size() == 0) {
        Alert alert = new Alert(Alert.AlertType.WARNING);
        alert.setTitle("Information");
        alert.setHeaderText("");
        alert.setContentText("Load Data First");
        alert.showAndWait();
        return;
        }

        if (i == list.size()- 1) {
        i = 0;
        Alert alert = new Alert(Alert.AlertType.WARNING);
        alert.setTitle("Information");
        alert.setHeaderText("");
        alert.setContentText("Last Record in File");
        alert.showAndWait();
        i= list.size()-1;
        return;
        }else {
        i = i + 1;
        }
            Contacts p = list.get(i);
            getContacts(p); 
    }

    @FXML//Scroll backwards through the ArrayList
    private void onPrevious(ActionEvent e) {

        if (list == null || list.size() == 0) {
        Alert alert = new Alert(Alert.AlertType.WARNING);
        alert.setTitle("Information");
        alert.setHeaderText("");
        alert.setContentText("Load Data First");
        alert.showAndWait();
        return;
        }

        if (i == 0) {
        i = list.size()-1;
        Alert alert = new Alert(Alert.AlertType.WARNING);
        alert.setTitle("Information");
        alert.setHeaderText("");
        alert.setContentText("First Record in File");
        alert.showAndWait();
        i=0;
        return;
        }else {
        i = i - 1 ;
        }
            Contacts p = list.get(i); 
            getContacts(p);
    }

    //Helper for Contacts Class
    private void getContacts(Contacts p){
        txfFName.setText("" + p.getFName());
        txfLName.setText("" + p.getLName());
        txfPNum.setText ("" + p.getPnum());
        txfEMail.setText("" + p.getEmail());    
    }

    @FXML
    private void oneSave(ActionEvent e) throws IOException{

    if(txfFName.getText().isEmpty() || txfLName.getText().isEmpty() || txfPNum.getText().isEmpty() || txfEMail.getText().isEmpty()) {
        Alert alert = new Alert(Alert.AlertType.WARNING);
        alert.setTitle("Information");
        alert.setHeaderText("");
        alert.setContentText("No DATA entered\n"+
        "ENTER new data and Alt + S to SAVE");
        alert.showAndWait();

        if(txfFName.getText().isEmpty()) {
            txfFName.requestFocus();
            return;
        }
        if(txfLName.getText().isEmpty()) {
            txfLName.requestFocus();
            return;
        }
        if(txfPNum.getText().isEmpty()) {
            txfPNum.requestFocus();
            return;
        }
        if(txfEMail.getText().isEmpty()) {
            txfEMail.requestFocus();
            return;
        }   
    }

    String fname = txfFName.getText().trim();
    String lname = txfLName.getText().trim();
    String pnum = txfPNum.getText().trim();
    String email = txfEMail.getText().trim();
    String data = (fname + "," + lname + "," + pnum + "," + email + "," + '\r');

    File dirPath = new File("C:/A_CSV");
    dirPath.mkdirs();//Make the directory

    File file = new File(dirPath,"People.csv");
    if(!file.exists()){
       file.createNewFile();//Create and empty text file
    }

    Alert alert1 = new Alert(AlertType.CONFIRMATION);
    alert1.setTitle("Confirm Save");
    alert1.setHeaderText("");
    alert1.setContentText("Select OK to Save Data");
    //Alert Do You Want to SAVE
    Optional<ButtonType> result = alert1.showAndWait();
    if (result.get() == ButtonType.OK){
        FileWriter fileWriter = new FileWriter(file.getPath(),true);
        try (BufferedWriter bufferWritter = new BufferedWriter(fileWriter)) {
            bufferWritter.write(data);

        //Alert that you did SAVE too many Alerts!          
        Alert alert = new Alert(AlertType.INFORMATION);
        alert.setTitle("Information Dialog");
        alert.setHeaderText(null);
        alert.setContentText("Data Saved");
        alert.showAndWait();
        txfFName.setText("");
        txfLName.setText("");
        txfPNum.setText("");
        txfEMail.setText("");
        txfFName.requestFocus();
        table.getItems().clear();//Clears the table
    }

    } else {
        return;
        //if you did not save do we clear the entered data ?
        // ... user chose CANCEL or closed the dialog
    }
    }

    @FXML//Clear Fields and ArrayList
    private void onClear(ActionEvent e) {

    if(txfFName.getText().isEmpty()||txfLName.getText().isEmpty()||txfPNum.getText().isEmpty()||txfEMail.getText().isEmpty()) {
        Alert alert = new Alert(Alert.AlertType.WARNING);
        alert.setTitle("Information");
        alert.setHeaderText("");
        alert.setContentText("No Data Present to CLEAR\n"+
        "Click LOAD to Obtain Data");
        alert.showAndWait();
        return; 
    }
    table.getItems().clear();
    i=0;
    list.clear();
    txfFName.setText("");
    txfLName.setText("");
    txfPNum.setText("");
    txfEMail.setText("");
    txfFName.requestFocus();
    }
    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {
        table.setPlaceholder(new Label("Select Help then Click Directions or Alt + L to Load Data"));

    }

    }

Contacts Class
package appCSVFile;

public class Contacts {

    private String FName;
    private String LName;
    private String PNum;
    private String EMail;

    //public Contacts(String pFname, String pLname, String pPnum, String pEmail) {
        //super();
        //this.FName = pFname;
        //this.LName = pLname;
        //this.PNum  = pPnum;
        //this.EMail = pEmail;
    //}
    public Contacts(String pFname,String pLname, String pPnum, String pEmail){
        FName = pFname;
        LName = pLname;
        PNum =  pPnum;
        EMail = pEmail;
    }

    @Override
    public String toString(){
    return FName + "," + 
           LName + "," +
           PNum  + "," +
           EMail + "," + '\r' ;
}
    public String toFile(){
        return FName + "," + LName + "," + PNum + "," + EMail + "," +'\r';
    }
    public String getFName(){
        return FName;
    }
    public String getLName(){
        return LName;
    }
    public String getPnum(){
        return PNum;
    }
    public String getEmail(){
        return EMail;
    }
}

Person Class
package appCSVFile;

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

public class Person {
    //This belongs to CSV Controller
    //===============================
    private final StringProperty firstName = new SimpleStringProperty(this, "firstName", null);
    private final StringProperty lastName = new SimpleStringProperty(this, "lastName", null);
    private final StringProperty phoneNumber = new SimpleStringProperty(this, "phoneNumber", null);
    private final StringProperty emailAddress = new SimpleStringProperty(this, "emailAddress", null);

    public Person() {
        this(null, null, null,null);
    }

    public Person(String firstName, String lastName, String phoneNumber,String emailAddress) {
        this.firstName.set(firstName);
        this.lastName.set(lastName);
        this.phoneNumber.set(phoneNumber);
        this.emailAddress.set(emailAddress);
        }

    /* firstName Property */
    public final String getFirstName() {//1
    return firstName.get();
    }
    public final void setFirstName(String firstName) {//1
    firstNameProperty().set(firstName);
    }

    public final StringProperty firstNameProperty() {//1
    return firstName;
    }

    public final String getLasttName() {//2
    return lastName.get();
    }
    public final void setLastName(String lastName) {//2
    lastNameProperty().set(lastName);
    }

    public final StringProperty lastNameProperty() {//2
    return lastName;
    }

    public final String getPhoneNumber() {//3
    return phoneNumber.get();
    }
    public final void setPhoneNumber(String phoneNumber) {//3
    phoneNumberProperty().set(phoneNumber);
    }

    public final StringProperty phoneNumberProperty() {//3
    return phoneNumber;
    }

    public final String getEmailAddress() {
    return emailAddress.get();
    }
    public final void setEmailAddress(String emailAddress) {
    emailAddressProperty().set(emailAddress);
    }

    public final StringProperty emailAddressProperty() {
    return emailAddress;
    }
}
FXML file
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.input.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane fx:id="apCSV" prefHeight="650.0" prefWidth="1040.0"
    xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
    fx:controller="appCSVFile.CSVController">
    <children>
        <Pane fx:id="paneONE" prefHeight="650.0" prefWidth="1040.0"
            style="-fx-background-color: lightgray;" AnchorPane.bottomAnchor="0.0"
            AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"
            AnchorPane.topAnchor="0.0">
            <children>
                <MenuBar style="-fx-background-color: lightgray;">
                    <menus>
                        <Menu mnemonicParsing="false" text="File">
                            <items>
                                <MenuItem mnemonicParsing="false" onAction="#onLoad"
                                    text="Load">
                                    <accelerator>
                                        <KeyCodeCombination alt="ANY" code="L"
                                            control="UP" meta="UP" shift="UP" shortcut="UP" />
                                    </accelerator>
                                </MenuItem>
                                <MenuItem mnemonicParsing="false" onAction="#oneSave"
                                    text="Save">
                                    <accelerator>
                                        <KeyCodeCombination alt="ANY" code="S"
                                            control="UP" meta="UP" shift="UP" shortcut="UP" />
                                    </accelerator>
                                </MenuItem>
                            </items>
                        </Menu>
                        <Menu mnemonicParsing="false" text="Edit">
                            <items>
                                <MenuItem mnemonicParsing="false" onAction="#onRemove"
                                    text="Remove">
                                    <accelerator>
                                        <KeyCodeCombination alt="ANY" code="R"
                                            control="UP" meta="UP" shift="UP" shortcut="UP" />
                                    </accelerator>
                                </MenuItem>
                                <MenuItem mnemonicParsing="false" onAction="#onClear"
                                    text="Clear">
                                    <accelerator>
                                        <KeyCodeCombination alt="ANY" code="C"
                                            control="UP" meta="UP" shift="UP" shortcut="UP" />
                                    </accelerator>
                                </MenuItem>
                            </items>
                        </Menu>
                        <Menu mnemonicParsing="false" text="Navigate">
                            <items>
                                <MenuItem mnemonicParsing="false" onAction="#onNext"
                                    text="Forward">
                                    <accelerator>
                                        <KeyCodeCombination alt="ANY" code="F"
                                            control="UP" meta="UP" shift="UP" shortcut="UP" />
                                    </accelerator>
                                </MenuItem>
                                <MenuItem mnemonicParsing="false" onAction="#onPrevious"
                                    text="Previous">
                                    <accelerator>
                                        <KeyCodeCombination alt="ANY" code="P"
                                            control="UP" meta="UP" shift="UP" shortcut="UP" />
                                    </accelerator>
                                </MenuItem>
                            </items>
                        </Menu>
                        <Menu mnemonicParsing="false" text="Help">
                            <items>
                                <MenuItem mnemonicParsing="false" onAction="#onDir"
                                    text="Directions" />
                                <MenuItem mnemonicParsing="false" text="About" />
                            </items>
                        </Menu>
                    </menus>
                </MenuBar>
                <Label focusTraversable="false" layoutX="50.0" layoutY="73.0"
                    text="First Name">
                    <font>
                        <Font size="18.0" />
                    </font>
                </Label>
                <TextField fx:id="txfFName" layoutX="150.0" layoutY="70.0"
                    style="-fx-font-weight: bold;" />
                <Label focusTraversable="false" layoutX="370.0" layoutY="73.0"
                    text="Last Name">
                    <font>
                        <Font size="18.0" />
                    </font>
                </Label>
                <TextField fx:id="txfLName" layoutX="470.0" layoutY="70.0"
                    prefHeight="28.0" prefWidth="230.0" style="-fx-font-weight: bold;" />
                <Label focusTraversable="false" layoutX="50.0" layoutY="113.0"
                    text="Phone Number">
                    <font>
                        <Font size="18.0" />
                    </font>
                </Label>
                <TextField fx:id="txfPNum" layoutX="179.0" layoutY="110.0"
                    prefHeight="28.0" prefWidth="164.0" style="-fx-font-weight: bold;"
                    text="505-412-7650" />
                <Label focusTraversable="false" layoutX="405.0" layoutY="113.0"
                    text="E-Mail">
                    <font>
                        <Font size="18.0" />
                    </font>
                </Label>
                <TextField fx:id="txfEMail" layoutX="470.0" layoutY="110.0"
                    prefHeight="28.0" prefWidth="230.0" style="-fx-font-weight: bold;" />
                <VBox fx:id="vbxDir" alignment="TOP_CENTER" layoutX="150.0"
                    layoutY="163.0" prefHeight="240.0" prefWidth="190.0" visible="false">
                    <children>
                        <Button focusTraversable="false" mnemonicParsing="false"
                            onAction="#onClose" style="-fx-font-weight: bold;" text="CLOSE" />
                        <TextArea focusTraversable="false" prefHeight="215.0"
                            prefWidth="190.0"
                            style="-fx-border-width: 2; -fx-border-color: blue; -fx-font-weight: bold;"
                            text="     Shortcut Directions&#10;&#10;Alt + L  to Load&#10;Alt + S  to Save&#10;&#10;Alt + R  to Remove&#10;Alt + C  to Clear&#10;&#10;Alt + F  Scroll Next&#10;Alt + P  Scroll Previous" />
                    </children>
                </VBox>
                <TableView fx:id="table" editable="true" layoutX="50.0"
                    layoutY="190.0" prefHeight="200.0" prefWidth="861.0">
                    <columns>
                        <TableColumn fx:id="firstNameColumn" editable="false"
                            maxWidth="200.0" minWidth="200.0" prefWidth="200.0" resizable="false"
                            sortable="false" text="First Name" />
                        <TableColumn fx:id="lastNameColumn" editable="false"
                            maxWidth="240.0" minWidth="240.0" prefWidth="240.0" resizable="false"
                            text="Last Name" />
                        <TableColumn fx:id="phoneNumberColumn" editable="false"
                            maxWidth="175.0" minWidth="175.0" prefWidth="175.0" resizable="false"
                            sortable="false" text="Phone Number" />
                        <TableColumn fx:id="emailAddressColumn" editable="false"
                            maxWidth="240.0" minWidth="240.0" prefWidth="240.0" resizable="false"
                            sortable="false" text="Email Address" />
                    </columns>
                </TableView>
            </children>
        </Pane>
    </children>
</AnchorPane>