diff options
author | Matt Windsor <mbw500@student.cs.york.ac.uk> | 2011-02-20 23:39:35 +0000 |
---|---|---|
committer | Matt Windsor <mbw500@student.cs.york.ac.uk> | 2011-02-20 23:39:35 +0000 |
commit | e2fc92f5c42dde942e8b71d38b9745b6f3c98053 (patch) | |
tree | d9d95332cee432390396bdc295d40a7ad5abe5ee | |
parent | 904caa25f8de49cc20823a25ce8051dfdcae7c26 (diff) |
Use swixml instead of procedural UI generation; retrieve tracks as well as albums, including digitised status etc.
-rw-r--r-- | .classpath | 2 | ||||
-rw-r--r-- | src/uk/org/ury/database/DatabaseDriver.java | 21 | ||||
-rw-r--r-- | src/uk/org/ury/database/DatabaseLogin.java | 25 | ||||
-rw-r--r-- | src/uk/org/ury/database/UserClass.java | 20 | ||||
-rw-r--r-- | src/uk/org/ury/frontend/FrontendPanel.java | 4 | ||||
-rw-r--r-- | src/uk/org/ury/frontend/HintField.java | 60 | ||||
-rw-r--r-- | src/uk/org/ury/frontend/laf.xml | 25 | ||||
-rw-r--r-- | src/uk/org/ury/library/LibraryItem.java | 4 | ||||
-rw-r--r-- | src/uk/org/ury/library/LibraryTableModel.java | 53 | ||||
-rw-r--r-- | src/uk/org/ury/library/LibraryUtils.java | 18 | ||||
-rw-r--r-- | src/uk/org/ury/library/viewer/LibraryViewerPanel.java | 158 | ||||
-rw-r--r-- | src/uk/org/ury/library/viewer/library_viewer_gui.xml | 22 |
12 files changed, 270 insertions, 142 deletions
@@ -3,5 +3,7 @@ <classpathentry kind="src" path="src"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> <classpathentry kind="lib" path="lib/postgresql-9.0-801.jdbc4.jar"/> + <classpathentry kind="lib" path="lib/swixml.jar"/> + <classpathentry kind="lib" path="lib/jdom.jar"/> <classpathentry kind="output" path="bin"/> </classpath> diff --git a/src/uk/org/ury/database/DatabaseDriver.java b/src/uk/org/ury/database/DatabaseDriver.java index 732714c..bd70c8f 100644 --- a/src/uk/org/ury/database/DatabaseDriver.java +++ b/src/uk/org/ury/database/DatabaseDriver.java @@ -46,29 +46,16 @@ public class DatabaseDriver */ public - DatabaseDriver (UserClass userclass) throws MissingCredentialsException, ConnectionFailureException + DatabaseDriver (UserClass userclass) + throws MissingCredentialsException, ConnectionFailureException { DatabaseLogin login = null; - switch (userclass) - { - case READ_ONLY: - login = DatabaseLogin.getLoginFromFile ("read_only.txt"); - break; - case READ_WRITE: - login = DatabaseLogin.getLoginFromFile ("read_write.txt"); - default: - throw new IllegalArgumentException ("Unused user class."); - } - - + login = DatabaseLogin.getLoginFromFile (userclass.configName + ".txt"); + try { - System.out.println ("Trying to acquire connection..."); - connect (login); - - System.out.println ("...connection succeeded."); } catch (SQLException e) { diff --git a/src/uk/org/ury/database/DatabaseLogin.java b/src/uk/org/ury/database/DatabaseLogin.java index e2f22bf..2afa6ce 100644 --- a/src/uk/org/ury/database/DatabaseLogin.java +++ b/src/uk/org/ury/database/DatabaseLogin.java @@ -35,6 +35,7 @@ public class DatabaseLogin * @param password The database password. * * @see getLoginFromFile + * @see getLoginFromConfig */ private @@ -126,6 +127,30 @@ public class DatabaseLogin return login; } + + /** + * Retrieve login credentials from the configuration file. + * + * @param configName The name of the tag in the configuration + * file containing the credentials. + * + * @return a new DatabaseLogin containing the information + * retrieved from the file. + * + * @throws IllegalArgumentException if the filename is + * null. + * + * @throws MissingCredentialsException if the tag or + * configuration file does not exist. + */ + + public static DatabaseLogin + getLoginFromConfig (String configName) + { + // TODO Auto-generated method stub + return null; + } + /** * @return the username. diff --git a/src/uk/org/ury/database/UserClass.java b/src/uk/org/ury/database/UserClass.java index 8f30952..79af61a 100644 --- a/src/uk/org/ury/database/UserClass.java +++ b/src/uk/org/ury/database/UserClass.java @@ -19,6 +19,22 @@ package uk.org.ury.database; public enum UserClass { - READ_ONLY, - READ_WRITE + // Constant configName + READ_ONLY ("read_only"), + READ_WRITE ("read_write"); + + + /** + * The name of the tag in the configuration file that contains + * the credentials for this user class. + */ + + public String configName; + + + private + UserClass (String configName) + { + this.configName = configName; + } } diff --git a/src/uk/org/ury/frontend/FrontendPanel.java b/src/uk/org/ury/frontend/FrontendPanel.java index e2e8c44..6012f22 100644 --- a/src/uk/org/ury/frontend/FrontendPanel.java +++ b/src/uk/org/ury/frontend/FrontendPanel.java @@ -15,6 +15,7 @@ import javax.swing.JPanel; * @author Matt Windsor * */ + public abstract class FrontendPanel extends JPanel { /** @@ -28,7 +29,4 @@ public abstract class FrontendPanel extends JPanel { super (); } - - public abstract String - getName (); } diff --git a/src/uk/org/ury/frontend/HintField.java b/src/uk/org/ury/frontend/HintField.java new file mode 100644 index 0000000..a43f1c3 --- /dev/null +++ b/src/uk/org/ury/frontend/HintField.java @@ -0,0 +1,60 @@ +/** + * + */ +package uk.org.ury.frontend; + + +import javax.swing.BorderFactory; +import javax.swing.JTextArea; + + +/** + * A non-editable text area displaying a hint about how to use a + * frontend screen. + * + * @author Matt Windsor + * + */ + +public class HintField extends JTextArea +{ + /** + * + */ + private static final long serialVersionUID = -6221888920919127273L; + + + /** + * Construct a new HintField with no initial hint. + */ + + public + HintField () + { + super (); + + setLineWrap (true); + setWrapStyleWord (true); + setEditable (false); + setOpaque (false); + } + + + /** + * Construct a new HintField. + * + * @param hint The hint to display in the HintField. + */ + + public + HintField (String hint) + { + super (hint); + + setLineWrap (true); + setWrapStyleWord (true); + setEditable (false); + setOpaque (false); + setBorder (BorderFactory.createEmptyBorder (5, 5, 5, 5)); + } +} diff --git a/src/uk/org/ury/frontend/laf.xml b/src/uk/org/ury/frontend/laf.xml new file mode 100644 index 0000000..651aba8 --- /dev/null +++ b/src/uk/org/ury/frontend/laf.xml @@ -0,0 +1,25 @@ +<synth> + <style id="backingStyle"> + <opaque value="TRUE" /> + + <font name="Verdana" size="14" /> + + <state> + <color value="BLACK" type="BACKGROUND" /> + <color value="WHITE" type="FOREGROUND" /> + </state> + </style> + + <bind style="backingStyle" type="region" key=".*" /> + + + <style id="buttonStyle"> + <state> + <color value="BLACK" type="BACKGROUND" /> + <color value="WHITE" type="FOREGROUND" /> + </state> + </style> + + <bind style="buttonStyle" type="region" key="button" /> +</synth> + diff --git a/src/uk/org/ury/library/LibraryItem.java b/src/uk/org/ury/library/LibraryItem.java index 593d1a5..f4283b0 100644 --- a/src/uk/org/ury/library/LibraryItem.java +++ b/src/uk/org/ury/library/LibraryItem.java @@ -25,6 +25,7 @@ public class LibraryItem { // Constant SQL identifier TITLE ("title"), + ALBUM ("album"), ARTIST ("artist"), LABEL ("label"), STATUS ("status"), @@ -41,7 +42,8 @@ public class LibraryItem ADD_FORENAME ("fnameadd"), ADD_SURNAME ("snameadd"), EDIT_FORENAME ("fnameedit"), - EDIT_SURNAME ("snameedit"); + EDIT_SURNAME ("snameedit"), + DIGITISED ("digitised"); public final String sql; diff --git a/src/uk/org/ury/library/LibraryTableModel.java b/src/uk/org/ury/library/LibraryTableModel.java index 6f55243..7883438 100644 --- a/src/uk/org/ury/library/LibraryTableModel.java +++ b/src/uk/org/ury/library/LibraryTableModel.java @@ -49,7 +49,7 @@ public class LibraryTableModel extends AbstractTableModel public int getColumnCount () { - return 3; + return 5; } @@ -65,6 +65,19 @@ public class LibraryTableModel extends AbstractTableModel } + /** + * @param c The column whose class should be investigated. + * + * @return the column class of column c. + */ + + @Override + public Class<?> + getColumnClass (int c) { + return getValueAt (0, c).getClass (); + } + + /* (non-Javadoc) * @see javax.swing.table.TableModel#getValueAt(int, int) */ @@ -78,10 +91,39 @@ public class LibraryTableModel extends AbstractTableModel { case 0: // Title return li.get (LibraryProperty.TITLE); + case 1: // Artist return li.get (LibraryProperty.ARTIST); - case 2: // Medium - return li.get (LibraryProperty.MEDIUM); + + case 2: // Album + return li.get (LibraryProperty.ALBUM); + + case 3: // Medium + + // TODO: Make this less kludge-y + + String mediumString = li.get (LibraryProperty.MEDIUM); + + if (mediumString.equals ("c")) + return "Compact Disc"; + else if (mediumString.equals ("7")) + return "7\" Vinyl"; + else if (mediumString.equals ("2")) + return "12\" Vinyl"; + else + return "Unrecognised"; + + case 4: // Digitised + + // Return true if marked true, false if marked false or unknown etc. + + String digitisedString = li.get (LibraryProperty.DIGITISED); + + if (digitisedString.equals ("t")) + return true; + else + return false; + default: return ""; } @@ -103,7 +145,12 @@ public class LibraryTableModel extends AbstractTableModel case 1: return "Artist"; case 2: + return "Album"; + case 3: return "Medium"; + case 4: + return "On system?"; + default: return "ERROR"; } diff --git a/src/uk/org/ury/library/LibraryUtils.java b/src/uk/org/ury/library/LibraryUtils.java index 0809d13..2843efa 100644 --- a/src/uk/org/ury/library/LibraryUtils.java +++ b/src/uk/org/ury/library/LibraryUtils.java @@ -28,11 +28,9 @@ public class LibraryUtils /** * Perform a library search. * - * Presently, the title and artist comparisons are logically ANDed. - * * @param db The database to query. * - * @param title The search fragment to include in the search. + * @param search The search fragment to include in the search. * Can be empty or null. * * @throws IllegalArgumentException if db, title or artist @@ -62,21 +60,27 @@ public class LibraryUtils ResultSet rs = null; List<LibraryItem> results = new ArrayList<LibraryItem> (); - Object[] params = {"%" + search + "%", "%" + search + "%"}; + Object[] params = {"%" + search + "%", "%" + search + "%", "%" + search + "%"}; try { rs = db.executeQuery ( - "SELECT title, artist, recordlabel AS label, status, media AS medium, format," + "SELECT r.title AS album, t.title," + + " t.artist, recordlabel AS label, status, media AS medium, format," + " datereleased, EXTRACT(EPOCH FROM dateadded) as dateadded," + " EXTRACT(EPOCH FROM datetime_lastedit) AS dateedited," + " shelfletter, shelfnumber, cdid, memberid_add, memberid_lastedit," + + " digitised," + " a.fname AS fnameadd, a.sname AS snameadd, b.fname AS fnameedit, b.sname AS snameedit" + " FROM rec_record AS r" + + " INNER JOIN rec_track AS t ON (r.recordid = t.recordid)" + " INNER JOIN member AS a ON (a.memberid = r.memberid_add)" + " LEFT JOIN member AS b ON (b.memberid = r.memberid_lastedit)" - + " WHERE title ILIKE ?" - + " OR artist ILIKE ?;", params, 50); + + " WHERE t.title ILIKE ?" + + " OR t.artist ILIKE ?" + + " OR r.title ILIKE ?" + + " ORDER BY digitised DESC, medium ASC, r.title ASC," + + " t.artist ASC, t.title ASC;", params, 50); } catch (SQLException e) { diff --git a/src/uk/org/ury/library/viewer/LibraryViewerPanel.java b/src/uk/org/ury/library/viewer/LibraryViewerPanel.java index cf2edfe..d6c2f79 100644 --- a/src/uk/org/ury/library/viewer/LibraryViewerPanel.java +++ b/src/uk/org/ury/library/viewer/LibraryViewerPanel.java @@ -3,28 +3,24 @@ */ package uk.org.ury.library.viewer; -import java.awt.BorderLayout; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import javax.swing.BorderFactory; -import javax.swing.GroupLayout; -import javax.swing.JButton; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JScrollPane; +import java.net.URL; + import javax.swing.JTable; -import javax.swing.JTextArea; import javax.swing.JTextField; -import javax.swing.SwingConstants; +import org.swixml.SwingEngine; + +import uk.org.ury.frontend.FrontendError; import uk.org.ury.frontend.FrontendPanel; +import uk.org.ury.frontend.HintField; import uk.org.ury.library.LibraryTableModel; + /** - * @author Matt Windsor + * Frontend panel providing access to an underlying library viewer. + * + * @author Matt Windsor, Nathan Lasseter */ public class LibraryViewerPanel extends FrontendPanel @@ -33,24 +29,34 @@ public class LibraryViewerPanel extends FrontendPanel * */ private static final long serialVersionUID = -2441616418398056712L; + + + /** + * Action method for performing a search, bound by the UI XML + * manifest to the search field and button + */ + + public void + search () + { + // TODO: SwingWorker? + + master.doSearch (searchField.getText ()); + + // This is necessary to force the table to update with the new results. + + resultsTable.setModel (new LibraryTableModel (master.getLibraryList ())); + } /* Controller of this panel. */ private LibraryViewer master; - /* Panel widgets. */ + /* Panel widgets exposed by the SwiXML user interface. */ - private LibraryTableModel resultsModel; private JTable resultsTable; - private JScrollPane resultsPane; - - private JLabel searchLabel; - private JTextField searchField; - private JButton searchButton; - - /** * Construct a new LibraryViewerPanel. * @@ -63,99 +69,33 @@ public class LibraryViewerPanel extends FrontendPanel super (); master = inMaster; + - setLayout (new BorderLayout ()); - - JPanel groupPanel = new JPanel (); - - GroupLayout layout = new GroupLayout (groupPanel); - - groupPanel.setLayout (layout); - - layout.setAutoCreateGaps (true); - layout.setAutoCreateContainerGaps (true); + URL path = getClass ().getResource ("library_viewer_gui.xml"); - searchLabel = new JLabel ("Search"); - searchLabel.setFont(new Font("Verdana", Font.BOLD, 14)); - - searchField = new JTextField (); + if (path == null) + throw new IllegalArgumentException ("XML file does not exist."); + + SwingEngine se = new SwingEngine (this); + se.getTaglib ().registerTag ("hint", HintField.class); - searchField.setPreferredSize (new Dimension (250, 25)); - searchField.setFont(new Font("Verdana", Font.BOLD, 14)); - searchLabel.setDisplayedMnemonic ('T'); - searchLabel.setLabelFor (searchField); - - searchButton = new JButton ("Search"); + /* The UI implementation is contained in library_viewer_gui.xml. + * + * It is hooked into the object resultsTable and the action + * method search. + * + * See the XML file for more details. + */ - searchField.addActionListener(new ActionListener() { - public void actionPerformed (ActionEvent event) { - master.doSearch (searchField.getText ()); - resultsTable.setModel (new LibraryTableModel (master.getLibraryList ())); - } - }); - - searchButton.addActionListener (new ActionListener () - { - public void - actionPerformed (ActionEvent event) + try { - master.doSearch (searchField.getText ()); - resultsTable.setModel (new LibraryTableModel (master.getLibraryList ())); + se.insert (path, this); + } + catch (Exception e) + { + FrontendError.reportFatal ("UI creation failure: " + e.getMessage (), null); } - }); - - - // Layout - - - layout.setHorizontalGroup - ( - layout.createSequentialGroup () - .addGroup (layout.createParallelGroup (GroupLayout.Alignment.LEADING) - .addComponent (searchLabel)) - .addGroup (layout.createParallelGroup (GroupLayout.Alignment.LEADING) - .addComponent (searchField)) - .addGroup (layout.createParallelGroup (GroupLayout.Alignment.LEADING) - .addComponent (searchButton)) - ); - - layout.setVerticalGroup - ( - layout.createSequentialGroup () - .addGroup (layout.createParallelGroup (GroupLayout.Alignment.LEADING) - .addComponent (searchLabel) - .addComponent (searchField) - .addComponent (searchButton)) - ); - - layout.linkSize (SwingConstants.HORIZONTAL, searchField); - layout.linkSize (SwingConstants.VERTICAL, searchField); - - add (groupPanel, BorderLayout.NORTH); - - - // Table - - resultsModel = new LibraryTableModel (master.getLibraryList ()); - resultsTable = new JTable (resultsModel); - - resultsPane = new JScrollPane (resultsTable); - - add (resultsPane, BorderLayout.CENTER); - - - // Explanation (TODO: Subclass?) - - JTextArea explanation = new JTextArea ("To narrow your search, type part or all of the record title or artist into the box above."); - - explanation.setLineWrap (true); - explanation.setWrapStyleWord (true); - explanation.setEditable (false); - explanation.setOpaque (false); - explanation.setBorder (BorderFactory.createEmptyBorder (5, 5, 5, 5)); - - add (explanation, BorderLayout.SOUTH); } diff --git a/src/uk/org/ury/library/viewer/library_viewer_gui.xml b/src/uk/org/ury/library/viewer/library_viewer_gui.xml new file mode 100644 index 0000000..2be08b8 --- /dev/null +++ b/src/uk/org/ury/library/viewer/library_viewer_gui.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<panel layout="BorderLayout"> + <hbox constraints="BorderLayout.NORTH" border="EmptyBorder(5,5,5,5)" size="640,32"> + <label text="Search for:" labelfor="searchField" displayedmnemonic="VK_F" + font="Verdana-BOLD-14" /> + <hbox border="EmptyBorder(0,5,0,5)"> + <textfield id="searchField" mnemonic="VK_F" action="search" /> + </hbox> + <button id="searchButton" text="Search" mnemonic="VK_S" action="search" + font="Verdana-BOLD-14" /> + </hbox> + + <hbox constraints="BorderLayout.CENTER" border="EmptyBorder(0,5,0,5)"> + <scrollpane id="resultsPane" constraints="BorderLayout.CENTER"> + <table id="resultsTable" /> + </scrollpane> + </hbox> + + <hbox constraints="BorderLayout.SOUTH" border="EmptyBorder(5,5,5,5)"> + <hint text="To narrow your search, type part or all of the record title or artist into the box above." /> + </hbox> +</panel> |