From b6869036b7839b4540cee1114f44bc5c9b33d9c4 Mon Sep 17 00:00:00 2001 From: Josh Walters Date: Tue, 13 Dec 2011 17:35:57 -0800 Subject: Initial commit of code. --- src/com/joshwalters/bookcatalog/AddBook.java | 123 ++++++ src/com/joshwalters/bookcatalog/ApplyChanges.java | 116 ++++++ src/com/joshwalters/bookcatalog/BookCatalog.java | 457 +++++++++++++++++++++ src/com/joshwalters/bookcatalog/DeleteBook.java | 120 ++++++ .../joshwalters/bookcatalog/SearchDatabase.java | 112 +++++ .../bookdatabase/BookAlreadyInDatabase.java | 34 ++ .../bookcatalog/bookdatabase/BookDatabase.java | 360 ++++++++++++++++ .../bookcatalog/bookdatabase/EmptyDatabase.java | 34 ++ .../bookcatalog/isbnlookup/GDataISBNLookup.java | 158 +++++++ .../bookcatalog/isbnlookup/ISBNLookup.java | 286 +++++++++++++ .../bookcatalog/isbnlookup/InvalidSearchTerms.java | 34 ++ .../bookcatalog/isbnlookup/NoBookFound.java | 34 ++ .../bookcatalog/sound/ErrorPlayingSound.java | 34 ++ .../bookcatalog/sound/PlayWavSoundFile.java | 78 ++++ .../bookcatalog/table/BookCatalogTableModel.java | 103 +++++ 15 files changed, 2083 insertions(+) create mode 100644 src/com/joshwalters/bookcatalog/AddBook.java create mode 100644 src/com/joshwalters/bookcatalog/ApplyChanges.java create mode 100644 src/com/joshwalters/bookcatalog/BookCatalog.java create mode 100644 src/com/joshwalters/bookcatalog/DeleteBook.java create mode 100644 src/com/joshwalters/bookcatalog/SearchDatabase.java create mode 100644 src/com/joshwalters/bookcatalog/bookdatabase/BookAlreadyInDatabase.java create mode 100644 src/com/joshwalters/bookcatalog/bookdatabase/BookDatabase.java create mode 100644 src/com/joshwalters/bookcatalog/bookdatabase/EmptyDatabase.java create mode 100644 src/com/joshwalters/bookcatalog/isbnlookup/GDataISBNLookup.java create mode 100644 src/com/joshwalters/bookcatalog/isbnlookup/ISBNLookup.java create mode 100644 src/com/joshwalters/bookcatalog/isbnlookup/InvalidSearchTerms.java create mode 100644 src/com/joshwalters/bookcatalog/isbnlookup/NoBookFound.java create mode 100644 src/com/joshwalters/bookcatalog/sound/ErrorPlayingSound.java create mode 100644 src/com/joshwalters/bookcatalog/sound/PlayWavSoundFile.java create mode 100644 src/com/joshwalters/bookcatalog/table/BookCatalogTableModel.java (limited to 'src') diff --git a/src/com/joshwalters/bookcatalog/AddBook.java b/src/com/joshwalters/bookcatalog/AddBook.java new file mode 100644 index 0000000..05b227c --- /dev/null +++ b/src/com/joshwalters/bookcatalog/AddBook.java @@ -0,0 +1,123 @@ +/* + * Book Catalog - Catalog your book collection. + * + * Copyright (C) 2009 Joshua Walters + * URL: http://joshwalters.com + * + * This file is part of Book Catalog. + * + * Book Catalog is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Book Catalog is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Book Catalog. If not, see . + */ + +package com.joshwalters.bookcatalog; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.sql.SQLException; + +import javax.swing.JTable; +import javax.swing.JTextField; + +import com.joshwalters.bookcatalog.bookdatabase.BookAlreadyInDatabase; +import com.joshwalters.bookcatalog.bookdatabase.BookDatabase; +import com.joshwalters.bookcatalog.bookdatabase.EmptyDatabase; +import com.joshwalters.bookcatalog.isbnlookup.ISBNLookup; +import com.joshwalters.bookcatalog.isbnlookup.InvalidSearchTerms; +import com.joshwalters.bookcatalog.isbnlookup.NoBookFound; +import com.joshwalters.bookcatalog.sound.PlayWavSoundFile; +import com.joshwalters.bookcatalog.table.BookCatalogTableModel; + +/** + * Adds a book to the book database using an ISBN number. + * + * @author Josh Walters + */ +class AddBook implements ActionListener { + + private ISBNLookup bookLookup = null; + private BookDatabase bookDatabase = null; + private JTable bookCatalogTable = null; + + /** + * Get the different objects needed for the class to function. + * + * @param bookDatabase + * @param bookLookup + * @param bookCatalogTable + */ + public AddBook(BookDatabase bookDatabase, ISBNLookup bookLookup, + JTable bookCatalogTable) { + this.bookDatabase = bookDatabase; + this.bookLookup = bookLookup; + this.bookCatalogTable = bookCatalogTable; + } + + /** + * Add the book to the database using its ISBN number. + */ + public void actionPerformed(ActionEvent arg) { + try { + String barcode = null; + JTextField addBookField = (JTextField) arg.getSource(); + barcode = addBookField.getText(); + addBookField.setText(""); + // Search for the book using its barcode. + bookLookup.searchBooks(barcode); + // Insert the book into the database. + bookDatabase.insertBook(bookLookup.getTitle(), bookLookup + .getAuthor(), bookLookup.getDate(), bookLookup + .getDescription(), bookLookup.getISBN(), bookLookup + .getPrice(), bookLookup.getPublisher(), bookLookup + .getSubject()); + // Play the beep sound to alert the user that the book was added to + // the database. + new PlayWavSoundFile("data/sounds/beep.wav").start(); + try { + // Get the table model of the table. + BookCatalogTableModel bookCatalogTableModel = (BookCatalogTableModel) bookCatalogTable + .getModel(); + // Update the data in the table with the new book. + bookCatalogTableModel.setData(bookDatabase + .getDatabaseForTable()); + // Refresh the table to draw the new info. + bookCatalogTableModel.fireTableDataChanged(); + } catch (EmptyDatabase e) { + // The database was empty, print an error message. + System.err.println(e.getLocalizedMessage()); + } + // The following code selects the newly added row. + int row = bookCatalogTable.getRowCount() - 1; + int col = 4; + // Search for the row, and then select it. + for (int i = 0; i <= row; i++) { + String value = (String) bookCatalogTable.getValueAt(i, col); + if (value.equalsIgnoreCase(bookLookup.getISBN())) { + bookCatalogTable.setRowSelectionInterval(i, i); + } + } + } catch (SQLException e) { + // There was an SQL error of some sort. + System.err.println(e.getLocalizedMessage()); + } catch (NoBookFound e) { + // The book data was not found online, play the error sound. + new PlayWavSoundFile("data/sounds/error.wav").start(); + } catch (BookAlreadyInDatabase e) { + // The book was already in the error database, play the error sound. + new PlayWavSoundFile("data/sounds/beep.wav").start(); + } catch (InvalidSearchTerms e) { + // Invalid search terms, play the error sound. + new PlayWavSoundFile("data/sounds/error.wav").start(); + } + } +} diff --git a/src/com/joshwalters/bookcatalog/ApplyChanges.java b/src/com/joshwalters/bookcatalog/ApplyChanges.java new file mode 100644 index 0000000..445d89c --- /dev/null +++ b/src/com/joshwalters/bookcatalog/ApplyChanges.java @@ -0,0 +1,116 @@ +/* + * Book Catalog - Catalog your book collection. + * + * Copyright (C) 2009 Joshua Walters + * URL: http://joshwalters.com + * + * This file is part of Book Catalog. + * + * Book Catalog is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Book Catalog is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Book Catalog. If not, see . + */ + +package com.joshwalters.bookcatalog; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.sql.SQLException; + +import javax.swing.JTable; +import javax.swing.JTextArea; +import javax.swing.JTextField; + +import com.joshwalters.bookcatalog.bookdatabase.BookDatabase; +import com.joshwalters.bookcatalog.bookdatabase.EmptyDatabase; +import com.joshwalters.bookcatalog.table.BookCatalogTableModel; + +/** + * Updates a book's entry in the database. + * + * @author Josh Walters + */ +class ApplyChanges implements ActionListener { + + private JTable bookCatalogTable; + private BookDatabase bookDatabase; + private JTextField titleField; + private JTextField authorField; + private JTextField dateField; + private JTextArea descriptionArea; + private JTextField ISBNField; + private JTextField priceField; + private JTextField publisherField; + private JTextField subjectField; + private JTextArea notesArea; + + /** + * Get the different objects needed for the class to function. + * + * @param bookCatalogTable + * @param bookDatabase + * @param titleField + * @param authorField + * @param dateField + * @param descriptionArea + * @param ISBNField + * @param priceField + * @param publisherField + * @param subjectField + * @param notesArea + */ + ApplyChanges(JTable bookCatalogTable, BookDatabase bookDatabase, + JTextField titleField, JTextField authorField, + JTextField dateField, JTextArea descriptionArea, + JTextField ISBNField, JTextField priceField, + JTextField publisherField, JTextField subjectField, + JTextArea notesArea) { + this.bookCatalogTable = bookCatalogTable; + this.bookDatabase = bookDatabase; + this.titleField = titleField; + this.authorField = authorField; + this.dateField = dateField; + this.descriptionArea = descriptionArea; + this.ISBNField = ISBNField; + this.priceField = priceField; + this.publisherField = publisherField; + this.subjectField = subjectField; + this.notesArea = notesArea; + } + + /** + * The user hit the "Apply Changes" button, update the book entry. + */ + public void actionPerformed(ActionEvent arg) { + try { + // Update the book entry. + bookDatabase.updateBook(titleField.getText(), + authorField.getText(), dateField.getText(), descriptionArea + .getText(), ISBNField.getText(), priceField + .getText(), publisherField.getText(), subjectField + .getText(), notesArea.getText()); + // Get the table model. + BookCatalogTableModel bookCatalogTableModel = (BookCatalogTableModel) bookCatalogTable + .getModel(); + // Update the table's data. + bookCatalogTableModel.setData(bookDatabase.getDatabaseForTable()); + // Refresh the table. + bookCatalogTableModel.fireTableDataChanged(); + } catch (SQLException e) { + // There was an SQL error. + System.err.println(e.getLocalizedMessage()); + } catch (EmptyDatabase e) { + // The database was empty. + System.err.println(e.getLocalizedMessage()); + } + } +} \ No newline at end of file diff --git a/src/com/joshwalters/bookcatalog/BookCatalog.java b/src/com/joshwalters/bookcatalog/BookCatalog.java new file mode 100644 index 0000000..17aed55 --- /dev/null +++ b/src/com/joshwalters/bookcatalog/BookCatalog.java @@ -0,0 +1,457 @@ +/* + * Book Catalog - Catalog your book collection. + * + * Copyright (C) 2009 Joshua Walters + * URL: http://joshwalters.com + * + * This file is part of Book Catalog. + * + * Book Catalog is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Book Catalog is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Book Catalog. If not, see . + */ + +package com.joshwalters.bookcatalog; + +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.Rectangle; +import java.sql.SQLException; +import java.util.Comparator; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.JTextArea; +import javax.swing.JTextField; +import javax.swing.ListSelectionModel; +import javax.swing.UIManager; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.table.TableModel; +import javax.swing.table.TableRowSorter; + +import com.joshwalters.bookcatalog.bookdatabase.BookDatabase; +import com.joshwalters.bookcatalog.isbnlookup.GDataISBNLookup; +import com.joshwalters.bookcatalog.isbnlookup.ISBNLookup; +import com.joshwalters.bookcatalog.table.BookCatalogTableModel; + +/** + * Catalogs and organizes your book collection. + * + * @author Josh Walters + */ +public class BookCatalog { + + /** + * Performs book lookups using ISBN numbers. + */ + private ISBNLookup bookLookup = null; + /** + * Stores the users book catalog. + */ + private BookDatabase bookDatabase = null; + /** + * Allows user to search book catalog. + */ + private JTextField searchField; + /** + * Allows user to add book to catalog. + */ + private JTextField addBookField; + /** + * Displays the book catalog. + */ + // private JTable bookCatalogTable; + private JTable bookCatalogTable; + /** + * Used for managing the book catalog table. + */ + private BookCatalogTableModel bookCatalogTableModel; + /** + * Displays the title of a book. + */ + private JTextField titleField; + /** + * Displays the author of a book. + */ + private JTextField authorField; + /** + * Displays the publish date of a book. + */ + private JTextField dateField; + /** + * Displays the description of a book. + */ + private JTextArea descriptionArea; + /** + * Displays the ISBN number of a book. + */ + private JTextField ISBNField; + /** + * Displays the price of a book. + */ + private JTextField priceField; + /** + * Displays the publisher of a book. + */ + private JTextField publisherField; + /** + * Displays the subject of a book. + */ + private JTextField subjectField; + /** + * Displays the notes on a book. + */ + private JTextArea notesArea; + /** + * Stores the width of the different text fields/areas. + */ + private static final int FIELD_WIDTH = 20; + /** + * Stores the height of the text areas. + */ + private static final int FIELD_HEIGHT = 5; + + /** + * Sets up all the GUI components of the program. + */ + BookCatalog() { + // Setup the book lookup. + bookLookup = new GDataISBNLookup(); + // Setup the book database. + bookDatabase = new BookDatabase(); + try { + // Connect to the book database. + bookDatabase.connectToDatabase(); + } catch (SQLException e) { + // There was an SQL error of some sort. + System.err.println(e.getLocalizedMessage()); + } catch (ClassNotFoundException e) { + System.err.println(e.getLocalizedMessage()); + } + // Create the window and its label. + JFrame frame = new JFrame("Book Catalog"); + // Exit the window on close. + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + // Set the L&F to Nimbus if possible. + SetLookAndFeel(); + // Set the layout. + frame.setLayout(new GridBagLayout()); + // The constraints. + GridBagConstraints gridConstraints = new GridBagConstraints(); + // The search label. + JLabel searchLabel = new JLabel("Search"); + gridConstraints.gridx = 0; + gridConstraints.gridy = 0; + gridConstraints.insets.top = 10; + gridConstraints.insets.left = 20; + frame.add(searchLabel, gridConstraints); + // The search text field + searchField = new JTextField(FIELD_WIDTH); + gridConstraints.gridx = 1; + gridConstraints.gridy = 0; + gridConstraints.insets.top = 10; + gridConstraints.insets.left = 10; + frame.add(searchField, gridConstraints); + // The add book label + JLabel addBookLabel = new JLabel("Add Book"); + gridConstraints.gridx = 2; + gridConstraints.gridy = 0; + gridConstraints.insets.top = 10; + gridConstraints.insets.left = 60; + frame.add(addBookLabel, gridConstraints); + // The add book field + addBookField = new JTextField(FIELD_WIDTH); + gridConstraints.gridx = 3; + gridConstraints.gridy = 0; + gridConstraints.insets.top = 10; + gridConstraints.insets.left = 10; + gridConstraints.fill = GridBagConstraints.REMAINDER; + gridConstraints.anchor = GridBagConstraints.WEST; + frame.add(addBookField, gridConstraints); + // Change the grid constraints back to their the normal state. + gridConstraints.fill = GridBagConstraints.NONE; + gridConstraints.anchor = GridBagConstraints.CENTER; + gridConstraints.insets = new Insets(10, 10, 10, 10); + // The book catalog table. + bookCatalogTableModel = new BookCatalogTableModel(bookDatabase); + bookCatalogTable = new JTable(bookCatalogTableModel); + setupTable(); + gridConstraints.gridx = 0; + gridConstraints.gridy = 1; + gridConstraints.gridwidth = 4; + gridConstraints.gridheight = 10; + gridConstraints.weightx = 1; + gridConstraints.weighty = 1; + gridConstraints.fill = GridBagConstraints.BOTH; + // The scroll panel will store the book catalog table. + JScrollPane scrollPaneForCatalog = new JScrollPane(bookCatalogTable); + // Add the scroll panel with the table to the frame. + frame.add(scrollPaneForCatalog, gridConstraints); + // Change the grid constraints back to their the normal state. + gridConstraints.gridwidth = 1; + gridConstraints.gridheight = 1; + gridConstraints.weightx = 0; + gridConstraints.weighty = 0; + gridConstraints.fill = GridBagConstraints.NONE; + // The title label + JLabel titleLabel = new JLabel("Title"); + gridConstraints.gridx = 5; + gridConstraints.gridy = 1; + frame.add(titleLabel, gridConstraints); + // The title field + titleField = new JTextField(FIELD_WIDTH); + gridConstraints.gridx = 6; + gridConstraints.gridy = 1; + frame.add(titleField, gridConstraints); + // The author label + JLabel authorLabel = new JLabel("Author"); + gridConstraints.gridx = 5; + gridConstraints.gridy = 2; + frame.add(authorLabel, gridConstraints); + // The author field + authorField = new JTextField(FIELD_WIDTH); + gridConstraints.gridx = 6; + gridConstraints.gridy = 2; + frame.add(authorField, gridConstraints); + // The date label + JLabel dateLabel = new JLabel("Date"); + gridConstraints.gridx = 5; + gridConstraints.gridy = 3; + frame.add(dateLabel, gridConstraints); + // The date field + dateField = new JTextField(FIELD_WIDTH); + gridConstraints.gridx = 6; + gridConstraints.gridy = 3; + frame.add(dateField, gridConstraints); + // The description label + JLabel descriptionLabel = new JLabel("Description"); + gridConstraints.gridx = 5; + gridConstraints.gridy = 4; + frame.add(descriptionLabel, gridConstraints); + // The date field + descriptionArea = new JTextArea(FIELD_HEIGHT, FIELD_WIDTH); + descriptionArea.setLineWrap(true); + descriptionArea.setWrapStyleWord(true); + gridConstraints.gridx = 6; + gridConstraints.gridy = 4; + JScrollPane scrollPaneForDescriptionArea = new JScrollPane( + descriptionArea); + frame.add(scrollPaneForDescriptionArea, gridConstraints); + // The ISBN label + JLabel ISBNLabel = new JLabel("ISBN"); + gridConstraints.gridx = 5; + gridConstraints.gridy = 5; + frame.add(ISBNLabel, gridConstraints); + // The ISBN field + ISBNField = new JTextField(FIELD_WIDTH); + ISBNField.setEnabled(false); + gridConstraints.gridx = 6; + gridConstraints.gridy = 5; + frame.add(ISBNField, gridConstraints); + // The price label + JLabel priceLabel = new JLabel("Price"); + gridConstraints.gridx = 5; + gridConstraints.gridy = 6; + frame.add(priceLabel, gridConstraints); + // The price field + priceField = new JTextField(FIELD_WIDTH); + gridConstraints.gridx = 6; + gridConstraints.gridy = 6; + frame.add(priceField, gridConstraints); + // The publisher label + JLabel publisherLabel = new JLabel("Publisher"); + gridConstraints.gridx = 5; + gridConstraints.gridy = 7; + frame.add(publisherLabel, gridConstraints); + // The publisher field + publisherField = new JTextField(FIELD_WIDTH); + gridConstraints.gridx = 6; + gridConstraints.gridy = 7; + frame.add(publisherField, gridConstraints); + // The subject label + JLabel subjectLabel = new JLabel("Subject"); + gridConstraints.gridx = 5; + gridConstraints.gridy = 8; + frame.add(subjectLabel, gridConstraints); + // The subject field + subjectField = new JTextField(FIELD_WIDTH); + gridConstraints.gridx = 6; + gridConstraints.gridy = 8; + frame.add(subjectField, gridConstraints); + // The notes label + JLabel ratingLabel = new JLabel("Notes"); + gridConstraints.gridx = 5; + gridConstraints.gridy = 9; + frame.add(ratingLabel, gridConstraints); + // The notes field + notesArea = new JTextArea(FIELD_HEIGHT, FIELD_WIDTH); + gridConstraints.gridx = 6; + gridConstraints.gridy = 9; + JScrollPane scrollPaneForNotesArea = new JScrollPane(notesArea); + frame.add(scrollPaneForNotesArea, gridConstraints); + // Listens for search database input. + SearchDatabase searchDatabase = new SearchDatabase(bookCatalogTable, + bookDatabase, searchField); + searchField.getDocument().addDocumentListener(searchDatabase); + // The apply changes button + JButton applyChangesButton = new JButton("Apply Changes"); + gridConstraints.gridx = 5; + gridConstraints.gridy = 10; + gridConstraints.anchor = GridBagConstraints.NORTH; + frame.add(applyChangesButton, gridConstraints); + // The delete book button + JButton deleteBookButton = new JButton("Delete Book"); + gridConstraints.gridx = 6; + gridConstraints.gridy = 10; + gridConstraints.anchor = GridBagConstraints.NORTH; + frame.add(deleteBookButton, gridConstraints); + // Listens for add book input. + addBookField.addActionListener(new AddBook(bookDatabase, bookLookup, + bookCatalogTable)); + // Listens for delete book button press. + deleteBookButton.addActionListener(new DeleteBook(bookDatabase, + titleField, authorField, dateField, descriptionArea, ISBNField, + priceField, publisherField, subjectField, notesArea, + searchDatabase)); + // Listens for apply changes button press. + applyChangesButton.addActionListener(new ApplyChanges(bookCatalogTable, + bookDatabase, titleField, authorField, dateField, + descriptionArea, ISBNField, priceField, publisherField, + subjectField, notesArea)); + // Set the frame size. + frame.pack(); + // Set minimum size for the frame. + Rectangle rect = frame.getBounds(); + frame.setMinimumSize(new Dimension(rect.width, rect.height)); + // Center the frame. + frame.setLocationRelativeTo(null); + // Show the frame. + frame.setVisible(true); + } + + /** + * Sets up the table. + */ + private void setupTable() { + // Make the table fill the scroll pane. + bookCatalogTable.setFillsViewportHeight(true); + // Don't show the grid. + bookCatalogTable.setShowGrid(false); + // Disable focus so that there wont be cell selection box highlights. + bookCatalogTable.setFocusable(false); + // Only allow one row at a time to be selected. + bookCatalogTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + // Prevent reordering of the table headers. + bookCatalogTable.getTableHeader().setReorderingAllowed(false); + // Auto sort the rows if the user clicks on the headers. + bookCatalogTable.setAutoCreateRowSorter(true); + // Create a new table sorter object. + TableRowSorter sorter = new TableRowSorter( + bookCatalogTable.getModel()); + // Set the table to use this new sorter object. + bookCatalogTable.setRowSorter(sorter); + /* + * Set the comparator for the 5th column (the price column) to handle + * money correctly. + */ + sorter.setComparator(5, new Comparator() { + + public int compare(String s1, String s2) { + // Strip the '$' from both of the strings. + s1 = s1.replaceFirst("\\$", ""); + s2 = s2.replaceFirst("\\$", ""); + Double one = new Double(s1); + Double two = new Double(s2); + return one.compareTo(two); + } + }); + // Listens for table row selections. + ListSelectionModel listSelection = bookCatalogTable.getSelectionModel(); + // Add the new listener. + listSelection.addListSelectionListener(new ListSelectionListener() { + + public void valueChanged(ListSelectionEvent arg0) { + int selectedRow = bookCatalogTable.getSelectedRow(); + if (selectedRow != -1) { + /* + * Place the data in the selected row to the corresponding + * text area/field. Also move the caret to the front of the + * text element. + */ + titleField.setText((String) bookCatalogTable.getValueAt( + selectedRow, 0)); + titleField.setCaretPosition(0); + ; + authorField.setText((String) bookCatalogTable.getValueAt( + selectedRow, 1)); + authorField.setCaretPosition(0); + dateField.setText((String) bookCatalogTable.getValueAt( + selectedRow, 2)); + dateField.setCaretPosition(0); + descriptionArea.setText((String) bookCatalogTable + .getValueAt(selectedRow, 3)); + descriptionArea.setCaretPosition(0); + ISBNField.setText((String) bookCatalogTable.getValueAt( + selectedRow, 4)); + ISBNField.setCaretPosition(0); + priceField.setText((String) bookCatalogTable.getValueAt( + selectedRow, 5)); + priceField.setCaretPosition(0); + publisherField.setText((String) bookCatalogTable + .getValueAt(selectedRow, 6)); + publisherField.setCaretPosition(0); + subjectField.setText((String) bookCatalogTable.getValueAt( + selectedRow, 7)); + subjectField.setCaretPosition(0); + notesArea.setText((String) bookCatalogTable.getValueAt( + selectedRow, 8)); + notesArea.setCaretPosition(0); + } + } + }); + } + + /** + * Disconnect from the database upon GC. + */ + protected void finalize() { + bookDatabase.disconnectFromDatabase(); + } + + /** + * Set the look and feel of the Swing GUI to Nimbus if possible. + */ + private void SetLookAndFeel() { + try { + // UIManager.getSystemLookAndFeelClassName() + UIManager + .setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"); + } catch (Exception e) { + // Do nothing. Just use the standard L&F. + } + } + + /** + * Run the program. + * + * @param args + */ + public static void main(String args[]) { + new BookCatalog(); + } +} \ No newline at end of file diff --git a/src/com/joshwalters/bookcatalog/DeleteBook.java b/src/com/joshwalters/bookcatalog/DeleteBook.java new file mode 100644 index 0000000..7f0bffc --- /dev/null +++ b/src/com/joshwalters/bookcatalog/DeleteBook.java @@ -0,0 +1,120 @@ +/* + * Book Catalog - Catalog your book collection. + * + * Copyright (C) 2009 Joshua Walters + * URL: http://joshwalters.com + * + * This file is part of Book Catalog. + * + * Book Catalog is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Book Catalog is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Book Catalog. If not, see . + */ + +package com.joshwalters.bookcatalog; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.sql.SQLException; + +import javax.swing.JOptionPane; +import javax.swing.JTextArea; +import javax.swing.JTextField; + +import com.joshwalters.bookcatalog.bookdatabase.BookDatabase; + +/** + * Deletes a book from the database. + * + * @author Josh Walters + */ +public class DeleteBook implements ActionListener { + + private BookDatabase bookDatabase; + private JTextField titleField; + private JTextField authorField; + private JTextField dateField; + private JTextArea descriptionArea; + private JTextField ISBNField; + private JTextField priceField; + private JTextField publisherField; + private JTextField subjectField; + private JTextArea notesArea; + private SearchDatabase searchDatabase; + + /** + * Get the different objects needed for the class to function. + * + * @param bookDatabase + * @param titleField + * @param authorField + * @param dateField + * @param descriptionArea + * @param ISBNField + * @param priceField + * @param publisherField + * @param subjectField + * @param notesArea + * @param searchDatabase + */ + public DeleteBook(BookDatabase bookDatabase, JTextField titleField, + JTextField authorField, JTextField dateField, + JTextArea descriptionArea, JTextField ISBNField, + JTextField priceField, JTextField publisherField, + JTextField subjectField, JTextArea notesArea, + SearchDatabase searchDatabase) { + this.bookDatabase = bookDatabase; + this.titleField = titleField; + this.authorField = authorField; + this.dateField = dateField; + this.descriptionArea = descriptionArea; + this.ISBNField = ISBNField; + this.priceField = priceField; + this.publisherField = publisherField; + this.subjectField = subjectField; + this.notesArea = notesArea; + this.searchDatabase = searchDatabase; + } + + /** + * The user clicked on the "Delete Book" button. Remove the book from the + * database. + */ + public void actionPerformed(ActionEvent arg) { + try { + // Check if the user really wants to delete the book. + int result = JOptionPane.showConfirmDialog(null, + "Do you really want to delete \"" + titleField.getText() + + "\" from your catalog?", "Warning", + JOptionPane.YES_NO_OPTION); + if (result == JOptionPane.YES_OPTION) { + // Delete the book using its ISBN number. + bookDatabase.deleteBook(ISBNField.getText()); + // Update the table. + searchDatabase.updateTableWithSearchString(); + // Clear all the text fields/areas. + titleField.setText(""); + authorField.setText(""); + dateField.setText(""); + descriptionArea.setText(""); + ISBNField.setText(""); + priceField.setText(""); + publisherField.setText(""); + subjectField.setText(""); + notesArea.setText(""); + } + } catch (SQLException e) { + // There was an SQL exception. + System.err.println(e.getLocalizedMessage()); + } + } +} diff --git a/src/com/joshwalters/bookcatalog/SearchDatabase.java b/src/com/joshwalters/bookcatalog/SearchDatabase.java new file mode 100644 index 0000000..ffe68f0 --- /dev/null +++ b/src/com/joshwalters/bookcatalog/SearchDatabase.java @@ -0,0 +1,112 @@ +/* + * Book Catalog - Catalog your book collection. + * + * Copyright (C) 2009 Joshua Walters + * URL: http://joshwalters.com + * + * This file is part of Book Catalog. + * + * Book Catalog is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Book Catalog is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Book Catalog. If not, see . + */ + +package com.joshwalters.bookcatalog; + +import java.sql.SQLException; + +import javax.swing.JTable; +import javax.swing.JTextField; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +import com.joshwalters.bookcatalog.bookdatabase.BookDatabase; +import com.joshwalters.bookcatalog.bookdatabase.EmptyDatabase; +import com.joshwalters.bookcatalog.table.BookCatalogTableModel; + +/** + * Searches the database for books. s + * + * @author Josh Walters + */ +class SearchDatabase implements DocumentListener { + + private JTable bookCatalogTable; + private BookDatabase bookDatabase; + private JTextField searchField; + + /** + * Get the different objects needed for the class to function. + * + * @param bookCatalogTable + * @param bookDatabase + * @param searchField + */ + public SearchDatabase(JTable bookCatalogTable, BookDatabase bookDatabase, + JTextField searchField) { + this.bookCatalogTable = bookCatalogTable; + this.bookDatabase = bookDatabase; + this.searchField = searchField; + } + + /** + * Updates the table with the search string given by the user. + */ + public void updateTableWithSearchString() { + try { + // Get the table model. + BookCatalogTableModel bookCatalogTableModel = (BookCatalogTableModel) bookCatalogTable + .getModel(); + // If the search field is empty, display all books in the database + // in the table. + if (searchField.getText().length() == 0) { + String[][] data = bookDatabase.getDatabaseForTable(); + bookCatalogTableModel.setData(data); + bookCatalogTableModel.fireTableDataChanged(); + } else { + // Search for matches to the search string. + String[][] data = bookDatabase + .searchDatabaseForTable(searchField.getText()); + // Update the table. + bookCatalogTableModel.setData(data); + // Refresh the table. + bookCatalogTableModel.fireTableDataChanged(); + } + } catch (SQLException e) { + // There was an SQL error of some sort. + System.err.println(e.getLocalizedMessage()); + } catch (EmptyDatabase e) { + // The database was empty. + System.err.println(e.getLocalizedMessage()); + } + } + + /** + * Nothing to do here. + */ + public void changedUpdate(DocumentEvent arg0) { + } + + /** + * Update the table with the search string. + */ + public void insertUpdate(DocumentEvent arg0) { + updateTableWithSearchString(); + } + + /** + * Update the table with the search string. + */ + public void removeUpdate(DocumentEvent arg0) { + updateTableWithSearchString(); + } +} \ No newline at end of file diff --git a/src/com/joshwalters/bookcatalog/bookdatabase/BookAlreadyInDatabase.java b/src/com/joshwalters/bookcatalog/bookdatabase/BookAlreadyInDatabase.java new file mode 100644 index 0000000..b6428ef --- /dev/null +++ b/src/com/joshwalters/bookcatalog/bookdatabase/BookAlreadyInDatabase.java @@ -0,0 +1,34 @@ +/* + * Book Catalog - Catalog your book collection. + * + * Copyright (C) 2009 Joshua Walters + * URL: http://joshwalters.com + * + * This file is part of Book Catalog. + * + * Book Catalog is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Book Catalog is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Book Catalog. If not, see . + */ + +package com.joshwalters.bookcatalog.bookdatabase; + +/** + * Thrown if the book is already in the database. + * + * @author Josh Walters + */ +public class BookAlreadyInDatabase extends Exception { + + /** The serial ID */ + private static final long serialVersionUID = -433273330040981967L; +} \ No newline at end of file diff --git a/src/com/joshwalters/bookcatalog/bookdatabase/BookDatabase.java b/src/com/joshwalters/bookcatalog/bookdatabase/BookDatabase.java new file mode 100644 index 0000000..9f06aba --- /dev/null +++ b/src/com/joshwalters/bookcatalog/bookdatabase/BookDatabase.java @@ -0,0 +1,360 @@ +/* + * Book Catalog - Catalog your book collection. + * + * Copyright (C) 2009 Joshua Walters + * URL: http://joshwalters.com + * + * This file is part of Book Catalog. + * + * Book Catalog is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Book Catalog is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Book Catalog. If not, see . + */ + +package com.joshwalters.bookcatalog.bookdatabase; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Vector; + +/** + * Manages the database of books. + * + * @author Josh Walters + */ +public class BookDatabase { + + /** The SQL statement. */ + private Statement statement; + /** The SQL result set. */ + private ResultSet resultSet; + /** The connection to the SQL database. */ + private Connection connection; + + /** + * Automatically disconnect from the database. + */ + protected void finalize() { + disconnectFromDatabase(); + } + + /** + * Connects to the database. If the table for the record of books does not + * exist yet, then it will be created. + * + * @throws SQLException + * @throws ClassNotFoundException + */ + public void connectToDatabase() throws SQLException, ClassNotFoundException { + try { + // Connect to the database. + Class.forName("org.sqlite.JDBC"); + // Create the database file. + connection = DriverManager + .getConnection("jdbc:sqlite:bookcatalog.db"); + statement = connection.createStatement(); + } catch (SQLException e) { + throw e; + } catch (ClassNotFoundException e) { + throw e; + } + // Set the timeout to unlimited. + statement.setQueryTimeout(0); + // Create the table if it does not exist. + statement.executeUpdate("create table if not exists bookcatalog(" + + "Title text, Author text, Date text," + + "Description text, ISBN text, Price text," + + "Publisher text, Subject text, Notes text)"); + } + + /** + * Check to see if a book is in the database. + * + * @param ISBN + * @return True if book is in database, false if not. + * @throws SQLException + */ + public boolean isBookInDatabase(String ISBN) throws SQLException { + // The SQL statement. + PreparedStatement preparedStatement = connection + .prepareStatement("select * from bookcatalog where ISBN = ?"); + preparedStatement.setString(1, ISBN); + resultSet = preparedStatement.executeQuery(); + boolean doesBookExist = resultSet.next(); + resultSet.close(); + return doesBookExist; + } + + /** + * Check if a book in the database has a price assigned to it. + * + * @param ISBN + * @return True if the book has price associated with it. False if not. + * @throws SQLException + */ + boolean bookHasPrice(String ISBN) throws SQLException { + // The SQL statement + PreparedStatement preparedStatement = connection + .prepareStatement("select Price from bookcatalog where ISBN = ?"); + preparedStatement.setString(1, ISBN); + resultSet = preparedStatement.executeQuery(); + resultSet.next(); + // Get the price value + String bookPriceInCatalog = resultSet.getString(1); + resultSet.close(); + if (bookPriceInCatalog == null) { + return false; + } else { + return true; + } + } + + /** + * Sets the price for a book. + * + * @param ISBN + * @param Price + * @throws SQLException + */ + void setBookPrice(String ISBN, String Price) throws SQLException { + // The SQL statement + PreparedStatement preparedStatement = connection + .prepareStatement("update bookcatalog set Price = ? where ISBN = ?"); + preparedStatement.setString(1, Price); + preparedStatement.setString(2, ISBN); + if (preparedStatement.execute()) { + resultSet = statement.getResultSet(); + if (resultSet != null) { + resultSet.close(); + } + } + } + + /** + * Delete a book from the database. + * + * @param ISBN + * Used to identify the book to delete. + * @throws SQLException + */ + public void deleteBook(String ISBN) throws SQLException { + // The SQL statement + PreparedStatement preparedStatement = connection + .prepareStatement("delete from bookcatalog where ISBN = ?"); + preparedStatement.setString(1, ISBN); + if (preparedStatement.execute()) { + resultSet = statement.getResultSet(); + if (resultSet != null) { + resultSet.close(); + } + } + } + + /** + * Updates a book entry with new information. + * + * @param Title + * @param Author + * @param Date + * @param Description + * @param ISBN + * @param Price + * @param Publisher + * @param Subject + * @param Notes + * @throws SQLException + */ + public void updateBook(String Title, String Author, String Date, + String Description, String ISBN, String Price, String Publisher, + String Subject, String Notes) throws SQLException { + // The SQL statement + PreparedStatement preparedStatement = connection + .prepareStatement("update bookcatalog set Title = ?, Author = ?, Date = ?, Description = ?, Price = ?, Publisher = ?, Subject = ?, Notes = ? where ISBN = ?"); + preparedStatement.setString(1, Title); + preparedStatement.setString(2, Author); + preparedStatement.setString(3, Date); + preparedStatement.setString(4, Description); + preparedStatement.setString(5, Price); + preparedStatement.setString(6, Publisher); + preparedStatement.setString(7, Subject); + preparedStatement.setString(8, Notes); + preparedStatement.setString(9, ISBN); + if (preparedStatement.execute()) { + resultSet = statement.getResultSet(); + if (resultSet != null) { + resultSet.close(); + } + } + } + + /** + * Inserts a book into the database. + * + * @param Title + * @param Author + * @param Date + * @param Description + * @param ISBN + * @param Price + * @param Publisher + * @param Subject + * @throws SQLException + * @throws BookAlreadyInDatabase + */ + public void insertBook(String Title, String Author, String Date, + String Description, String ISBN, String Price, String Publisher, + String Subject) throws SQLException, BookAlreadyInDatabase { + // Check to see if the book is in the database + if (!isBookInDatabase(ISBN)) { + // The SQL statement + PreparedStatement preparedStatement = connection + .prepareStatement("insert into bookcatalog values(?,?,?,?,?,?,?,?,?);"); + // Set the values for the prepared statement + preparedStatement.setString(1, Title); + preparedStatement.setString(2, Author); + preparedStatement.setString(3, Date); + preparedStatement.setString(4, Description); + preparedStatement.setString(5, ISBN); + preparedStatement.setString(6, Price); + preparedStatement.setString(7, Publisher); + preparedStatement.setString(8, Subject); + // Set the notes for the book blank by default. + preparedStatement.setString(9, ""); + if (preparedStatement.execute()) { + resultSet = statement.getResultSet(); + if (resultSet != null) { + resultSet.close(); + } + } + } else { + // If the book exists in the database check to see if it has a price + // assigned to it + if (!bookHasPrice(ISBN) && Price != null) { + // If the book doesn't have a price associated with it, give it + // one. + setBookPrice(ISBN, Price); + } else { + // The book is already in the database and we don't have/need + // the price. + throw new BookAlreadyInDatabase(); + } + } + } + + /** + * Get the database in a multidimensional string for use with a Swing table. + * + * @return The database in a multidimensional string. + * @throws SQLException + * @throws EmptyDatabase + */ + public String[][] getDatabaseForTable() throws SQLException, EmptyDatabase { + // Get the number of books in the database. + resultSet = statement + .executeQuery("select count(ISBN) from bookcatalog"); + if (resultSet.next()) { + int rows = resultSet.getInt(1); + resultSet.close(); + // Select all the data in the database. + resultSet = statement.executeQuery("select * from bookcatalog"); + // Create a new multidimensional string that will store the + // database. + String data[][] = new String[rows][9]; + resultSet.next(); + // Iterate over the database and store the data in the string. + for (int i = 0; i < rows; i++) { + for (int j = 1; j <= 9; j++) { + data[i][j - 1] = resultSet.getString(j); + } + resultSet.next(); + } + resultSet.close(); + // Return the database in string format. + return data; + } + throw new EmptyDatabase(); + } + + /** + * This gets the database for a Swing table, but limits the results to + * entries that match the search string. + * + * @param searchString + * @return + * @throws SQLException + * @throws EmptyDatabase + */ + public String[][] searchDatabaseForTable(String searchString) + throws SQLException, EmptyDatabase { + String[][] data = null; + Vector cells = new Vector(); + // Remove all percent signs from the string. + searchString = searchString.replace("\\%", ""); + // Add percent signs at beginning and end of string. + searchString = "%" + searchString + "%"; + // Replace space characters with percent signs. + searchString = searchString.replace(" ", "%"); + /* + * Look for entries in the database that are similar to the search + * string. + */ + PreparedStatement preparedStatement = connection + .prepareStatement("select * from bookcatalog where Title like ? or Author like ? or Date like ? or Description like ? or ISBN like ? or Price like ? or Publisher like ? or Subject like ? or Notes like ?"); + preparedStatement.setString(1, searchString); + preparedStatement.setString(2, searchString); + preparedStatement.setString(3, searchString); + preparedStatement.setString(4, searchString); + preparedStatement.setString(5, searchString); + preparedStatement.setString(6, searchString); + preparedStatement.setString(7, searchString); + preparedStatement.setString(8, searchString); + preparedStatement.setString(9, searchString); + resultSet = preparedStatement.executeQuery(); + // Store the result data in a vector. + while (resultSet.next()) { + for (int i = 1; i <= 9; i++) { + cells.add(resultSet.getString(i)); + } + } + // Create a new multidimensional string to store the database search + // result. + data = new String[cells.size() / 9][9]; + // Store the results in the string. + for (int i = 0; i < cells.size() / 9; i++) { + for (int j = 0; j < 9; j++) { + data[i][j] = (String) cells.get((i * 9) + j); + } + } + // Return the data in string format. + return data; + } + + /** + * Disconnect from the database. This will be called upon GC, but is best to + * call it manually. + * + * @throws SQLException + */ + public void disconnectFromDatabase() { + try { + if (connection.isClosed() != true) { + connection.close(); + } + } catch (SQLException e) { + // Do nothing + } + } +} \ No newline at end of file diff --git a/src/com/joshwalters/bookcatalog/bookdatabase/EmptyDatabase.java b/src/com/joshwalters/bookcatalog/bookdatabase/EmptyDatabase.java new file mode 100644 index 0000000..1ee98bf --- /dev/null +++ b/src/com/joshwalters/bookcatalog/bookdatabase/EmptyDatabase.java @@ -0,0 +1,34 @@ +/* + * Book Catalog - Catalog your book collection. + * + * Copyright (C) 2009 Joshua Walters + * URL: http://joshwalters.com + * + * This file is part of Book Catalog. + * + * Book Catalog is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Book Catalog is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Book Catalog. If not, see . + */ + +package com.joshwalters.bookcatalog.bookdatabase; + +/** + * Thrown if the database is empty. + * + * @author Josh Walters + */ +public class EmptyDatabase extends Exception { + + /** The serial ID */ + private static final long serialVersionUID = 7140054511201111418L; +} \ No newline at end of file diff --git a/src/com/joshwalters/bookcatalog/isbnlookup/GDataISBNLookup.java b/src/com/joshwalters/bookcatalog/isbnlookup/GDataISBNLookup.java new file mode 100644 index 0000000..dc670b3 --- /dev/null +++ b/src/com/joshwalters/bookcatalog/isbnlookup/GDataISBNLookup.java @@ -0,0 +1,158 @@ +/* + * Book Catalog - Catalog your book collection. + * + * Copyright (C) 2009 Joshua Walters + * URL: http://joshwalters.com + * + * This file is part of Book Catalog. + * + * Book Catalog is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Book Catalog is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Book Catalog. If not, see . + */ + +package com.joshwalters.bookcatalog.isbnlookup; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.List; + +import com.google.gdata.client.books.BooksService; +import com.google.gdata.client.books.VolumeQuery; +import com.google.gdata.data.books.VolumeEntry; +import com.google.gdata.data.books.VolumeFeed; +import com.google.gdata.data.dublincore.Creator; +import com.google.gdata.data.dublincore.Subject; +import com.google.gdata.data.dublincore.Title; +import com.google.gdata.util.ServiceException; + +/** + * Performs book lookup with GData. + * + * @author Josh Walters + */ +public class GDataISBNLookup extends ISBNLookup { + + /** + * Used for looking up the book. + */ + private BooksService service; + /** + * The URL for the Google volumes feed. + */ + public final String FEED_URL = "http://books.google.com/books/feeds/volumes"; + + /** + * Sets up the book service. + */ + public GDataISBNLookup() { + service = new BooksService("BookCatalog-1.0"); + } + + /** + * Searches for a book. + */ + public void searchBooks(String barcode) throws NoBookFound, + InvalidSearchTerms { + // Clear all the book data fields + emptyDataFields(); + // Purify the barcode, get the price if possible, and return just the + // ISBN + ISBN = purifyBarcode(barcode); + // Perform the query + VolumeQuery query; + try { + query = new VolumeQuery(new URL(FEED_URL)); + query.setFullTextQuery(ISBN); + // Only return one result + query.setMaxResults(1); + VolumeFeed volumeFeed = service.query(query, VolumeFeed.class); + // Process the result + processVolumeFeed(volumeFeed); + } catch (MalformedURLException e) { + // Print the error to the error stream + System.err.println(e.getMessage()); + } catch (IOException e) { + // Print the error to the error stream + System.err.println(e.getMessage()); + } catch (ServiceException e) { + // Print the error to the error stream + System.err.println(e.getMessage()); + } + } + + /** + * Processes the result feed to get the book data. + * + * @param volumeFeed + * @throws IOException + * @throws ServiceException + * @throws NoBookFound + */ + private void processVolumeFeed(VolumeFeed volumeFeed) throws IOException, + ServiceException, NoBookFound { + List volumeEntries = volumeFeed.getEntries(); + if (volumeEntries.size() == 0) { + throw new NoBookFound(); + } + // Send the data to be stored in the class + storeVolumeEntry(volumeEntries.get(0)); + } + + /** + * Store the data in the class variables. + * + * @param entry + * @throws IOException + * @throws ServiceException + */ + private void storeVolumeEntry(VolumeEntry entry) throws IOException, + ServiceException { + // Get the book title(s). + for (Title t : entry.getTitles()) { + if (title == null) { + title = t.getValue(); + } else { + title += ", " + t.getValue(); + } + } + // Get the book creator(s). + for (Creator c : entry.getCreators()) { + if (author == null) { + author = c.getValue(); + } else { + author += ", " + c.getValue(); + } + } + // Get the book date. + if (entry.getDates().size() > 0) { + date = entry.getDates().get(0).getValue(); + } + // Get the book description. + if (entry.getDescriptions().size() > 0) { + description = entry.getDescriptions().get(0).getValue(); + } + // Get the book subject(s). + for (Subject s : entry.getSubjects()) { + if (subject == null) { + subject = s.getValue(); + } else { + subject += ", " + s.getValue(); + } + } + // Get the book publisher. + if (entry.getPublishers().size() > 0) { + publisher = entry.getPublishers().get(0).getValue(); + } + } +} \ No newline at end of file diff --git a/src/com/joshwalters/bookcatalog/isbnlookup/ISBNLookup.java b/src/com/joshwalters/bookcatalog/isbnlookup/ISBNLookup.java new file mode 100644 index 0000000..92d31ff --- /dev/null +++ b/src/com/joshwalters/bookcatalog/isbnlookup/ISBNLookup.java @@ -0,0 +1,286 @@ +/* + * Book Catalog - Catalog your book collection. + * + * Copyright (C) 2009 Joshua Walters + * URL: http://joshwalters.com + * + * This file is part of Book Catalog. + * + * Book Catalog is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Book Catalog is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Book Catalog. If not, see . + */ + +package com.joshwalters.bookcatalog.isbnlookup; + +import java.util.regex.Pattern; + +/** + * Abstract class for performing an ISBN lookup for a book. + * + * @author Josh Walters + */ +public abstract class ISBNLookup { + + /** + * The title of the book. + */ + protected String title; + /** + * The author of the book. + */ + protected String author; + /** + * The publisher of the book. + */ + protected String publisher; + /** + * The date the book was published. + */ + protected String date; + /** + * The description of the book. + */ + protected String description; + /** + * The subject of the book. + */ + protected String subject; + /** + * The books ISBN number. + */ + protected String ISBN; + /** + * The price of the book. + */ + protected String price; + + /** + * Purifies the input barcode to make it suitable for use in lookup. Also + * grabs the price from the barcode if it is present. + * + * @param barcode + * @return A purified barcode. + * @throws InvalidSearchTerms + */ + protected String purifyBarcode(String barcode) throws InvalidSearchTerms { + // Remove the extra characters that some scanners include + barcode = removeCharInString(barcode, ' '); + barcode = removeCharInString(barcode, '-'); + // Check to see if the barcode is made up of numbers. + if (!Pattern.matches("^\\d*$", barcode)) { + throw new InvalidSearchTerms(); + } + // Check to see that the barcode is at least 4 digits long. + if (barcode.length() < 4) { + throw new InvalidSearchTerms(); + } + // ISBN-13 + if (barcode.substring(0, 3).compareTo("978") == 0 + || barcode.substring(0, 3).compareTo("979") == 0) { + if (barcode.length() == 15) { + barcode = barcode.substring(0, 13); + } + if (barcode.length() == 18) { + price = barcode.substring(13); + barcode = barcode.substring(0, 13); + } + } + // ISBN-10 + else { + if (barcode.length() == 12) { + barcode = barcode.substring(0, 10); + } + if (barcode.length() == 15) { + price = barcode.substring(10); + barcode = barcode.substring(0, 10); + } + } + if (price != null) { + // Format price information + if (price.charAt(1) == '0') { + price = price.substring(2); + price = "$" + price.substring(0, 1) + "." + price.substring(1); + } else { + price = price.substring(1); + price = "$" + price.substring(0, 2) + "." + price.substring(2); + } + } + // Check to make sure that this is the proper length for an ISBN number. + if (barcode.length() != 10 & barcode.length() != 13) { + throw new InvalidSearchTerms(); + } + return barcode; + } + + /** + * Clear out all the data fields. + */ + protected void emptyDataFields() { + title = null; + author = null; + publisher = null; + date = null; + description = null; + subject = null; + ISBN = null; + price = null; + return; + } + + /** + * Removes character from string. + * + * @param s + * @param c + * @return The new string. + */ + private String removeCharInString(String s, char c) { + String result = ""; + for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) != c) { + result += s.charAt(i); + } + } + return result; + } + + /** + * Searches for a book. + * + * @param barcode + * @throws NoBookFound + * @throws InvalidSearchTerms + */ + public abstract void searchBooks(String barcode) throws NoBookFound, + InvalidSearchTerms; + + /** + * @return the title + */ + public String getTitle() { + return title; + } + + /** + * @param title + * the title to set + */ + public void setTitle(String title) { + this.title = title; + } + + /** + * @return the author + */ + public String getAuthor() { + return author; + } + + /** + * @param author + * the author to set + */ + public void setAuthor(String author) { + this.author = author; + } + + /** + * @return the publisher + */ + public String getPublisher() { + return publisher; + } + + /** + * @param publisher + * the publisher to set + */ + public void setPublisher(String publisher) { + this.publisher = publisher; + } + + /** + * @return the date + */ + public String getDate() { + return date; + } + + /** + * @param date + * the date to set + */ + public void setDate(String date) { + this.date = date; + } + + /** + * @return the description + */ + public String getDescription() { + return description; + } + + /** + * @param description + * the description to set + */ + public void setDescription(String description) { + this.description = description; + } + + /** + * @return the subject + */ + public String getSubject() { + return subject; + } + + /** + * @param subject + * the subject to set + */ + public void setSubject(String subject) { + this.subject = subject; + } + + /** + * @return the ISBN + */ + public String getISBN() { + return ISBN; + } + + /** + * @param ISBN + * the ISBN to set + */ + public void setISBN(String ISBN) { + this.ISBN = ISBN; + } + + /** + * @return the price + */ + public String getPrice() { + return price; + } + + /** + * @param price + * the price to set + */ + public void setPrice(String price) { + this.price = price; + } +} \ No newline at end of file diff --git a/src/com/joshwalters/bookcatalog/isbnlookup/InvalidSearchTerms.java b/src/com/joshwalters/bookcatalog/isbnlookup/InvalidSearchTerms.java new file mode 100644 index 0000000..558cde1 --- /dev/null +++ b/src/com/joshwalters/bookcatalog/isbnlookup/InvalidSearchTerms.java @@ -0,0 +1,34 @@ +/* + * Book Catalog - Catalog your book collection. + * + * Copyright (C) 2009 Joshua Walters + * URL: http://joshwalters.com + * + * This file is part of Book Catalog. + * + * Book Catalog is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Book Catalog is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Book Catalog. If not, see . + */ + +package com.joshwalters.bookcatalog.isbnlookup; + +/** + * Thrown if the search terms are invalid. + * + * @author Josh Walters + */ +public class InvalidSearchTerms extends Exception { + + /** The serial ID */ + private static final long serialVersionUID = 8598966809541800761L; +} \ No newline at end of file diff --git a/src/com/joshwalters/bookcatalog/isbnlookup/NoBookFound.java b/src/com/joshwalters/bookcatalog/isbnlookup/NoBookFound.java new file mode 100644 index 0000000..1c909e0 --- /dev/null +++ b/src/com/joshwalters/bookcatalog/isbnlookup/NoBookFound.java @@ -0,0 +1,34 @@ +/* + * Book Catalog - Catalog your book collection. + * + * Copyright (C) 2009 Joshua Walters + * URL: http://joshwalters.com + * + * This file is part of Book Catalog. + * + * Book Catalog is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Book Catalog is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Book Catalog. If not, see . + */ + +package com.joshwalters.bookcatalog.isbnlookup; + +/** + * Thrown if the book is not found. + * + * @author Josh Walters + */ +public class NoBookFound extends Exception { + + /** The serial ID */ + private static final long serialVersionUID = -7276230896519983235L; +} \ No newline at end of file diff --git a/src/com/joshwalters/bookcatalog/sound/ErrorPlayingSound.java b/src/com/joshwalters/bookcatalog/sound/ErrorPlayingSound.java new file mode 100644 index 0000000..313de47 --- /dev/null +++ b/src/com/joshwalters/bookcatalog/sound/ErrorPlayingSound.java @@ -0,0 +1,34 @@ +/* + * Book Catalog - Catalog your book collection. + * + * Copyright (C) 2009 Joshua Walters + * URL: http://joshwalters.com + * + * This file is part of Book Catalog. + * + * Book Catalog is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Book Catalog is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Book Catalog. If not, see . + */ + +package com.joshwalters.bookcatalog.sound; + +/** + * Thrown if there was an error playing the sound. + * + * @author Josh Walters + */ +class ErrorPlayingSound extends Exception { + + /** The serial ID */ + private static final long serialVersionUID = 7400904062337176243L; +} \ No newline at end of file diff --git a/src/com/joshwalters/bookcatalog/sound/PlayWavSoundFile.java b/src/com/joshwalters/bookcatalog/sound/PlayWavSoundFile.java new file mode 100644 index 0000000..23d6a6f --- /dev/null +++ b/src/com/joshwalters/bookcatalog/sound/PlayWavSoundFile.java @@ -0,0 +1,78 @@ +/* + * Book Catalog - Catalog your book collection. + * + * Copyright (C) 2009 Joshua Walters + * URL: http://joshwalters.com + * + * This file is part of Book Catalog. + * + * Book Catalog is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Book Catalog is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Book Catalog. If not, see . + */ + +package com.joshwalters.bookcatalog.sound; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +import sun.audio.AudioPlayer; +import sun.audio.AudioStream; + +/** + * Plays a WAV file in a separate thread. This allows for very simple + * asynchronous WAV playback. + * + * @author Josh Walters + */ +public class PlayWavSoundFile extends Thread { + + /** + * The WAV file to be played. + */ + private String filename; + + /** + * Takes the file name of the WAV file to be played. + * + * @param wavfile + * The WAV file to be played. + */ + public PlayWavSoundFile(String wavfile) { + filename = wavfile; + } + + /** + * Plays the WAV file. First checks to see if the file is in a JAR with the + * program, then checks to see if it is present in a regular folder/file. + * Playback is asynchronous. + */ + public void run() { + try { + // Look for the WAV in a JAR + InputStream in = getClass().getClassLoader().getResourceAsStream( + filename); + // If not in JAR, check for regular file/folder + if (in == null) { + in = new FileInputStream(filename); + } + // Get the audio, and play it + AudioStream as = new AudioStream(in); + AudioPlayer.player.start(as); + } catch (IOException e) { + // Print the error to error output + System.err.println("Error loading and playing sound file: " + + filename); + } + } +} \ No newline at end of file diff --git a/src/com/joshwalters/bookcatalog/table/BookCatalogTableModel.java b/src/com/joshwalters/bookcatalog/table/BookCatalogTableModel.java new file mode 100644 index 0000000..8fe69ba --- /dev/null +++ b/src/com/joshwalters/bookcatalog/table/BookCatalogTableModel.java @@ -0,0 +1,103 @@ +/* + * Book Catalog - Catalog your book collection. + * + * Copyright (C) 2009 Joshua Walters + * URL: http://joshwalters.com + * + * This file is part of Book Catalog. + * + * Book Catalog is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Book Catalog is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Book Catalog. If not, see . + */ + +package com.joshwalters.bookcatalog.table; + +import java.sql.SQLException; + +import javax.swing.table.AbstractTableModel; + +import com.joshwalters.bookcatalog.bookdatabase.BookDatabase; +import com.joshwalters.bookcatalog.bookdatabase.EmptyDatabase; + +/** + * The custom table model for the table that will display the book database. + * + * @author Josh Walters + */ +public class BookCatalogTableModel extends AbstractTableModel { + + /** The serial ID */ + private static final long serialVersionUID = -3321121530039301264L; + /** The column names. */ + private String[] columnNames = { "Title", "Author", "Date", "Description", + "ISBN", "Price", "Publisher", "Subject", "Notes" }; + /** Stores the data that is displayed in the table */ + private String[][] data; + /** The SQL database that stores the book collection records. */ + BookDatabase bookDatabase; + + /** + * Populates the table with the info in the book database. + * + * @param bookDatabase + */ + public BookCatalogTableModel(BookDatabase bookDatabase) { + this.bookDatabase = bookDatabase; + try { + data = bookDatabase.getDatabaseForTable(); + } catch (SQLException e) { + // SQL error. + System.err.println(e.getLocalizedMessage()); + } catch (EmptyDatabase e) { + // Database was empty. + System.err.println(e.getLocalizedMessage()); + } + } + + /** + * Sets the data to be displayed. + * + * @param data + */ + public void setData(String[][] data) { + this.data = data; + } + + /** + * Return the number of columns. + */ + public int getColumnCount() { + return columnNames.length; + } + + /** + * Get the number of rows. + */ + public int getRowCount() { + return data.length; + } + + /** + * Get the name of a column. + */ + public String getColumnName(int col) { + return columnNames[col]; + } + + /** + * Get the value at a column. + */ + public String getValueAt(int row, int col) { + return data[row][col]; + } +} \ No newline at end of file -- cgit v1.2.3-24-g4f1b