aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Windsor <mbw500@student.cs.york.ac.uk>2011-02-20 23:39:35 +0000
committerMatt Windsor <mbw500@student.cs.york.ac.uk>2011-02-20 23:39:35 +0000
commite2fc92f5c42dde942e8b71d38b9745b6f3c98053 (patch)
treed9d95332cee432390396bdc295d40a7ad5abe5ee
parent904caa25f8de49cc20823a25ce8051dfdcae7c26 (diff)
Use swixml instead of procedural UI generation; retrieve tracks as well as albums, including digitised status etc.
-rw-r--r--.classpath2
-rw-r--r--src/uk/org/ury/database/DatabaseDriver.java21
-rw-r--r--src/uk/org/ury/database/DatabaseLogin.java25
-rw-r--r--src/uk/org/ury/database/UserClass.java20
-rw-r--r--src/uk/org/ury/frontend/FrontendPanel.java4
-rw-r--r--src/uk/org/ury/frontend/HintField.java60
-rw-r--r--src/uk/org/ury/frontend/laf.xml25
-rw-r--r--src/uk/org/ury/library/LibraryItem.java4
-rw-r--r--src/uk/org/ury/library/LibraryTableModel.java53
-rw-r--r--src/uk/org/ury/library/LibraryUtils.java18
-rw-r--r--src/uk/org/ury/library/viewer/LibraryViewerPanel.java158
-rw-r--r--src/uk/org/ury/library/viewer/library_viewer_gui.xml22
12 files changed, 270 insertions, 142 deletions
diff --git a/.classpath b/.classpath
index 5d626e6..a922195 100644
--- a/.classpath
+++ b/.classpath
@@ -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>