-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathViewBooksPanel.java
More file actions
309 lines (264 loc) · 11.2 KB
/
Copy pathViewBooksPanel.java
File metadata and controls
309 lines (264 loc) · 11.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
package ui;
import dao.BookDAO;
import models.Book;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.util.List;
import java.util.logging.Logger;
/**
* ViewBooksPanel.java - Panel to display all books in library
*
* Features:
* - Displays all books in table format
* - Shows book details (ID, Title, Author, ISBN, etc.)
* - Sortable columns
* - Row selection for detailed view
* - Statistics summary
*
* Best Practice: Pagination could be added for large datasets
*/
public class ViewBooksPanel extends JPanel {
private static final Logger logger = Logger.getLogger(ViewBooksPanel.class.getName());
private static final long serialVersionUID = 1L;
// UI Components
private JTable booksTable;
private DefaultTableModel tableModel;
private JLabel statisticsLabel;
private JButton refreshButton;
private JButton deleteButton;
private JTextArea detailsArea;
// Data Access
private BookDAO bookDAO;
// Table columns
private static final String[] COLUMN_NAMES =
{"ID", "Title", "Author", "ISBN", "Publisher", "Year", "Category",
"Total", "Available", "Price (₹)"};
/**
* Constructor
*/
public ViewBooksPanel(BookDAO bookDAO) {
this.bookDAO = bookDAO;
setLayout(new BorderLayout(10, 10));
setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
// Create top panel with buttons and statistics
JPanel topPanel = createTopPanel();
add(topPanel, BorderLayout.NORTH);
// Create center panel with table
JPanel centerPanel = createTablePanel();
add(centerPanel, BorderLayout.CENTER);
// Create bottom panel with details
JPanel bottomPanel = createDetailsPanel();
add(bottomPanel, BorderLayout.SOUTH);
// Load initial data
loadAllBooks();
}
/**
* Creates top panel with refresh button and statistics
*/
private JPanel createTopPanel() {
JPanel panel = new JPanel(new BorderLayout());
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
refreshButton = new JButton("🔄 Refresh List");
refreshButton.addActionListener(e -> loadAllBooks());
buttonPanel.add(refreshButton);
deleteButton = new JButton("🗑 Delete Selected");
deleteButton.addActionListener(e -> handleDeleteBook());
deleteButton.setEnabled(false);
buttonPanel.add(deleteButton);
statisticsLabel = new JLabel(" ");
statisticsLabel.setFont(new Font("Arial", Font.BOLD, 12));
statisticsLabel.setForeground(new Color(0, 102, 204));
panel.add(buttonPanel, BorderLayout.WEST);
panel.add(statisticsLabel, BorderLayout.EAST);
return panel;
}
/**
* Creates the table panel
*/
private JPanel createTablePanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createTitledBorder("All Books in Library"));
// Create table model
tableModel = new DefaultTableModel(COLUMN_NAMES, 0) {
@Override
public boolean isCellEditable(int row, int column) {
return false; // Read-only table
}
};
// Create table
booksTable = new JTable(tableModel);
booksTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
booksTable.setRowHeight(25);
booksTable.getTableHeader().setFont(new Font("Arial", Font.BOLD, 11));
booksTable.setFont(new Font("Arial", Font.PLAIN, 11));
// Set column widths
booksTable.getColumnModel().getColumn(0).setPreferredWidth(40); // ID
booksTable.getColumnModel().getColumn(1).setPreferredWidth(150); // Title
booksTable.getColumnModel().getColumn(2).setPreferredWidth(100); // Author
booksTable.getColumnModel().getColumn(3).setPreferredWidth(80); // ISBN
booksTable.getColumnModel().getColumn(4).setPreferredWidth(100); // Publisher
booksTable.getColumnModel().getColumn(5).setPreferredWidth(50); // Year
booksTable.getColumnModel().getColumn(6).setPreferredWidth(80); // Category
booksTable.getColumnModel().getColumn(7).setPreferredWidth(50); // Total
booksTable.getColumnModel().getColumn(8).setPreferredWidth(70); // Available
booksTable.getColumnModel().getColumn(9).setPreferredWidth(70); // Price
// Add selection listener to show details
booksTable.getSelectionModel().addListSelectionListener(e -> {
if (!e.getValueIsAdjusting()) {
showSelectedBookDetails();
updateDeleteButtonState();
}
});
// Create scroll pane
JScrollPane scrollPane = new JScrollPane(booksTable);
scrollPane.setPreferredSize(new Dimension(900, 350));
panel.add(scrollPane, BorderLayout.CENTER);
return panel;
}
/**
* Creates details panel for selected book
*/
private JPanel createDetailsPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createTitledBorder("Selected Book Details"));
panel.setPreferredSize(new Dimension(900, 100));
detailsArea = new JTextArea(4, 80);
detailsArea.setEditable(false);
detailsArea.setLineWrap(true);
detailsArea.setWrapStyleWord(true);
detailsArea.setFont(new Font("Arial", Font.PLAIN, 11));
detailsArea.setText("Select a book from the table to see details");
JScrollPane scrollPane = new JScrollPane(detailsArea);
panel.add(scrollPane, BorderLayout.CENTER);
return panel;
}
/**
* Loads all books from database and displays in table
*/
private void loadAllBooks() {
try {
List<Book> books = bookDAO.getAllBooks();
tableModel.setRowCount(0); // Clear existing rows
if (books.isEmpty()) {
statisticsLabel.setText("No books in library");
deleteButton.setEnabled(false);
} else {
// Add each book as a row
for (Book book : books) {
Object[] rowData = {
book.getBookId(),
book.getTitle(),
book.getAuthor(),
book.getIsbn(),
book.getPublisher(),
book.getPublicationYear(),
book.getCategory(),
book.getTotalCopies(),
book.getAvailableCopies(),
String.format("%.2f", book.getPrice())
};
tableModel.addRow(rowData);
}
// Update statistics
updateStatistics(books);
booksTable.clearSelection();
updateDeleteButtonState();
logger.info("Loaded " + books.size() + " books");
}
} catch (Exception e) {
logger.severe("Error loading books: " + e.getMessage());
JOptionPane.showMessageDialog(this, "Error loading books: " + e.getMessage(),
"Error", JOptionPane.ERROR_MESSAGE);
}
}
/**
* Updates statistics label
*/
private void updateStatistics(List<Book> books) {
if (books.isEmpty()) {
statisticsLabel.setText("No books");
return;
}
int totalBooks = books.size();
int availableBooks = (int) books.stream()
.filter(Book::isAvailable)
.count();
int unavailableBooks = totalBooks - availableBooks;
double totalPrice = books.stream()
.mapToDouble(Book::getPrice)
.sum();
String stats = String.format(
"Total Books: %d | Available: %d | Unavailable: %d | Total Value: ₹%.2f",
totalBooks, availableBooks, unavailableBooks, totalPrice
);
statisticsLabel.setText(stats);
}
/**
* Shows details of selected book
*/
private void showSelectedBookDetails() {
int selectedRow = booksTable.getSelectedRow();
if (selectedRow < 0) {
detailsArea.setText("Select a book from the table to see details");
updateDeleteButtonState();
return;
}
try {
int bookId = (int) tableModel.getValueAt(selectedRow, 0);
Book book = bookDAO.getBookById(bookId);
if (book != null) {
String details = String.format(
"ID: %d | Title: %s | Author: %s\nISBN: %s | Publisher: %s | Year: %d\n" +
"Category: %s | Total Copies: %d | Available: %d | Price: ₹%.2f\n" +
"Availability: %s",
book.getBookId(), book.getTitle(), book.getAuthor(),
book.getIsbn(), book.getPublisher(), book.getPublicationYear(),
book.getCategory(), book.getTotalCopies(), book.getAvailableCopies(),
book.getPrice(),
book.isAvailable() ? "✓ Available" : "✗ Not Available"
);
detailsArea.setText(details);
}
} catch (Exception e) {
logger.severe("Error showing details: " + e.getMessage());
}
}
private void handleDeleteBook() {
int selectedRow = booksTable.getSelectedRow();
if (selectedRow < 0) {
JOptionPane.showMessageDialog(this,
"Please select a book to delete.",
"No Selection", JOptionPane.WARNING_MESSAGE);
return;
}
int bookId = (int) tableModel.getValueAt(selectedRow, 0);
String title = (String) tableModel.getValueAt(selectedRow, 1);
int choice = JOptionPane.showConfirmDialog(this,
"Are you sure you want to delete the selected book?\n" +
title + "\nThis action cannot be undone.",
"Confirm Delete", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
if (choice == JOptionPane.YES_OPTION) {
if (bookDAO.deleteBook(bookId)) {
JOptionPane.showMessageDialog(this,
"Book deleted successfully.",
"Deleted", JOptionPane.INFORMATION_MESSAGE);
loadAllBooks();
detailsArea.setText("Book deleted. Select another book for details.");
} else {
JOptionPane.showMessageDialog(this,
"Could not delete the selected book.",
"Delete Failed", JOptionPane.ERROR_MESSAGE);
}
}
}
private void updateDeleteButtonState() {
deleteButton.setEnabled(booksTable.getSelectedRow() >= 0);
}
/**
* Refreshes the panel
*/
public void refresh() {
loadAllBooks();
}
}