-1

I need help to understand the working of File handling in Java.

This is what I am doing:

import java.awt.LayoutManager;
import java.awt.event.ActionEvent;             
import java.awt.event.ActionListen;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.*;
import java.awt.Color;
import java.io.IOException;
import java.io.Writer;
import java.io.BufferedWriter;
import java.io.FileWriter;

public class Management extends JFrame implements ActionListener{

private ImageIcon image;
private static final long serialVersionUID = 1L;
private JTextField jt1, jt2, jt3, jt4;
private JLabel jl1, jl2, jl3, jl4, jl5, jl6;
private JButton jb1, jb2, jb3;
private JTextArea ja1;
private int id=1;
private ArrayList<Pateint> data = new ArrayList();
private int find;
private int x=0;
private final JLabel label = new JLabel("New label");

public Management(){
    label.setBackground(Color.GRAY);
    
    JLabel background;
    setSize(2048,1189);
    setLocationRelativeTo(null);
    image = new ImageIcon("1.jpg");
    background  = new JLabel("",image,JLabel.CENTER);
    background.setBounds(0,0,1200,700);
    getContentPane().add(background);
    setContentPane(new JLabel(new ImageIcon("1.jpg ")));
    setTitle("Clinic Management System");

    setLocation(400,500);
    setVisible(true);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    getContentPane().setLayout(null);

    jl1 = new JLabel("Please select one Option");
    jl1.setBounds(400, 270, 200,30);
    jt1 = new JTextField();
    jt1.setVisible(false);

    jt1.setBounds(200,200, 300,30);
    getContentPane().add(jl1);
    getContentPane().add(jt1);

    jb1 = new JButton("Book An Appointment");
    jb1.setBounds(300,300,200,200);
    getContentPane().add(jb1);

    jb2 = new JButton("View Pateints Record");
    jb2.setBounds(540, 300, 200, 200);
    getContentPane().add(jb2);

    jl2 = new JLabel("Enter Pateints Name:");
    jl2.setBounds(200, 170, 200, 30);
    getContentPane().add(jl2);
    jl2.setVisible(false);

    jl3 = new JLabel("Enter Phone number");
    jl3.setBounds(200, 250, 200,30);
    jl3.setVisible(false);
    getContentPane().add(jl3);

    jt2 = new JTextField();
    jt2.setBounds(200, 290, 300,30);
    jt2.setVisible(false);
    getContentPane().add(jt2);

    jt3 = new JTextField();
    jt3.setBounds(200, 360, 300,30);
    jt3.setVisible(false);
    getContentPane().add(jt3);

    jl4 = new JLabel("Enter Pateints Address: ");
    jl4.setBounds(200, 330, 200, 30);
    jl4.setVisible(false);
    getContentPane().add(jl4);

    ja1 = new JTextArea();
    ja1.setBounds(600, 200, 400, 200);
    ja1.setVisible(false);
    getContentPane().add(ja1);

    jl5 = new JLabel("Please Enter Description about your Disease");
    jl5.setBounds(600, 170, 300, 30);
    jl5.setVisible(false);
    getContentPane().add(jl5);

    jt4= new JTextField();
    jt4.setVisible(false);
    jt4.setBounds(600, 480, 300, 30);
    getContentPane().add(jt4);

    jl6 = new JLabel("Enter Date of appointment DD/MM/YYYY");
    jl6.setBounds(600, 450, 300, 30);
    jl6.setVisible(false);
    getContentPane().add(jl6);

    jb3 = new JButton("Submit");
    jb3.setBounds(500, 550, 100,30);
    jb3.setVisible(false);
    getContentPane().add(jb3);

    jb1.addActionListener(this);
    jb2.addActionListener(this);
    jb3.addActionListener(this);
}


@Override
public void actionPerformed(ActionEvent ae) {
    if(ae.getSource()==jb1){
        jb1.setVisible(false);
        jb2.setVisible(false);
        jl1.setVisible(false);

        jt1.setVisible(true);
        jl2.setVisible(true);
        jt2.setVisible(true);
        jl3.setVisible(true);
        jl4.setVisible(true);
        jt3.setVisible(true);
        ja1.setVisible(true);
        jl5.setVisible(true);
        jt4.setVisible(true);
        jl6.setVisible(true);
        jb3.setVisible(true);
    }
    else if(ae.getSource()==jb2){
        jb1.setVisible(true);
        jb2.setVisible(true);
        jl1.setVisible(true);
        find = Integer.parseInt(JOptionPane.showInputDialog(null, "Enter Pateint's ID"));
        for(int i=0; i<data.size(); i++){
            if(find==data.get(i).id){
                JOptionPane.showMessageDialog(null, "Name : "
                + data.get(i).name + " \nPhone : " + data.get(i).phone + "\nI.D : " +
                    data.get(i).id);
                break;
            }
        }
    }
    else if(ae.getSource()==jb3){
        jb1.setVisible(true);
        jb2.setVisible(true);
        jl1.setVisible(true);

        jb3.setVisible(false);
        jt1.setVisible(false);
        jl2.setVisible(false);
        jt2.setVisible(false);
        jl3.setVisible(false);
        jl4.setVisible(false);
        jt3.setVisible(false);
        ja1.setVisible(false);
        jl5.setVisible(false);
        jt4.setVisible(false);
        jl6.setVisible(false);
        jb3.setVisible(false);
        data.add(x, new Pateint(jt1.getText(), jt2.getText(), jt3.getText(), ja1.getText(), jt4.getText(), x+1));
        x++;
    }
}
public void ToFile(String[] filename , Arraylist<> data)
{
try {
FileWriter file = new FileWriter(filename: "accounts.txt",append: true);
BufferedWriter buffWrite = new BufferedWriter(file);
            buffWrite.append("Enter Patients Name: ");
            buffWrite.append(jt1.getText());
            buffWrite.append(" ");
            buffWrite.append("Enter Phone Number");
            buffWrite.append(jt2.getText());
            buffWrite.append("Enter Phone number");
            buffWrite.append(jt3.getText());
            buffWrite.append("Please Enter Description about your Disease");
            buffWrite.append(jt4.getText());
            buffWrite.append("Enter Pateints Address: ");
            buffWrite.append(ja1.getText());
            buffWrite.close();
}
catch(IOException e)

{
  System.out.println("Error writing");
}
}

problem: Exception Note: I am a newbie with this concept to please tell me what is wrong with my code.

I created a management system for the clinic. Where patient books their appointment. They enter their name, phone number, address, description and date.

