Deleting data from a txt file in GUI - java

I am creating my first GUI its a phonebook where users can add, show all, and delete contacts stored in a txt file. My problem here is I'm already able to write the datas to the txt file but I dont know to how delete a contact. Sorry guys newbee here.
This is how I put the data in a txt file and read it back.
private void ADD_ActionPerformed(java.awt.event.ActionEvent evt) {
inputs ++;
String[] name;
String[] number;
String[] email;
name = new String[inputs];
number = new String[inputs];
email = new String[inputs];
//arrays the inputs
for (int i = 0; i < inputs; i++) {
name [i] = name_field.getText();
number[i] = number_field.getText();
email [i] = email_field.getText();
}
name_field.setText("");
number_field.setText("");
email_field.setText("");
try (PrintWriter write = new PrintWriter(new BufferedWriter(new FileWriter("database.txt", true)))){
for (int i = 0; i < 1; i++) {
write.write("Name: "+name[i] + "\nNumber: " + number[i] + "\nEmail: " + email[i] +"\n\n");
}
} catch (IOException e) {
System.err.println("ERROR");
}
}
private void SHOW_ActionPerformed(java.awt.event.ActionEvent evt) {
try {
File f = new File("database.txt");
Scanner sc = new Scanner(f);
while (sc.hasNextLine()) {
String data = sc.nextLine();
contact_area.append("\n " + data);
}
} catch (IOException e) {
System.out.println("ERROR");
}
}
private void DELETE_ActionPerformed(java.awt.event.ActionEvent evt) {
// :( i dunno how to start
}

Unless you want to write code to search through the text file and delete that line, the easiest way to do it would be to read the entire .txt file, and add each contact to an ArrayList so that the user can add, edit, and delete contacts as they choose.
Easiest way to do that would be to make a class called "Contact" which contains a name, number, and email in each instance. Then you can manage each contact individually in the ArrayList. Here is what it would look like:
package contactbook;
public class Contact {
private String name, number, email;
public Contact(String name, String number, String email){
this.name = name;
this.number = number;
this.email = email;
}
//put setters and getters here
}
Then, when you start your program create an ArrayList like so:
ArrayList<Contact> ListOfContacts = new ArrayList<>();
//Read the text file here and create a new contact for each one read
//Display all the existing contacts on the GUI
After that, your ActionListener for the button that adds a contact would look like this:
ActionListener forAddButton = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
name = name_field.getText();
number = number_field.getText();
email = email_field.getText();
Contact newContact = new Contact(name, number, email);
ListOfContacts.add(newContact);
}
}
Display the contacts using a JTable and a delete button to delete the selected contact from the corresponding ArrayList element. You would do this by calling JTable.getSelectedRow() on your table model to get the correct contact in your ArrayList:
ActionListener forDeleteButton = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
ListOfContacts.remove(myTable.getSelectedRow());
}
};
Then add a "save" button that overwrites the text file with the ArrayList ListOfContacts. Hope this helps.

Related

Objects in the array list are also similar after being loaded. Why?

