aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVidhu Kant Sharma <vidhukant@vidhukant.com>2024-11-16 02:16:16 +0530
committerVidhu Kant Sharma <vidhukant@vidhukant.com>2024-11-16 02:16:16 +0530
commitda6b366397aa15e2686840c1d9ffa5dae5d49d2a (patch)
treea53bc42092a564bfbf66a67b70e3aa9cb8689798 /src
First CommitHEADmaster
Diffstat (limited to 'src')
-rw-r--r--src/META-INF/MANIFEST.MF3
-rw-r--r--src/Main.java23
-rw-r--r--src/Server/JSONMessage.java19
-rw-r--r--src/Server/SocketIOMessage.java17
-rw-r--r--src/Server/SocketServer.java53
-rw-r--r--src/Store/Book.java214
-rw-r--r--src/Store/ConnectionHandler.java28
-rw-r--r--src/Store/User.java120
-rw-r--r--src/UI/Components/BookListItem.java48
-rw-r--r--src/UI/Components/BooksList.java47
-rw-r--r--src/UI/Components/InputBox.java39
-rw-r--r--src/UI/Components/MenuBar.java29
-rw-r--r--src/UI/MainWindow.java121
-rw-r--r--src/UI/NewBookPopupWindow.java58
-rw-r--r--src/UI/SettingsPopupWindow.java36
15 files changed, 855 insertions, 0 deletions
diff --git a/src/META-INF/MANIFEST.MF b/src/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..37197ef
--- /dev/null
+++ b/src/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: Main
+
diff --git a/src/Main.java b/src/Main.java
new file mode 100644
index 0000000..e3a030a
--- /dev/null
+++ b/src/Main.java
@@ -0,0 +1,23 @@
+import Store.ConnectionHandler;
+import UI.MainWindow;
+
+import javax.swing.*;
+import java.awt.*;
+
+public class Main {
+ public static void main(String[] args) {
+ try {
+ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+ }
+ catch (UnsupportedLookAndFeelException | ClassNotFoundException | InstantiationException |
+ IllegalAccessException _) {
+ }
+
+ new ConnectionHandler("jdbc:sqlite:LibMan.db").connect();
+
+ EventQueue.invokeLater(() -> {
+ MainWindow w = new UI.MainWindow();
+ w.setVisible(true);
+ });
+ }
+} \ No newline at end of file
diff --git a/src/Server/JSONMessage.java b/src/Server/JSONMessage.java
new file mode 100644
index 0000000..c3f9712
--- /dev/null
+++ b/src/Server/JSONMessage.java
@@ -0,0 +1,19 @@
+package Server;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.util.Map;
+
+public class JSONMessage {
+ private Map data;
+
+ public JSONMessage(String json) throws JsonProcessingException {
+ ObjectMapper mapper = new ObjectMapper();
+ data = mapper.readValue(json, Map.class);
+ }
+
+ public Map getData() {
+ return data;
+ }
+}
diff --git a/src/Server/SocketIOMessage.java b/src/Server/SocketIOMessage.java
new file mode 100644
index 0000000..8e6167a
--- /dev/null
+++ b/src/Server/SocketIOMessage.java
@@ -0,0 +1,17 @@
+package Server;
+
+public class SocketIOMessage {
+ private String message;
+
+ public SocketIOMessage(String message) {
+ this.message = message;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+}
diff --git a/src/Server/SocketServer.java b/src/Server/SocketServer.java
new file mode 100644
index 0000000..f3a8f2e
--- /dev/null
+++ b/src/Server/SocketServer.java
@@ -0,0 +1,53 @@
+package Server;
+
+import Store.Book;
+import Store.User;
+import com.corundumstudio.socketio.SocketIOServer;
+import com.corundumstudio.socketio.listener.ConnectListener;
+import com.corundumstudio.socketio.listener.DisconnectListener;
+import com.corundumstudio.socketio.Configuration;
+
+public class SocketServer {
+ public static SocketIOServer server;
+
+ public SocketServer(Configuration config) {
+ server = new SocketIOServer(config);
+
+ server.addConnectListener(onConnected());
+ server.addDisconnectListener(onDisconnected());
+
+ server.addEventListener("login", JSONMessage.class, User.loginHandler());
+ server.addEventListener("signUp", JSONMessage.class, User.signUpHandler());
+
+ server.addEventListener("issue", JSONMessage.class, Book.issueHandler());
+ server.addEventListener("return", JSONMessage.class, Book.returnHandler());
+ server.addEventListener("getAllBooks", JSONMessage.class, Book.getListHandler(false));
+ server.addEventListener("getAvailableBooks", JSONMessage.class, Book.getListHandler(true));
+ }
+
+ private ConnectListener onConnected() {
+ return (client -> {
+ System.out.println("New connection!");
+ });
+ }
+
+ private DisconnectListener onDisconnected() {
+ return (client -> {
+ System.out.println("Disconnected!");
+ });
+ }
+
+ public void start() {
+ server.start();
+
+ Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
+ public void run() {
+ server.stop();
+ }
+ }, "Shutdown-thread"));
+ }
+
+ public void stop() {
+ server.stop();
+ }
+}
diff --git a/src/Store/Book.java b/src/Store/Book.java
new file mode 100644
index 0000000..4232d77
--- /dev/null
+++ b/src/Store/Book.java
@@ -0,0 +1,214 @@
+package Store;
+
+import Server.JSONMessage;
+import Server.SocketServer;
+import UI.MainWindow;
+import com.corundumstudio.socketio.listener.DataListener;
+
+import java.sql.*;
+import java.util.ArrayList;
+import java.util.Map;
+
+public class Book {
+ private int id;
+ private String title;
+ private String author;
+ private int issuedBy;
+ private String issuedByName = "";
+
+ public Book(int id) {
+ this.id = id;
+ }
+
+ public Book(String title, String author) {
+ this.title = title;
+ this.author = author;
+ this.issuedBy = 0; // 0 means available since IDs start with 1
+ }
+
+ public Book(int id, String title, String author, int issuedBy, String issuedByName) {
+ this.id = id;
+ this.title = title;
+ this.author = author;
+ this.issuedBy = issuedBy;
+ this.issuedByName = issuedByName;
+ }
+
+ public String getTitle() {
+ return this.title;
+ }
+
+ public String getAuthor() {
+ return this.author;
+ }
+
+ public int getIssuedBy() {
+ return this.issuedBy;
+ }
+
+ public int getId() {
+ return this.id;
+ }
+
+ public String getIssuedByName() {
+ return issuedByName;
+ }
+
+ public int bookIssuedBy() throws SQLException {
+ String sql = "SELECT issuedBy from Book where ID = " + this.id;
+ Statement statement = ConnectionHandler.connection.createStatement();
+
+ ResultSet response = statement.executeQuery(sql);
+ while (response.next()) {
+ return response.getInt("issuedBy");
+ }
+
+ return 0;
+ }
+
+ public boolean issue(int userId) throws SQLException {
+ if (bookIssuedBy() == 0) {
+ String sql = "UPDATE Book SET issuedBy = ? where ID = ?";
+ PreparedStatement statement = ConnectionHandler.connection.prepareStatement(sql);
+
+ statement.setInt(1, userId);
+ statement.setInt(2, this.id);
+
+ statement.executeUpdate();
+
+ ArrayList<Book> allBooks = Book.getAll(false);
+ UI.Components.BooksList.refreshBooks(allBooks);
+ if (MainWindow.serverStarted) {
+ SocketServer.server.getBroadcastOperations().sendEvent("booksUpdated", allBooks);
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean returnBook(int userId) throws SQLException {
+ if (bookIssuedBy() == userId) {
+ String sql = "UPDATE Book SET issuedBy = 0 where ID = ?";
+ PreparedStatement statement = ConnectionHandler.connection.prepareStatement(sql);
+
+ statement.setInt(1, this.id);
+
+ statement.executeUpdate();
+
+ ArrayList<Book> allBooks = Book.getAll(false);
+ UI.Components.BooksList.refreshBooks(allBooks);
+ if (MainWindow.serverStarted) {
+ SocketServer.server.getBroadcastOperations().sendEvent("booksUpdated", allBooks);
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ public void save() throws SQLException {
+ String sql = "INSERT INTO Book (title, author, issuedBy) VALUES (?, ?, ?)";
+
+ PreparedStatement statement = ConnectionHandler.connection.prepareStatement(sql);
+
+ statement.setString(1, title);
+ statement.setString(2, author);
+ statement.setInt(3, issuedBy);
+
+ statement.executeUpdate();
+
+ ArrayList<Book> allBooks = Book.getAll(false);
+ UI.Components.BooksList.refreshBooks(allBooks);
+ if (MainWindow.serverStarted) {
+ SocketServer.server.getBroadcastOperations().sendEvent("booksUpdated", allBooks);
+ }
+ }
+
+ public void delete() throws SQLException {
+ String sql = "DELETE FROM Book WHERE ID = ?";
+ PreparedStatement statement = ConnectionHandler.connection.prepareStatement(sql);
+
+ statement.setInt(1, this.id);
+
+ statement.executeUpdate();
+
+ ArrayList<Book> allBooks = Book.getAll(false);
+ UI.Components.BooksList.refreshBooks(allBooks);
+ if (MainWindow.serverStarted) {
+ SocketServer.server.getBroadcastOperations().sendEvent("booksUpdated", allBooks);
+ }
+ }
+
+ public static ArrayList<Book> getAll(boolean availableOnly) throws SQLException {
+ ArrayList<Book> books = new ArrayList<>();
+
+ String sql;
+ if (availableOnly) {
+ sql = "SELECT * FROM Book WHERE issuedBy = 0";
+ } else {
+ sql = "SELECT Book.ID, Book.title, Book.issuedBy, Book.author, " +
+ "User.userName FROM Book LEFT JOIN User ON User.ID = Book.issuedBy";
+ }
+ Statement statement = ConnectionHandler.connection.createStatement();
+
+ ResultSet response = statement.executeQuery(sql);
+ while (response.next()) {
+ books.add(new Book(response.getInt("ID"), response.getString("title"), response.getString("author"), response.getInt("issuedBy"), response.getString("userName")));
+ }
+
+ return books;
+ }
+
+ public static DataListener<JSONMessage> getListHandler(boolean availableOnly) {
+ return ((client, data, ackSender) -> {
+ ArrayList<Book> books = getAll(availableOnly);
+ client.sendEvent(availableOnly ? "availableBooksList" : "allBooksList", books);
+ });
+ }
+
+ public static DataListener<JSONMessage> issueHandler() {
+ return ((client, data, ackSender) -> {
+ Map d = data.getData();
+
+ int userId = (int) d.get("id");
+ Book b = new Book((int) d.get("bookId"));
+
+ if (b.issue(userId)) {
+ client.sendEvent("issued");
+ } else {
+ client.sendEvent("alreadyIssued");
+ }
+ });
+ }
+
+ public static DataListener<JSONMessage> returnHandler() {
+ return ((client, data, ackSender) -> {
+ Map d = data.getData();
+
+ int userId = (int) d.get("id");
+ Book b = new Book((int) d.get("bookId"));
+
+ if (b.returnBook(userId)) {
+ client.sendEvent("returned");
+ } else {
+ client.sendEvent("returnFailed");
+ }
+ });
+ }
+
+ public static void createTable() throws SQLException {
+ String sql = "CREATE TABLE IF NOT EXISTS Book (" +
+ "ID INTEGER NOT NULL PRIMARY KEY, " +
+ "title TEXT NOT NULL, " +
+ "author text NOT NULL, " +
+ "issuedBy INTEGER NOT NULL," +
+ "FOREIGN KEY(issuedBy) REFERENCES User(ID)" +
+ ");";
+
+ Statement statement = ConnectionHandler.connection.createStatement();
+ statement.execute(sql);
+ }
+}
diff --git a/src/Store/ConnectionHandler.java b/src/Store/ConnectionHandler.java
new file mode 100644
index 0000000..45d4446
--- /dev/null
+++ b/src/Store/ConnectionHandler.java
@@ -0,0 +1,28 @@
+package Store;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+public class ConnectionHandler {
+ String address;
+ public static Connection connection;
+
+ public ConnectionHandler(String address) {
+ this.address = address;
+ }
+
+ public void connect() {
+ try {
+ connection = DriverManager.getConnection(this.address);
+
+ // create tables if they don't exist
+ Book.createTable();
+ User.createTable();
+ } catch (SQLException e) {
+ System.err.println(e.getMessage());
+ }
+ }
+
+ // TODO: disconnect
+}
diff --git a/src/Store/User.java b/src/Store/User.java
new file mode 100644
index 0000000..e414520
--- /dev/null
+++ b/src/Store/User.java
@@ -0,0 +1,120 @@
+package Store;
+
+import Server.JSONMessage;
+import com.corundumstudio.socketio.listener.DataListener;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Map;
+
+public class User {
+ private int id;
+ private final String userName;
+ private final String password;
+
+ public User(String userName, String password) {
+ this.userName = userName;
+ this.password = password;
+ }
+
+ public boolean save() throws SQLException {
+ if (!checkUniqueUsername(userName)) {
+ return false;
+ }
+
+ String sql = "INSERT INTO User (userName, password) VALUES (?, ?)";
+ PreparedStatement statement = ConnectionHandler.connection.prepareStatement(sql);
+
+ statement.setString(1, userName);
+ statement.setString(2, password);
+
+ statement.executeUpdate();
+
+ return true;
+ }
+
+ private boolean checkUniqueUsername(String userName) throws SQLException {
+ String sql = "SELECT * FROM User WHERE userName = '" + userName + "'";
+ Statement statement = ConnectionHandler.connection.createStatement();
+
+ ResultSet response = statement.executeQuery(sql);
+ while (response.next()) {
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean login() throws SQLException {
+ String sql = "SELECT * FROM User WHERE userName = '" + this.userName + "' AND password = '" + this.password + "'";
+ Statement statement = ConnectionHandler.connection.createStatement();
+
+ boolean loggedIn = false;
+ ResultSet response = statement.executeQuery(sql);
+ while (response.next()) {
+ this.id = response.getInt("ID");
+ loggedIn = true;
+ }
+
+ return loggedIn;
+ }
+
+ public static void createTable() throws SQLException {
+ String sql = "CREATE TABLE IF NOT EXISTS User (" +
+ "ID INTEGER NOT NULL PRIMARY KEY," +
+ "userName TEXT NOT NULL," +
+ "password text NOT NULL" +
+ ");";
+
+ Statement statement = ConnectionHandler.connection.createStatement();
+ statement.execute(sql);
+ }
+
+ public static DataListener<JSONMessage> signUpHandler() {
+ return ((client, data, ackSender) -> {
+ Map<String,String> d = data.getData();
+
+ User user = new User(d.get("userName"), d.get("password"));
+ try {
+ if (user.save()) {
+ client.sendEvent("signedUp");
+ } else {
+ client.sendEvent("usernameTaken");
+ client.sendEvent("signUpFailed");
+ }
+ } catch (SQLException e) {
+ client.sendEvent("signUpFailed");
+ System.out.println(e.getMessage());
+ }
+ });
+ }
+
+ public static DataListener<JSONMessage> loginHandler() {
+ return ((client, data, ackSender) -> {
+ Map<String,String> d = data.getData();
+
+ User user = new User(d.get("userName"), d.get("password"));
+ try {
+ user.login();
+ } catch (SQLException e) {
+ System.out.println(e.getMessage());
+ }
+
+ if (user.login()) {
+ client.sendEvent("loggedIn", user.id);
+ } else {
+ client.sendEvent("loginFailed");
+ }
+ });
+ }
+
+ public String toJSON() {
+ return "{" +
+ "\"id\": " + id + "," +
+ "\"userName\": " + userName + "," +
+ "\"password\": " + password +
+ " }";
+ }
+} \ No newline at end of file
diff --git a/src/UI/Components/BookListItem.java b/src/UI/Components/BookListItem.java
new file mode 100644
index 0000000..1204f76
--- /dev/null
+++ b/src/UI/Components/BookListItem.java
@@ -0,0 +1,48 @@
+package UI.Components;
+
+import Store.Book;
+
+import javax.swing.*;
+import javax.swing.border.EmptyBorder;
+import javax.swing.border.MatteBorder;
+import java.awt.*;
+import java.sql.SQLException;
+import java.util.Objects;
+
+public class BookListItem extends JPanel {
+ BookListItem(Book book) {
+ this.setBorder(BorderFactory.createCompoundBorder(new EmptyBorder(6, 10, 6, 10), new MatteBorder(0, 0, 1, 0, Color.BLACK)));
+
+ JLabel titleLabel = new JLabel(book.getTitle());
+ titleLabel.setFont(new Font(titleLabel.getFont().getName(), Font.BOLD, titleLabel.getFont().getSize() + 2));
+ this.add(titleLabel);
+
+ JPanel deleteButtonPanel = new JPanel();
+ JButton deleteButton = new JButton("Delete Book");
+ deleteButtonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
+ deleteButtonPanel.add(deleteButton);
+ this.add(deleteButtonPanel);
+
+ deleteButton.addActionListener(e -> {
+ try {
+ book.delete();
+ } catch (SQLException ex) {
+ throw new RuntimeException(ex);
+ }
+ });
+
+ JLabel authorLabel = new JLabel(book.getAuthor());
+ authorLabel.setForeground(Color.DARK_GRAY);
+ this.add(authorLabel);
+
+ JPanel issuedByLabelPanel = new JPanel();
+ JLabel issuedByLabel = new JLabel(!Objects.equals(book.getIssuedByName(), null) ? "Issued by user " + book.getIssuedByName() : "Available");
+ issuedByLabelPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
+ issuedByLabelPanel.add(issuedByLabel);
+ this.add(issuedByLabelPanel);
+
+ this.setMaximumSize(new Dimension(650, 100));
+ this.setLayout(new GridLayout(2, 2));
+ }
+}
+
diff --git a/src/UI/Components/BooksList.java b/src/UI/Components/BooksList.java
new file mode 100644
index 0000000..dfb21bf
--- /dev/null
+++ b/src/UI/Components/BooksList.java
@@ -0,0 +1,47 @@
+package UI.Components;
+
+import Store.Book;
+
+import javax.swing.*;
+import javax.swing.border.EmptyBorder;
+import java.sql.SQLException;
+import java.util.ArrayList;
+
+public class BooksList extends JPanel {
+ private static JPanel listPanel;
+
+ public BooksList() throws SQLException {
+ listPanel = new JPanel();
+ listPanel.setLayout(new BoxLayout(listPanel, BoxLayout.Y_AXIS));
+
+ refreshBooks();
+
+ JScrollPane scrollPane = new JScrollPane(listPanel);
+ scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+
+ this.add(scrollPane);
+
+ this.setBorder(new EmptyBorder(4, 8, 8, 8));
+ this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+ }
+
+ public static void refreshBooks(ArrayList<Book> books) throws SQLException {
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ listPanel.removeAll();
+
+ for (Book book : books) {
+ listPanel.add(new BookListItem(book));
+ }
+
+ listPanel.revalidate();
+ listPanel.repaint();
+ }
+ }).start();
+ }
+
+ public static void refreshBooks() throws SQLException {
+ refreshBooks(Book.getAll(false));
+ }
+}
diff --git a/src/UI/Components/InputBox.java b/src/UI/Components/InputBox.java
new file mode 100644
index 0000000..c15381e
--- /dev/null
+++ b/src/UI/Components/InputBox.java
@@ -0,0 +1,39 @@
+package UI.Components;
+
+import javax.swing.*;
+import java.awt.*;
+
+public class InputBox extends JPanel {
+ JLabel label;
+ JTextField textField;
+
+ public InputBox(String label) {
+ this.label = new JLabel(label);
+ this.label.setPreferredSize(new Dimension(70, 30));
+ this.add(this.label);
+
+ this.add(Box.createHorizontalGlue());
+
+ this.textField = new JTextField(20);
+ this.add(this.textField);
+
+ this.setLayout(new FlowLayout(FlowLayout.CENTER));
+ }
+
+ public String getLabel() {
+ return this.label.getText();
+ }
+
+ public String getValue() {
+ return this.textField.getText();
+ }
+
+ public void setLabel(String label) {
+ this.label.setText(label);
+ }
+
+ public void setValue(String value) {
+ this.textField.setText(value);
+ this.textField.repaint();
+ }
+}
diff --git a/src/UI/Components/MenuBar.java b/src/UI/Components/MenuBar.java
new file mode 100644
index 0000000..454bb83
--- /dev/null
+++ b/src/UI/Components/MenuBar.java
@@ -0,0 +1,29 @@
+package UI.Components;
+
+import javax.swing.*;
+import javax.swing.border.EmptyBorder;
+import java.awt.*;
+
+public class MenuBar extends JPanel {
+ public JButton settingsButton;
+ public JButton startStopButton;
+ public JButton addBookButton;
+
+ public MenuBar() {
+ settingsButton = new JButton("Settings");
+ this.add(settingsButton);
+
+ this.add(Box.createRigidArea(new Dimension(15, 0)));
+
+ startStopButton = new JButton("Start Server");
+ this.add(startStopButton);
+
+ this.add(Box.createHorizontalGlue());
+
+ addBookButton = new JButton("Add Book");
+ this.add(addBookButton);
+
+ this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
+ this.setBorder(new EmptyBorder(8, 8, 4, 8));
+ }
+}
diff --git a/src/UI/MainWindow.java b/src/UI/MainWindow.java
new file mode 100644
index 0000000..6c1ef83
--- /dev/null
+++ b/src/UI/MainWindow.java
@@ -0,0 +1,121 @@
+package UI;
+
+import Server.SocketServer;
+import Store.Book;
+import UI.Components.BooksList;
+import UI.Components.MenuBar;
+import com.corundumstudio.socketio.Configuration;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.sql.SQLException;
+
+public class MainWindow extends JFrame {
+ private static String hostname = "localhost";
+ private static int port = 8080;
+ private static SocketServer server;
+ public static boolean serverStarted = false;
+ private MenuBar menuBar;
+
+ private static NewBookPopupWindow newBookPopup;
+ private static SettingsPopupWindow settingsPopup;
+
+ public MainWindow() {
+ this.setTitle("Admin Panel - Library Management System");
+ this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ this.setSize(650, 500);
+ this.setResizable(false);
+ this.setLocationRelativeTo(null);
+
+ menuBar = new MenuBar();
+ menuBar.settingsButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (settingsPopup == null) {
+ settingsPopup = new SettingsPopupWindow();
+ settingsPopup.saveButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ hostname = settingsPopup.hostnameInput.getValue();
+ port = Integer.parseInt(settingsPopup.portInput.getValue());
+
+ settingsPopup.setVisible(false);
+ }
+ });
+ }
+
+ settingsPopup.hostnameInput.setValue(hostname);
+ settingsPopup.portInput.setValue(String.valueOf(port));
+
+ settingsPopup.setVisible(true);
+ }
+ });
+ menuBar.startStopButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (serverStarted) {
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ stopServer();
+ }
+ }).start();
+ } else {
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ startServer();
+ }
+ }).start();
+ }
+ }
+ });
+ menuBar.addBookButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (newBookPopup == null) {
+ newBookPopup = new NewBookPopupWindow();
+ }
+
+ newBookPopup.showWindow();
+ }
+ });
+ this.add(menuBar);
+
+ this.add(Box.createRigidArea(new Dimension(0, 5)));
+
+ BooksList booksList = null;
+ try {
+ booksList = new BooksList();
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ this.add(booksList);
+
+ this.setLayout(new BoxLayout(this.getContentPane(), BoxLayout.Y_AXIS));
+ }
+
+ private void setupServer() {
+ Configuration config = new Configuration();
+ config.setHostname(hostname);
+ config.setPort(port);
+ server = new SocketServer(config);
+ }
+
+ private void startServer() {
+ setupServer();
+ server.start();
+ serverStarted = true;
+ menuBar.settingsButton.setEnabled(false);
+ menuBar.startStopButton.setText("Stop Server");
+ }
+
+ private void stopServer() {
+ server.stop();
+ serverStarted = false;
+ menuBar.settingsButton.setEnabled(true);
+ menuBar.startStopButton.setText("Start Server");
+ }
+}
diff --git a/src/UI/NewBookPopupWindow.java b/src/UI/NewBookPopupWindow.java
new file mode 100644
index 0000000..f50f3e6
--- /dev/null
+++ b/src/UI/NewBookPopupWindow.java
@@ -0,0 +1,58 @@
+package UI;
+
+import Store.Book;
+import UI.Components.InputBox;
+
+import javax.swing.*;
+import javax.swing.border.EmptyBorder;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.sql.SQLException;
+
+public class NewBookPopupWindow extends JFrame {
+ public InputBox titleInput;
+ public InputBox authorInput;
+ public JButton saveButton;
+
+ public NewBookPopupWindow() {
+ this.setTitle("Add New Book");
+ this.setSize(350, 200);
+ this.setLocationRelativeTo(null);
+ this.setLayout(new FlowLayout(FlowLayout.TRAILING));
+
+ this.titleInput = new InputBox("Title:");
+ this.titleInput.setBorder(new EmptyBorder(0, 10, 0, 10));
+ this.add(this.titleInput);
+
+ this.authorInput = new InputBox("Author:");
+ this.authorInput.setBorder(new EmptyBorder(0, 10, 0, 10));
+ this.add(this.authorInput);
+
+ saveButton = new JButton("Save");
+ JPanel buttonPanel = new JPanel();
+ buttonPanel.setBorder(new EmptyBorder(0, 0, 0, 12));
+ buttonPanel.add(saveButton);
+ this.add(buttonPanel);
+
+ saveButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ Book newBook = new Book(titleInput.getValue(), authorInput.getValue());
+ try {
+ setVisible(false);
+ newBook.save();
+ } catch (SQLException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ });
+ }
+
+ public void showWindow() {
+ this.setVisible(true);
+ this.titleInput.setValue("");
+ this.authorInput.setValue("");
+ this.repaint();
+ }
+}
diff --git a/src/UI/SettingsPopupWindow.java b/src/UI/SettingsPopupWindow.java
new file mode 100644
index 0000000..6c962f0
--- /dev/null
+++ b/src/UI/SettingsPopupWindow.java
@@ -0,0 +1,36 @@
+package UI;
+
+import UI.Components.InputBox;
+
+import javax.swing.*;
+import javax.swing.border.EmptyBorder;
+import java.awt.*;
+
+public class SettingsPopupWindow extends JFrame {
+ public InputBox hostnameInput;
+ public InputBox portInput;
+ public JButton saveButton;
+
+ public SettingsPopupWindow() {
+ this.setTitle("Settings - Library Management System");
+ this.setSize(350, 200);
+ this.setResizable(false);
+ this.setLocationRelativeTo(null);
+
+ this.hostnameInput = new InputBox("Hostname:");
+ this.hostnameInput.setBorder(new EmptyBorder(0, 10, 0, 10));
+ this.add(this.hostnameInput);
+
+ this.portInput = new InputBox("PORT:");
+ this.portInput.setBorder(new EmptyBorder(0, 10, 0, 10));
+ this.add(this.portInput);
+
+ saveButton = new JButton("Save");
+ JPanel buttonPanel = new JPanel();
+ buttonPanel.setBorder(new EmptyBorder(0, 0, 0, 12));
+ buttonPanel.add(saveButton);
+ this.add(buttonPanel);
+
+ this.setLayout(new FlowLayout(FlowLayout.TRAILING));
+ }
+}