     private ArrayList<Pateint> data = new ArrayList();

The main Java calls the managememt class.

When text is entered and the application is closed. A text file should be created with all written typed text in it.

A text file should be created but it is not. I have tried for hours now but can not do it properly. I can not understand what is wrong with my code.

I need to see some code for this, while I am continuously trying to fix my code.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Shadow
  • 1
  • 1
  • 5
    It looks like you're expecting the `ToFile` method to be called when the application is closed - but I see no calls to it. – Jon Skeet Oct 28 '21 at 05:58
  • 2
    I would also consider exploring other file formats like JSON or XML (or even just CSV) which will provide you some inbuilt structures and support. You should always be considering how you're going to read it back again. In your particular case, I would remove the UI from the equation entirely and focus on getting the file written and read – MadProgrammer Oct 28 '21 at 06:00
  • 1
    I would also suggest having a look at [A Visual Guide to Layout Managers](https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html) and [`CardLayout`](https://docs.oracle.com/javase/tutorial/uiswing/layout/card.html) in particular – MadProgrammer Oct 28 '21 at 06:03
  • 1
    "problem: Exception" - do you mean you get an exception? In that case details on the exception might help (always include the stacktrace when asking about exceptions). You might also want to read [ask]. – Thomas Oct 28 '21 at 06:13
  • 2
    General tips (not covered above): 1) Don't wait to get 200+ lines of code before debugging vital functionality like appending text to a file. That could be done in around 40 LOC. 2) Change every catch to include something like `e.printStackTrace()` 3) Use a logical and consistent form of code formatting / indentation. It makes code much easier to read. 4) Add basic debugging statements (`println`) to methods to check they are called as you expect. 5) `setContentPane(new JLabel(new ImageIcon("1.jpg ")));` a) Leave image backgrounds out of code like this, they are irrelevant to the problem. .. – Andrew Thompson Oct 28 '21 at 06:13
  • (5) b) Don't use a label for a BG, but instead use a custom painted panel, and c) Load application resources using `getResource(..)` - they will be unavailable as a `File` at time of deployment. – Andrew Thompson Oct 28 '21 at 06:14
  • 2
    _I am a newbie with this concept_ Then I suggest you read [Creating a GUI With Swing](https://docs.oracle.com/javase/tutorial/uiswing/) which is part of Oracle's Java tutorials. I also recommend that you **not** use the GUI builder of your IDE to write _Swing_ applications. – Abra Oct 28 '21 at 06:19
  • 1
    *I need to see some code for this* Did you search for some? I bet there are a lot of examples out there. – Ole V.V. Oct 28 '21 at 06:31
  • Do **not** use the 'back' button to edit a question! It destroys edits made by others. Instead use the [edit] link below the tags. – Andrew Thompson Oct 28 '21 at 18:10

1 Answers1

0

Ok, so you have a number of issues, but, lets first focus on "file writing" issues.

A really important place to start is the Basic I/O lesson, just so you can get your head around, well, the basics.

One of the important goals of any solution should be to reduce coupling (between classes). Part of this is a process of reducing the amount "knowledge" (or implementation detail) of the system other parts of the solution might have. They just shouldn't care.

So, the first thing we want to do, is manage "bookings", so lets start there. You've established the basic requirements of a booking and we can describe it as such...

public interface Booking {
    public String getName();
    public String getPhoneNumber();
    public String getAddress();
    public String getDescription();
    public LocalDate getDateOfBirth();
}

Now, we need some way for the other parts of the system to interact with this data, in away which decouples them from the underlying implementation, I'm mean, why would the booking view care how the bookings are stored, it just cares it can make them :/

So, lets add a PatientRepository

public interface PatientRepository {
    public Booking createBooking(String name, String phoneNumber, String address, String description, LocalDate dob) throws IOException;
}

Ok, so, this "describes" parts of the systems, providing information about how some elements can be created, what we need next is some kind of implementation.

A booking is pretty basic, it's just a POJO, encapsulating the captured information...

public class DefaultBooking implements Booking {

    private String name;
    private String phoneNumber;
    private String address;
    private String description;
    private LocalDate dateOfBirth;

    public DefaultBooking(String name, String phoneNumber, String address, String description, LocalDate dateOfBirth) {
        this.name = name;
        this.phoneNumber = phoneNumber;
        this.address = address;
        this.description = description;
        this.dateOfBirth = dateOfBirth;
    }

    public String getName() {
        return name;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public String getAddress() {
        return address;
    }

    public String getDescription() {
        return description;
    }

    public LocalDate getDateOfBirth() {
        return dateOfBirth;
    }

}

The PatientRepository is a little more complicated.

Rolling your own file format is always a lot of work and I would consider things like JAXB/XML, JSON, CSV (using something like OpenCSV or Apache Commons CSV), but ultimately, your end goal should be to make use of some kind of database and make use of JDBC (possibly making use of something H2 or HSQL) (IMHO)

For this example, we're just rolling a simple line based file using ; as a property delimiter (or separator)

public class DefaultPatientRepository implements PatientRepository {

    private List<Booking> bookings;

    public DefaultPatientRepository() throws IOException {
        bookings = new ArrayList<>(32);
        File sourceFile = new File("Clinic.txt");
        if (sourceFile.exists()) {
            try (BufferedReader br = new BufferedReader(new FileReader(sourceFile))) {
                String line = null;
                while ((line = br.readLine()) != null) {
                    String parts[] = line.split(";");

                    String name = parts[0];
                    String phoneNumber = parts[1];
                    String address = parts[2];
                    String description = parts[3];
                    String dob = parts[4];

                    LocalDate dateOfBirth = LocalDate.parse(dob, DateTimeFormatter.ISO_LOCAL_DATE);

                    Booking booking = new DefaultBooking(name, phoneNumber, address, description, dateOfBirth);
                    bookings.add(booking);
                }
            }

            System.out.println("!! Loaded " + bookings.size() + " bookings");
        }
    }

    @Override
    public Booking createBooking(String name, String phoneNumber, String address, String description, LocalDate dob) throws IOException {
        // Rolling your own file format is just a complete pain in the ... code
        // To my mind, I'd explore XML, JSON and possibly even CSV if you're
        // not ready for a SQL based database solution, but I'm old and I'm lazy :P

        try (BufferedWriter bw = new BufferedWriter(new FileWriter(new File("Clinic.txt"), true))) {
            StringJoiner joiner = new StringJoiner(";");
            joiner.add(name);
            joiner.add(phoneNumber);
            joiner.add(address);
            joiner.add(description);
            joiner.add(DateTimeFormatter.ISO_LOCAL_DATE.format(dob));

            bw.write(joiner.toString());
            bw.newLine();
        }

        return new DefaultBooking(name, phoneNumber, address, description, dob);
    }

}

So, without doing anything else, we now have a basic solution. You can test it and verify it's functionality without the needed to include any other parts of the system.

A word of warning though, this solution will store the Clinic.txt in the current working directory, this can be problematic for a number of reasons.

  1. The working directory isn't static and is contextual to the location from which the program was launched
  2. The current work directory might be write protected (this happens way more often then you think)

For this, I would have a look at my answer for java- reading the properties file outside of jar file or Get current path of executed file which describes making use of "well known locations" based on the platform

And now, we've reached the point we can introduce the UI.

I strongly encourage you to have a look at A Visual Guide to Layout Managers and How to Use CardLayout

User interfaces are typically very complex and involve multiple different views and interactions. You want to spend you're time decoupling the views from each other and managing the scope of responsibility.

For example, just in your basic example, you have three distinct views.

  1. The menu
  2. The booking view
  3. The patient view (presumably involving some kind of search, which will add another view)

The menu doesn't care about the other two nor does it have an responsibility for managing them beyond showing them when the user requests them.

Equally, the other views don't care about the menu. All they really need to do is tell "some body" that they are no longer needed by the user.

The following example is an attempt to demonstrate a "possible" solution based around the use of CardLayout, it makes use of such concepts as

  • Observer pattern
  • Dependency injection
  • Decoupling of responsibilities

One particular feature you should pay attention to, is the ease at which it would be change the underlying implementation of the PatientRepository (to use a different file format, local database or even a web service), as the implementation is not tightly coupled to the rest of the system

import java.awt.CardLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.EventListener;
import java.util.EventObject;
import java.util.List;
import java.util.StringJoiner;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class Test {

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

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    PatientRepository patientRepository = new DefaultPatientRepository();
                    JFrame frame = new JFrame();
                    frame.add(new ClinicPane(patientRepository));
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    ex.printStackTrace();
                    JOptionPane.showMessageDialog(null, "Failed to load patient repository", "Error", JOptionPane.ERROR_MESSAGE);
                }
            }
        });
    }

    public class ClinicPane extends JPanel {

        private CardLayout cardLayout;
        private PatientRepository patientRepository;
        private DismissablePaneListener dismissablePaneListener = new DismissablePaneListener() {
            @Override
            public void didDismissView(DismissablePaneEvent evt) {
                // If you really wanted to you could consider having some kind
                // of idenitifier for the view and then have some custom logic
                // in place to determine which view to show next, but in this
                // case, we just want to show the menu again
                cardLayout.show(ClinicPane.this, "MainMenu");
            }
        };

        public ClinicPane(PatientRepository patientRepository) {
            this.patientRepository = patientRepository;
            cardLayout = new CardLayout();
            setLayout(cardLayout);

            add(new MenuPane(new MenuListener() {
                @Override
                public void didSelectMenuOption(MenuEvent evt) {
                    switch (evt.getOption()) {
                        case MAKE_A_BOOKING:
                            cardLayout.show(ClinicPane.this, "Booking");
                            break;
                        case VIEW_PATIENT_RECORD:
                            cardLayout.show(ClinicPane.this, "Patient");
                            break;
                    }

                }
            }), "MainMenu");

            BookingPane bookingPane = new BookingPane(patientRepository);
            configure(bookingPane);
            add(bookingPane, "Booking");

            PatientPane patientPane = new PatientPane(patientRepository);
            configure(patientPane);
            add(patientPane, "Patient");
        }

        protected DismissablePaneListener getDismissablePaneListener() {
            return dismissablePaneListener;
        }

        protected void configure(DismissablePane dismissablePane) {
            dismissablePane.addDismissablePaneListener(getDismissablePaneListener());
        }

        public PatientRepository getPatientRepository() {
            return patientRepository;
        }

    }

    public enum MenuOption {
        MAKE_A_BOOKING,
        VIEW_PATIENT_RECORD,
    }

    public class MenuEvent extends EventObject {

        private MenuOption option;

        public MenuEvent(Object source, MenuOption option) {
            super(source);
            this.option = option;
        }

        public MenuOption getOption() {
            return option;
        }

    }

    public interface MenuListener extends EventListener {
        public void didSelectMenuOption(MenuEvent evt);
    }

    public class MenuPane extends JPanel {

        public MenuPane() {
            this(null);
        }

        public MenuPane(MenuListener listener) {
            if (listener != null) {
                addMenuListener(listener);
            }
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.insets = new Insets(8, 8, 8, 8);

            add(new JLabel("Please select one Option"), gbc);
            add(makeButtonFor(MenuOption.MAKE_A_BOOKING), gbc);
            add(makeButtonFor(MenuOption.VIEW_PATIENT_RECORD), gbc);
        }

        public void addMenuListener(MenuListener listener) {
            listenerList.add(MenuListener.class, listener);
        }

        public void removeMenuListener(MenuListener listener) {
            listenerList.remove(MenuListener.class, listener);
        }

        protected JButton makeButtonFor(MenuOption action) {
            JButton btn = new JButton("Unknown action");
            switch (action) {
                case MAKE_A_BOOKING:
                    btn.setText("Make a booking");
                    btn.addActionListener(new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            fireDidSelectMenuOption(action);
                        }
                    });
                    break;
                case VIEW_PATIENT_RECORD:
                    btn.setText("View patient record");
                    btn.addActionListener(new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            fireDidSelectMenuOption(action);
                        }
                    });
                    break;
            }
            return btn;
        }

        protected void fireDidSelectMenuOption(MenuOption option) {
            MenuListener[] listeners = listenerList.getListeners(MenuListener.class);
            if (listeners.length == 0) {
                return;
            }
            MenuEvent evt = new MenuEvent(this, option);
            for (MenuListener listener : listeners) {
                listener.didSelectMenuOption(evt);
            }
        }

    }

    public class DismissablePaneEvent extends EventObject {

        public DismissablePaneEvent(DismissablePane source) {
            super(source);
        }

        public DismissablePane getDismissablePane() {
            return (DismissablePane) getSource();
        }

    }

    public interface DismissablePaneListener extends EventListener {
        public void didDismissView(DismissablePaneEvent evt);
    }

    public interface DismissablePane {
        public JPanel getPane();
        public void addDismissablePaneListener(DismissablePaneListener listener);
        public void removeDismissablePaneListener(DismissablePaneListener listener);
    }

    public abstract class AbstractDismissablePane extends JPanel implements DismissablePane {

        @Override
        public JPanel getPane() {
            return this;
        }

        @Override
        public void addDismissablePaneListener(DismissablePaneListener listener) {
            listenerList.add(DismissablePaneListener.class, listener);
        }

        @Override
        public void removeDismissablePaneListener(DismissablePaneListener listener) {
            listenerList.remove(DismissablePaneListener.class, listener);
        }

        protected void fireDidDismissPane() {
            DismissablePaneListener[] listeners = listenerList.getListeners(DismissablePaneListener.class);
            if (listeners.length == 0) {
                return;
            }
            DismissablePaneEvent evt = new DismissablePaneEvent(this);
            for (DismissablePaneListener listener : listeners) {
                listener.didDismissView(evt);
            }
        }

    }

    public class BookingPane extends AbstractDismissablePane {

        private PatientRepository patientRepository;

        public BookingPane(PatientRepository patientRepository) {
            this.patientRepository = patientRepository;
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.insets = new Insets(8, 8, 8, 8);

            add(new JLabel("Please make a booking"), gbc);
            add(new JLabel("This is where you'd collect all the booking details"), gbc);

            JButton save = new JButton("Save");
            JButton cancel = new JButton("Cancel");

            save.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        // Create an instance of Booking
                        Booking booking = getPatientRepository().createBooking("name", "phone number", "address", "description", LocalDate.now());
                        // Dismiss the view
                        fireDidDismissPane();
                    } catch (IOException ex) {
                        ex.printStackTrace();
                        JOptionPane.showMessageDialog(BookingPane.this, "Failed to create booking", "Error", JOptionPane.ERROR_MESSAGE);
                    }
                }
            });
            cancel.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    fireDidDismissPane();
                }
            });

            JPanel buttonPane = new JPanel(new GridLayout(1, 2));
            buttonPane.add(cancel);
            buttonPane.add(save);

            add(buttonPane, gbc);
        }

        public PatientRepository getPatientRepository() {
            return patientRepository;
        }

    }

    public class PatientPane extends AbstractDismissablePane {

        private PatientRepository patientRepository;

        public PatientPane(PatientRepository patientRepository) {
            this.patientRepository = patientRepository;
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.insets = new Insets(8, 8, 8, 8);

            add(new JLabel("Patient Record"), gbc);
            add(new JLabel("All your record belong to us"), gbc);

            JButton okay = new JButton("Okay");
            okay.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    fireDidDismissPane();
                }
            });

            add(okay, gbc);
        }

        public PatientRepository getPatientRepository() {
            return patientRepository;
        }

    }

    public interface Booking {
        public String getName();
        public String getPhoneNumber();
        public String getAddress();
        public String getDescription();
        public LocalDate getDateOfBirth();
    }

    public interface PatientRepository {
        public Booking createBooking(String name, String phoneNumber, String address, String description, LocalDate dob) throws IOException;
    }

    public class DefaultBooking implements Booking {

        private String name;
        private String phoneNumber;
        private String address;
        private String description;
        private LocalDate dateOfBirth;

        public DefaultBooking(String name, String phoneNumber, String address, String description, LocalDate dateOfBirth) {
            this.name = name;
            this.phoneNumber = phoneNumber;
            this.address = address;
            this.description = description;
            this.dateOfBirth = dateOfBirth;
        }

        public String getName() {
            return name;
        }

        public String getPhoneNumber() {
            return phoneNumber;
        }

        public String getAddress() {
            return address;
        }

        public String getDescription() {
            return description;
        }

        public LocalDate getDateOfBirth() {
            return dateOfBirth;
        }

    }

    public class DefaultPatientRepository implements PatientRepository {

        private List<Booking> bookings;

        public DefaultPatientRepository() throws IOException {
            bookings = new ArrayList<>(32);
            File sourceFile = new File("Clinic.txt");
            if (sourceFile.exists()) {
                try (BufferedReader br = new BufferedReader(new FileReader(sourceFile))) {
                    String line = null;
                    while ((line = br.readLine()) != null) {
                        String parts[] = line.split(";");

                        String name = parts[0];
                        String phoneNumber = parts[1];
                        String address = parts[2];
                        String description = parts[3];
                        String dob = parts[4];

                        LocalDate dateOfBirth = LocalDate.parse(dob, DateTimeFormatter.ISO_LOCAL_DATE);

                        Booking booking = new DefaultBooking(name, phoneNumber, address, description, dateOfBirth);
                        bookings.add(booking);
                    }
                }

                System.out.println("!! Loaded " + bookings.size() + " bookings");
            }
        }

        @Override
        public Booking createBooking(String name, String phoneNumber, String address, String description, LocalDate dob) throws IOException {
            // Rolling your own file format is just a complete pain in the ... code
            // To my mind, I'd explore XML, JSON and possibly even CSV if you're
            // not ready for a SQL based database solution, but I'm old and I'm lazy :P

            try (BufferedWriter bw = new BufferedWriter(new FileWriter(new File("Clinic.txt"), true))) {
                StringJoiner joiner = new StringJoiner(";");
                joiner.add(name);
                joiner.add(phoneNumber);
                joiner.add(address);
                joiner.add(description);
                joiner.add(DateTimeFormatter.ISO_LOCAL_DATE.format(dob));

                bw.write(joiner.toString());
                bw.newLine();
            }

            return new DefaultBooking(name, phoneNumber, address, description, dob);
        }

    }
}

I bet you're now sorry you even asked ;)

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366