My program is a simple chatroom. the values ​​written from the user by the text field in the registration section and creates an account. I have a class called "Account" that takes the same values ​​in the input and it contains the same fields. All accounts need to be saved and loaded for later implementation.
I used the code below (this is part of the program code) but there is a problem. I printed the values ​​after loading and found that it was reporting null values. Then after adding a new account to the array list all the values ​​in the list were changed to the added value. For example, I create and save an account with name "a" and email "a", then run the program again.
Adding the account with name and email "B" here prints two accounts B. what is the problem?
String email= t4.getText();
String password=t5.getText();
String name=t1.getText();
String family=t2.getText();
String phoneNumber=t3.getText();
try {
FileInputStream f = new FileInputStream("accounts.txt");
ObjectInputStream obj = new ObjectInputStream(f);
int size=obj.readInt();
for (int i = 0; i <size ; i++) {
accounts.add((Account)obj.readObject());
}
} catch (Exception e){
e.printStackTrace();
}
for (int i = 0; i <accounts.size() ; i++) {
System.out.println(accounts.get(i).name+" "+accounts.get(i).email);
}
Account account = new Account(name,family,phoneNumber,email,password);
accounts.add(account);
try{
FileOutputStream f=new FileOutputStream("accounts.txt",false);
ObjectOutputStream obj=new ObjectOutputStream(f);
obj.writeInt(accounts.size());
for (Account a:accounts) {
obj.writeObject(a);
}
} catch (Exception e){
e.printStackTrace();
}
for (int i = 0; i <accounts.size() ; i++) {
System.out.println(accounts.get(i).name+" "+accounts.get(i).email);
}
//class account
class Account implements Serializable {
static String name, family, phoneNumber, email, password;
static ArrayList<Post> posts = new ArrayList();
static ArrayList<Account> following = new ArrayList();
static ArrayList<Account> follower = new ArrayList();
Account(String n, String f, String pn, String e, String ps) {
name = n;
family = f;
phoneNumber = pn;
email = e;
password = ps;
}
void follow(Account user) {
following.add(user);
user.follower.add(this);
}
void post(String data) {
Post post = new Post(data, new Date(), this);
posts.add(post);
for (Account account : follower) {
account.posts.add(post);
}
}
}
All the members of the Account class are static, meaning that they belong to the class instead of a specific instance. Make them non-static and you should be good to go.

Checking if user exists in text file when registering

When making a registration class for registration and login system, it successfully adds the user into the text file. What I am asking is how I can make the program check if user's login ID already exists in text file.
Contents of text file:
User{nickname= Barry, loginID= baz15, password= dan}
When entering the same details for registering, it adds this again. How can I make it not add this again to the file and instead displays a JOptionPane?
I have an array list that references User class to check if the user exists in the text file. This is my code so far:
public class RegistrationJFrame extends javax.swing.JFrame {
ArrayList<User> users = new ArrayList<>();
public RegistrationJFrame() {
initComponents();
lblErrorMessage.setVisible(false);
}
private void btnRegisterActionPerformed(java.awt.event.ActionEvent evt) {
String nickname = edtNickname.getText();
String loginID = edtLoginID.getText();
String password = String.valueOf(edtPassword.getPassword());
String confirmPassword = String.valueOf(edtReenterPassword.getPassword());
if (!password.equals(confirmPassword)) {
lblErrorMessage.setText("Passwords do not match");
}
if (nickname.equals("") || loginID.equals("") || password.equals("")) {
lblErrorMessage.setText("You must fill in the text fields");
}
for (int i = 0; i < users.size(); i++) {
if (users.get(i).getLoginID().equals(loginID)) {
JOptionPane.showMessageDialog(null, "User exists in file");
} else {
JOptionPane.showMessageDialog(null, "User does not exist");
}
}
try {
User user = new User(nickname, loginID, password);
users.add(user);
File filename = new File("userinfo.txt");
if (!filename.exists()) {
filename.createNewFile();
}
FileWriter fw = new FileWriter(filename, true);
BufferedWriter bw = new BufferedWriter(fw);
bw.write(user.toString());
bw.newLine();
bw.close();
} catch (Exception e) {
System.out.println("");
}
}
}
A simple fix would be to rewrite your users to the file instead of appending the new user to your file. This means you would just have to loop through the list and rewrite all the users to file each time a new user is created. You could create a saveToFile() method like so and call it
private void saveToFile()
{
try{
File filename = new File("userinfo.txt");
if (!filename.exists()) {
filename.createNewFile();
}
FileWriter fw = new FileWriter(filename, false); //false so you don't append and overwrite
BufferedWriter bw = new BufferedWriter(fw);
//now loop your arraylist of users to resave them to your file
for(User currUser : users)
{
bw.write(currUser.toString());
bw.newLine();
}
bw.close();
}catch (Exception e)
{
e.printStackTrace();
}
}
Next you have to determine when it's ok to add the user and save it. Try using a boolean in your btnRegisterActionPerformed method like this
private void btnRegisterActionPerformed(java.awt.event.ActionEvent evt) {
String nickname = edtNickname.getText();
String loginID = edtLoginID.getText();
String password = String.valueOf(edtPassword.getPassword());
String confirmPassword = String.valueOf(edtReenterPassword.getPassword());
if (!password.equals(confirmPassword)) {
lblErrorMessage.setText("Passwords do not match");
}
if (nickname.equals("") || loginID.equals("") || password.equals("")) {
lblErrorMessage.setText("You must fill in the text fields");
}
boolean addUser = true;
for (int i = 0; i < users.size(); i++) {
if (users.get(i).getLoginID().equals(loginID)) {
JOptionPane.showMessageDialog(null, "User exists in file");
addUser = false;
break;//no need to keep checking so break out of the for loop
} else {
JOptionPane.showMessageDialog(null, "User does not exist");
}
}
if(addUser)
{
User user = new User(nickname, loginID, password);
users.add(user);
//now save the contents of the list to the file
saveToFile();
}
}
You are currently always adding the user to your file which is incorrect. We use the boolean to determine if the user does not exist, and only when the user cannot be found do we add the user and save to the file.
If I understood you correct I would do it with a separate method:
public class RegistrationJFrame extends javax.swing.JFrame {
ArrayList<User> users = new ArrayList<>();
public RegistrationJFrame() {
initComponents();
lblErrorMessage.setVisible(false);
}
private void btnRegisterActionPerformed(java.awt.event.ActionEvent evt) {
String nickname = edtNickname.getText();
String loginID = edtLoginID.getText();
String password = String.valueOf(edtPassword.getPassword());
String confirmPassword = String.valueOf(edtReenterPassword.getPassword());
if (!password.equals(confirmPassword)) {
lblErrorMessage.setText("Passwords do not match");
}
if (nickname.equals("") || loginID.equals("") || password.equals("")) {
lblErrorMessage.setText("You must fill in the text fields");
}
for (int i = 0; i < users.size(); i++) {
if (users.get(i).getLoginID().equals(loginID)) {
JOptionPane.showMessageDialog(null, "User exists in file");
} else {
JOptionPane.showMessageDialog(null, "User does not exist");
User user = new User(nickname, loginID, password);
users.add(user);
saveUser(user);
}
}
}
private void saveUser(User user) {
try {
File filename = new File("userinfo.txt");
if (!filename.exists()) {
filename.createNewFile();
}
FileWriter fw = new FileWriter(filename, true);
BufferedWriter bw = new BufferedWriter(fw);
bw.write(user.toString());
bw.newLine();
bw.close();
} catch (Exception e) {
System.out.println("");
}
}
}
For your file you maybe go better with a json file. Might be easier if you want to add further information to the user.

Storing Objects of an array into CSV file and reading them with specific arguments for GUI

As a part of my assignment I had to store objects of an array in a flat-file and retrieve them when certain criteria was met. I can save the objects fine but when retrieving them I have an issue with getting more than one value, I understand what is going wrong but I am struggling to find a solution. Here is the concept of whats happening.
Button no 10,A (R1S10 in the code)is my testing button, When I click it it creates an event that I will show below.
Click event for button 10A -
private void R1S10ActionPerformed(java.awt.event.ActionEvent evt) {
seats.add(seat1);
if (R1S10.getBackground().equals(Color.red) &&(IsSeatBooked().equals("true"))){
Component frame = null;
JOptionPane.showMessageDialog(frame, "Seat UnBooked");
seat1.setBooked("false");
seat1.setName("");
R1S10.setBackground(Color.yellow);
try {
reader();
writer();
//String booked = "true";
//Pass String booked into csv file
} catch (IOException ex) {
Logger.getLogger(SeatingPlan.class.getName()).log(Level.SEVERE, null, ex);
}
}
else{
Component frame = null;
String name = JOptionPane.showInputDialog(frame, "Please enter name of Customer booking");
if (name.isEmpty()) {
JOptionPane.showMessageDialog(frame, "No value entered");
} else if (name != null) {
seat1.setName(name);
seat1.setBooked("true");
R1S10.setBackground(Color.red);
JOptionPane.showMessageDialog(frame, "Your Booking has been placed");
try {
writer();
reader();
//String booked = "true";
//Pass String booked into csv file
} catch (IOException ex) {
Logger.getLogger(SeatingPlan.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
Followed by the screen below -
Outcome -
And when the button is pressed again -
I am using three methods in this SeatingPlan.java - writer(),reader() and IsSeatBooked().
SeatingPlan -
public class SeatingPlan extends javax.swing.JFrame {
/**
* Creates new form SeatingPlan
*/
String seatNo, name, bookedSeat;
FileWriter fileWriter = null;
List<Seat> seats = new ArrayList<Seat>();
//Seat Object Declaration
Seat seat1 = new Seat("R1S10","","false");
Seat seat2 = new Seat("R1S9", "", "false");
String fileName = "seat.csv";
writer -
public void writer() throws IOException {
//Delimiter used in CSV file
final String NEW_LINE_SEPARATOR = "\n", COMMA_DELIMITER = ",";
//CSV file header
final String FILE_HEADER = "seatID,name,booked";
//fileName = System.getProperty("user.home") + "/seat.csv";
try {
fileWriter = new FileWriter(fileName);
//Write the CSV file header
fileWriter.append(FILE_HEADER.toString());
//Add a new line separator after the header
fileWriter.append(NEW_LINE_SEPARATOR);
//Write a new student object list to the CSV file
for (Seat seat : seats) {
fileWriter.append(String.valueOf(seat.getSeatID()));
fileWriter.append(COMMA_DELIMITER);
fileWriter.append(seat.getName());
fileWriter.append(COMMA_DELIMITER);
fileWriter.append(seat.isBooked());
fileWriter.append(NEW_LINE_SEPARATOR);
}
System.out.println("CSV file was created successfully !!!");
} catch (Exception e) {
System.out.println("Error in CsvFileWriter !!!");
e.printStackTrace();
} finally {
fileWriter.flush();
fileWriter.close();
}
}
reader -
public void reader() {
//Delimiter used in CSV file
final String COMMA_DELIMITER = ",";
//Student attributes index
final int SEAT_ID_IDX = 0;
final int SEAT_NAME_IDX = 1;
final int SEAT_BOOKED = 2;
//private static final int STUDENT_LNAME_IDX = 2;
BufferedReader fileReader = null;
try {
//Create a new list of student to be filled by CSV file data
List<Seat> seats = new ArrayList<>();
String line = "";
//Create the file reader
fileReader = new BufferedReader(new FileReader(fileName));
//Read the CSV file header to skip it
fileReader.readLine();
//Read the file line by line starting from the second line
while ((line = fileReader.readLine()) != null) {
//Get all tokens available in line
String[] tokens = line.split(COMMA_DELIMITER);
if (tokens.length > 0) {
//Create a new seat object and fill his data
Seat seat = new Seat(tokens[SEAT_ID_IDX],
tokens[SEAT_NAME_IDX], tokens[SEAT_BOOKED]);
seats.add(seat);
seatNo = tokens[SEAT_ID_IDX];
//System.out.println("Seat Number: " + seatNo);
bookedSeat = tokens[SEAT_BOOKED];
}
}
//Print the new student list
for (Seat seat : seats) {
System.out.println(seat.toString());
}
} catch (Exception e) {
System.out.println("Error in CsvFileReader !!!");
e.printStackTrace();
} finally {
try {
fileReader.close();
} catch (IOException e) {
System.out.println("Error while closing fileReader !!!");
e.printStackTrace();
}
}
}//end reader
SeatingPlan - This if where I have tried to have the arguments controlling the outcome but IsBooked is colliding when multiple seats are selected.
public SeatingPlan() throws IOException {
setVisible(true);
initComponents();
//reader();
ColourSectionGold();
ColourSectionBronze();
reader();
if(R1S10.getBackground().equals(Color.yellow) && (IsSeatBooked().equals("true"))){ R1S10.setBackground(Color.red);}
//if(R1S9.getBackground().equals(Color.yellow) && (IsSeatBooked().equals("true2"))){ R1S9.setBackground(Color.red);}
}
IsSeatBooked -
public String IsSeatBooked(){
return bookedSeat;
}//end IsSeatBooked
Im using the method above as my argument to see whether a seat is booked or not, but when a new seat is click it sets the whole value of 'bookedSeat' - which leaves the system not working correctly. I understand the code is not very efficient but is there any temporary fix for this problem, if I have explained it correctly.
Also I will include my class for Seat -
public class Seat {
private String seatID;
private String booked;
private String name;
private int price;
public Seat(String seatID,String name,String booked){
this.seatID = seatID;
this.booked = "";
this.name = name;
this.price = price;
}
public String getSeatID() {
return seatID;
}
public void setSeatID(String seatID) {
this.seatID = seatID;
}
public String isBooked() {
return booked;
}
public void setBooked(String booked) {
this.booked = booked;
}
public String getStatus(){
return booked;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setPrice() {
this.price = price;
}}//end class Seat
And a look at the CSV file that is created -
I wish to be able to click more than one button and save its state, Button 10 works fine at the moment, but as IsBooked only has one value at a time it clashes.
If you took the time to check this out, I appreciate it. Any constructive criticism is helpful and any ideas would be great!
Thanks,
Paddy.
Too much code to look at to see exactly what you are doing.
Instead of using your csv file, you could create a Properties file. The Propertiesfile will store the data in the form of:
key:data
So in your case the key would be the id: A1, A2... and the data would be the name of the person who booked the seat.
So the file would start out as empty. When you create the GUI you would create a loop that checks each id to see if an entry is found in the Properties field. If it is found then you display the seat as taken, otherwise it is empty.
Then whenever you want to book a seat you just use the setProperty(...) method.
The Properties class has load(...) and store(...) methods.
So the Properties class allows you to easily manage a flat file database with minimal effort.
Note, you would never have variable names like R1S10. That would requirement 100 different variables with if/else statements. Instead you would extend JButton and pass in the row and seat as parameters the button. Then in the ActionListener for the button you can access the row/seat information to built the ID used as the key for the properties file.
Edit:
Couldn't quite make the loop that checks if the ID is in the properties file.
If the property is null, the seath is empty.
import java.util.*;
public class Main
{
public static void main(String[] args)
{
Properties properties = new Properties();
properties.setProperty("A2", "Smith");
properties.setProperty("C3", "Jones");
String[] rows = { "A", "B", "C", "D" };
int seats = 4;
for (int row = 0; row < rows.length; row++)
{
for (int seat = 1; seat <= seats; seat++)
{
String key = rows[row] + seat;
String property = properties.getProperty( key );
System.out.println(key + " : " + property);
}
}
}
}

Get selected items from combo box

I have a combo box that contains data from an array. I want to be able to get the the selected name in the JComboBox and print it to a text file. The problem is that the name wont write to the text file.
Array code:
public class readfiles {
String [] names = new String[15];
int i = 0;
private Scanner readNames;
//Opens the file
public void openFile() {
try {
readNames = new Scanner(new File("ChildName.txt"));
} catch (Exception e) {
System.out.println("Could not locate the data file!");
}
}
//Reads the names in the file
public void readFile() {
while(readNames.hasNext()) {
names[i] = readNames.next();
System.out.println(names[i]);
i++;
}
}
//Closes the file
public void closeFile() {
readNames.close();
}
}
ComboBox code:
//JComboBox for selecting child
JLabel selectChildName = new JLabel("Please Select Your Child:");
sPanel.add(selectChildName);
readfiles readNames = new readfiles();
readNames.openFile();
readNames.readFile();
readNames.closeFile();
JComboBox<String> selectChild = new JComboBox<String>(readNames.names);
sPanel.add(selectChild);
And finally this is what I am doing to write the selected name to a text file.
bw.write(selectChild.getSelectedIndex());
UPDATE
Used:
bw.write(selectChild.getSelectedItem().toString());
You need JComboBox#getSelectedItem() instead of JComboBox#getSelectedIndex(). As it is a String, it should be printed within the file.
Returns the current selected item.
Do not forget to also use a ItemListener with your JComboBox

Need assistance with list selection listener

I'm trying to fill my list selection listener method with code, but I don't know how to approach it. Essentially, I would like for the method to fill multiple text fields when an item is selected from the JList.
My JList looks like this:
private JList <String> contactList;
private DefaultListModel<String> model;
//Textfields
comboBookType = new JComboBox(BookType.values());
nameText = new JTextField("", 17);
authorText = new JTextField("", 17);
genreText = new JTextField ("", 17);
comboCategory = new JComboBox (readCategory());
//initialize defaultlistmodel and jlist
model = new DefaultListModel <String>();
bookList = new JList (model);
bookList.setVisibleRowCount(10);
bookList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
bookList.setFixedCellHeight (20);
bookList.setFixedCellWidth (130);
bookList.setBorder (BorderFactory.createLineBorder(Color.BLACK,1));
JPanel left = new JPanel(new BorderLayout());
left.add (new JScrollPane(bookList), BorderLayout.NORTH);
bookList.addListSelectionListener (new ListSelection());
//populating Jlist
class openFileListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
book.getBooks();
for (String name : addressBook.getBooks())
{
model.addElement(name);
}
}
}
//the getBooks() method in my Library class
public ArrayList<String> getBooks ()
{
File file;
Scanner input;
BookType type;
ArrayList<String> books;
ArrayList<String> names = new ArrayList<String>();
try
{
file = new File ("Books.txt");
input = new Scanner (file);
while (input.hasNext())
{
String line = input.nextLine ( );
String [] book = line.split(",");
type = BookType.valueOf(info[0]);
String name = book[1];
b = new Book (type, book[1], book[2], book[3], book[4], info[5]);
list.add (b);
information.add (name);
numOfBooks++;
}
input.close ( );
}
catch (FileNotFoundException e)
{
JOptionPane.showMessageDialog (null, "File not found");
}
return information;
}
Here's what I have so far in my list selection listener:
private class ListSelection implements ListSelectionListener
{
public void valueChanged (ListSelectionEvent e)
{
book.getInfo ( );
int index = bookList.getSelectedIndex ( );
}
//getInfo() method in Library class
public ArrayList<Book> getInfo ()
{
File file;
Scanner input;
BookType type;
ArrayList<String> book;
try
{
file = new File ("Book.txt");
input = new Scanner (file);
while (input.hasNext())
{
String line = input.nextLine ( );
String [] info = line.split(",");
type = BookType.valueOf(info[0]);
String name = info[1];
Book b = new Contact (type, info[1], info[2], info[3], info[4],info[5]);
list.add (b);
}
input.close ( );
}
catch (FileNotFoundException e)
{
JOptionPane.showMessageDialog (null, "File not found");
}
return list;
It's not much, but I have no ideas on where to go from here. I know I have to utilize the index that I got from from getSelectedIndex but I don't know how, please help, thank you.
I know I have to utilize the index that I got from from getSelectedIndex but I don't know how
You would use the index to get the selection item from the ListModel:
String book = model.getElementAt(index);
Or the easier approach is to get the element from the JList using the getSelectedValue() method:
private class ListSelection implements ListSelectionListener
{
public void valueChanged (ListSelectionEvent e)
{
if (e.getValueIsAdjusting()) return;
//book.getInfo ( );
//int index = bookList.getSelectedIndex ( );
String book = bookList.getSelectedValue();
}
}
Now the problem you have is finding the information about the book. You are creating Book objects and adding them to an ArrayList. So now you need to create a loop to look at all entries in the ArrayList. Something like:
ArrayList<Book> bookInfo = getInfo();
for (Book book: bookInfo)
{
if (book.equals(book.getTitle())
{
authorTextField.setText( book.getAuthor());
// ... for the rest of the text fields
return;
}
}
Note a better design would be to read the book info into your class when the class is constructed. This way to don't read the data from the text file every time a selection is made in the JList.

Categories

Resources