Senin, 13 Juli 2026

JAVA MVC 4 CRUD CSV File

java swing gui CRUD jtable sample model view controller book title and author database in one package and save as csv file

Gemini said

Here is a complete, lightweight Java Swing CRUD application implementing the Model-View-Controller (MVC) design pattern.

This implementation handles a database of books (Title and Author) and persists the data directly to a CSV file (books.csv). For simplicity and to meet your requirement, all classes are designed to sit within the same package.

Project Structure

Since everything is in one package (e.g., com.bookapp), you will create four files:

  1. Book.java (The Data Model)

  2. BookRepository.java (The CSV Database Handler)

  3. BookView.java (The Swing GUI View)

  4. BookController.java (The Controller / Main Entry)

1. The Model (Book.java)

This represents a single book entity.

Java
package com.bookapp;

public class Book {
    private String title;
    private String author;

    public Book(String title, String author) {
        this.title = title;
        this.author = author;
    }

    public String getTitle() { return title; }
    public void setTitle(String title) { this.title = title; }

    public String getAuthor() { return author; }
    public void setAuthor(String author) { this.author = author; }
}

2. The File Handler (BookRepository.java)

This class manages reading from and writing to the CSV file.

Java
package com.bookapp;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class BookRepository {
    private final String csvFile = "books.csv";

    // Load books from CSV
    public List<Book> loadBooks() {
        List<Book> books = new ArrayList<>();
        File file = new File(csvFile);
        
        if (!file.exists()) return books; // Return empty list if file doesn't exist yet

        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
            String line;
            while ((line = br.readLine()) != null) {
                String[] data = line.split(",");
                if (data.length >= 2) {
                    // Escape commas if necessary, but keeping it simple here
                    books.add(new Book(data[0].trim(), data[1].trim()));
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return books;
    }

    // Save books to CSV
    public void saveBooks(List<Book> books) {
        try (PrintWriter pw = new PrintWriter(new FileWriter(csvFile))) {
            for (Book book : books) {
                pw.println(book.getTitle() + "," + book.getAuthor());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3. The View (BookView.java)

This handles the GUI layout. It exposes UI components and data to the controller via methods so that it doesn't handle business logic itself.

Java
package com.bookapp;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.ActionListener;

public class BookView extends JFrame {
    private JTextField txtTitle = new JTextField(15);
    private JTextField txtAuthor = new JTextField(15);
    private JButton btnCreate = new JButton("Add");
    private JButton btnUpdate = new JButton("Update");
    private JButton btnDelete = new JButton("Delete");
    private JButton btnClear = new JButton("Clear");
    
    private JTable table = new JTable();
    private DefaultTableModel tableModel = new DefaultTableModel(new Object[]{"Title", "Author"}, 0);

    public BookView() {
        setTitle("Book CRUD Manager (MVC)");
        setSize(600, 400);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        table.setModel(tableModel);
        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

        // Input Panel
        JPanel inputPanel = new JPanel(new GridLayout(2, 2, 5, 5));
        inputPanel.add(new JLabel("Title:"));
        inputPanel.add(txtTitle);
        inputPanel.add(new JLabel("Author:"));
        inputPanel.add(txtAuthor);

        // Buttons Panel
        JPanel buttonPanel = new JPanel();
        buttonPanel.add(btnCreate);
        buttonPanel.add(btnUpdate);
        buttonPanel.add(btnDelete);
        buttonPanel.add(btnClear);

        // Top Area combining Inputs and Buttons
        JPanel topPanel = new JPanel(new BorderLayout());
        topPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        topPanel.add(inputPanel, BorderLayout.CENTER);
        topPanel.add(buttonPanel, BorderLayout.SOUTH);

        // Main Layout
        setLayout(new BorderLayout());
        add(topPanel, BorderLayout.NORTH);
        add(new JScrollPane(table), BorderLayout.CENTER);
    }

    // Getters and Helper Methods for Controller
    public String getBookTitle() { return txtTitle.getText().trim(); }
    public String getBookAuthor() { return txtAuthor.getText().trim(); }
    
    public void setInputs(String title, String author) {
        txtTitle.setText(title);
        txtAuthor.setText(author);
    }

    public int getSelectedRow() { return table.getSelectedRow(); }
    public DefaultTableModel getTableModel() { return tableModel; }
    public JTable getTable() { return table; }

    public void clearInputs() {
        txtTitle.setText("");
        txtAuthor.setText("");
        table.clearSelection();
    }

    // Listeners registrations
    public void addCreateListener(ActionListener l) { btnCreate.addActionListener(l); }
    public void addUpdateListener(ActionListener l) { btnUpdate.addActionListener(l); }
    public void addDeleteListener(ActionListener l) { btnDelete.addActionListener(l); }
    public void addClearListener(ActionListener l) { btnClear.addActionListener(l); }
}

4. The Controller & Main Application (BookController.java)

The brains of the operation. It syncs the BookRepository (Model/Data) with the BookView (UI) and handles all user interactions.

Java
package com.bookapp;

import javax.swing.JOptionPane;
import javax.swing.table.DefaultTableModel;
import java.util.List;

public class BookController {
    private BookView view;
    private BookRepository repository;
    private List<Book> bookList; // Runtime memory cache of our data

    public BookController(BookView view, BookRepository repository) {
        this.view = view;
        this.repository = repository;
        this.bookList = repository.loadBooks();

        // Populate View table initially
        updateTable();

        // Wire up listeners
        this.view.addCreateListener(e -> handleCreate());
        this.view.addUpdateListener(e -> handleUpdate());
        this.view.addDeleteListener(e -> handleDelete());
        this.view.addClearListener(e -> view.clearInputs());

        // Table row selection syncs back to input fields
        this.view.getTable().getSelectionModel().addListSelectionListener(e -> {
            int selectedRow = view.getSelectedRow();
            if (selectedRow != -1) {
                String title = view.getTableModel().getValueAt(selectedRow, 0).toString();
                String author = view.getTableModel().getValueAt(selectedRow, 1).toString();
                view.setInputs(title, author);
            }
        });
    }

    private void updateTable() {
        DefaultTableModel model = view.getTableModel();
        model.setRowCount(0); // Clear table view
        for (Book book : bookList) {
            model.addRow(new Object[]{book.getTitle(), book.getAuthor()});
        }
    }

    private void handleCreate() {
        String title = view.getBookTitle();
        String author = view.getBookAuthor();

        if (title.isEmpty() || author.isEmpty()) {
            JOptionPane.showMessageDialog(view, "Fields cannot be empty!");
            return;
        }

        bookList.add(new Book(title, author));
        repository.saveBooks(bookList);
        updateTable();
        view.clearInputs();
    }

    private void handleUpdate() {
        int selectedRow = view.getSelectedRow();
        if (selectedRow == -1) {
            JOptionPane.showMessageDialog(view, "Select a book to update.");
            return;
        }

        String title = view.getBookTitle();
        String author = view.getBookAuthor();

        if (title.isEmpty() || author.isEmpty()) {
            JOptionPane.showMessageDialog(view, "Fields cannot be empty!");
            return;
        }

        // Update runtime list and save to CSV
        Book book = bookList.get(selectedRow);
        book.setTitle(title);
        book.setAuthor(author);
        
        repository.saveBooks(bookList);
        updateTable();
        view.clearInputs();
    }

    private void handleDelete() {
        int selectedRow = view.getSelectedRow();
        if (selectedRow == -1) {
            JOptionPane.showMessageDialog(view, "Select a book to delete.");
            return;
        }

        bookList.remove(selectedRow);
        repository.saveBooks(bookList);
        updateTable();
        view.clearInputs();
    }

    // MAIN ENTRY POINT
    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(() -> {
            BookView view = new BookView();
            BookRepository repository = new BookRepository();
            new BookController(view, repository);
            view.setVisible(true);
        });
    }
}

How to Run it:

  1. Put all 4 files into a directory folder named com/bookapp (matching the package structure).

Tidak ada komentar: