aboutsummaryrefslogtreecommitdiff
path: root/src/uk/org/ury/library
diff options
context:
space:
mode:
Diffstat (limited to 'src/uk/org/ury/library')
-rw-r--r--src/uk/org/ury/library/LibraryRequestHandler.java144
-rw-r--r--src/uk/org/ury/library/LibraryUtils.java112
-rw-r--r--src/uk/org/ury/library/item/LibraryItem.java26
-rw-r--r--src/uk/org/ury/library/item/LibraryItemProperty.java62
-rw-r--r--src/uk/org/ury/library/viewer/LibraryTableModel.java184
-rw-r--r--src/uk/org/ury/library/viewer/LibraryViewer.java95
-rw-r--r--src/uk/org/ury/library/viewer/LibraryViewerPanel.java10
-rw-r--r--src/uk/org/ury/library/viewer/library_viewer_gui.xml12
8 files changed, 554 insertions, 91 deletions
diff --git a/src/uk/org/ury/library/LibraryRequestHandler.java b/src/uk/org/ury/library/LibraryRequestHandler.java
new file mode 100644
index 0000000..30bb7fc
--- /dev/null
+++ b/src/uk/org/ury/library/LibraryRequestHandler.java
@@ -0,0 +1,144 @@
+/**
+ *
+ */
+package uk.org.ury.library;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import uk.org.ury.database.DatabaseDriver;
+import uk.org.ury.database.UserClass;
+import uk.org.ury.database.exceptions.ConnectionFailureException;
+import uk.org.ury.database.exceptions.MissingCredentialsException;
+import uk.org.ury.database.exceptions.QueryFailureException;
+import uk.org.ury.library.exceptions.EmptySearchException;
+import uk.org.ury.library.item.LibraryItem;
+import uk.org.ury.server.Server;
+import uk.org.ury.server.RequestHandler;
+import uk.org.ury.server.exceptions.HandleFailureException;
+import uk.org.ury.server.protocol.Directive;
+
+/**
+ * A request handler for library queries.
+ *
+ * @author Matt Windsor
+ */
+
+public class LibraryRequestHandler implements RequestHandler
+{
+ /**
+ * Handle a server GET request (that is, a request for data
+ * output).
+ *
+ * @param parameters A key-value map of parameters supplied with
+ * the server request. Typically, the function
+ * parameter will detail the function that the
+ * request handler is expected to perform.
+ *
+ * @param server The server from which the request originated.
+ * This will be able to provide the handler with
+ * pooled resources, for example the database.
+ *
+ * @return A list of lines to return in the body of the
+ * server's response to the client.
+ *
+ * @throws HandleFailureException if the handler cannot
+ * handle the request.
+ */
+
+ @Override
+ public List<String>
+ handleGetRequest (Map<String, String> parameters, Server server)
+ throws HandleFailureException
+ {
+ List<String> response = new ArrayList<String> ();
+
+ if (parameters.containsKey ("function"))
+ {
+ String function = parameters.get ("function");
+
+ if (function.equals ("search"))
+ {
+ doSearch (parameters, response, server);
+ }
+ else if (function.equals ("help"))
+ {
+ response.add ("INFO: Available functions:");
+ response.add ("INFO: search (string) - search library for string.");
+ }
+ else
+ throw new HandleFailureException ("Unknown function: "
+ + function + ". (Try 'function=help'.)");
+
+ }
+ else
+ throw new HandleFailureException ("No function provided. (Try 'function=help'.)");
+
+ return response;
+ }
+
+
+ /**
+ * Perform a library search, populating the response list.
+ *
+ * @param parameters A key-value map of parameters supplied with
+ * the server request. Typically, the function
+ * parameter will detail the function that the
+ * request handler is expected to perform.
+ *
+ * @param response The response list to populate.
+ *
+ * @param server The server providing database resources.
+ *
+ * @throws HandleFailureException if an error occurs
+ * that thwarts the handling of the request.
+ */
+
+ private void
+ doSearch (Map<String, String> parameters,
+ List<String> response, Server server)
+ throws HandleFailureException
+ {
+ if (parameters.containsKey ("search") == false)
+ throw new HandleFailureException ("Search term is missing.");
+ else if (parameters.get ("search") == null)
+ throw new HandleFailureException ("Search term is null.");
+
+ String search = parameters.get ("search");
+ DatabaseDriver dd = null;
+
+ try
+ {
+ dd = server.getDatabaseConnection (UserClass.READ_ONLY);
+ }
+ catch (MissingCredentialsException e)
+ {
+ throw new HandleFailureException (e.getMessage ());
+ }
+ catch (ConnectionFailureException e)
+ {
+ throw new HandleFailureException (e.getMessage ());
+ }
+
+ try
+ {
+ for (LibraryItem li : LibraryUtils.search (dd, search))
+ {
+ response.add (Directive.ITEM_START.toString ());
+
+ response.addAll (li.asResponse ());
+
+ response.add (Directive.ITEM_END.toString ());
+ }
+ }
+ catch (QueryFailureException e)
+ {
+ throw new HandleFailureException (e.getMessage ());
+ }
+ catch (EmptySearchException e)
+ {
+ throw new HandleFailureException (e.getMessage ());
+ }
+ }
+}
diff --git a/src/uk/org/ury/library/LibraryUtils.java b/src/uk/org/ury/library/LibraryUtils.java
index a280738..8a71285 100644
--- a/src/uk/org/ury/library/LibraryUtils.java
+++ b/src/uk/org/ury/library/LibraryUtils.java
@@ -8,12 +8,16 @@ import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import java.util.Map;
import uk.org.ury.database.DatabaseDriver;
import uk.org.ury.database.exceptions.QueryFailureException;
-import uk.org.ury.library.LibraryItemProperty;
import uk.org.ury.library.exceptions.EmptySearchException;
+import uk.org.ury.library.item.LibraryItem;
+import uk.org.ury.library.item.LibraryItemProperty;
+import uk.org.ury.server.protocol.Directive;
/**
@@ -77,13 +81,9 @@ public class LibraryUtils
+ " 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, clean,"
- + " a.fname AS fnameadd, a.sname AS snameadd, b.fname AS fnameedit, b.sname AS snameedit"
+ + " shelfletter, shelfnumber, cdid, digitised, clean"
+ " 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 t.title ILIKE ?"
+ " OR t.artist ILIKE ?"
+ " OR r.title ILIKE ?"
@@ -126,7 +126,7 @@ public class LibraryUtils
{
// Translate SQL columns into a list of properties.
- HashMap<LibraryItemProperty, String> properties = new HashMap<LibraryItemProperty, String> ();
+ Map<LibraryItemProperty, String> properties = new HashMap<LibraryItemProperty, String> ();
for (LibraryItemProperty p : LibraryItemProperty.values ())
{
@@ -144,4 +144,102 @@ public class LibraryUtils
return new LibraryItem (properties);
}
+
+
+ /**
+ * Construct items from a server response body.
+ *
+ * @param response The list of strings that constitute the response.
+ *
+ * @return a list of LibraryItems corresponding to the item
+ * stanzas in the response.
+ */
+
+ public static List<LibraryItem>
+ extractItemsFromResponse (List<String> response)
+ {
+ List<LibraryItem> result = new ArrayList<LibraryItem> ();
+
+ boolean inItem = false;
+ List<String> itemBuffer = new ArrayList<String> ();
+
+ for (String line : response)
+ {
+ if (inItem == false)
+ {
+ if (line.startsWith (Directive.ITEM_START.toString ()))
+ {
+ inItem = true;
+ itemBuffer.clear ();
+ }
+ }
+
+ if (inItem == true)
+ {
+ itemBuffer.add (line);
+
+ if (line.startsWith (Directive.ITEM_END.toString ()))
+ {
+ inItem = false;
+ result.add (createItemFromResponse (itemBuffer));
+ }
+ }
+ }
+
+ return result;
+ }
+
+
+ /**
+ * Construct a new item from a server response fragment.
+ *
+ * @param response The list of strings that constitutes the response.
+ * The list must begin with Directive.ITEM_START and
+ * end with Directive.ITEM_END's string
+ * representations and otherwise contain solely
+ * Directive.ITEM_PROPERTY lines.
+ *
+ * @return a LibraryItem embodying the properties described
+ * in the response fragment.
+ *
+ * @throws IllegalArgumentException if the response is
+ * malformed or null, or if the instantiation of
+ * DatabaseItem does not use String as its data type.
+ */
+
+ public static LibraryItem
+ createItemFromResponse (List<String> response)
+ {
+ // TODO: More appropriate exceptions.
+
+ if (response == null)
+ throw new IllegalArgumentException ("Response is null.");
+ else if (response.get (0).equals (Directive.ITEM_START.toString ())
+ && response.get (response.size () - 1)
+ .equals (Directive.ITEM_END.toString ()))
+ {
+ // Response of size 2 must be blank.
+ if (response.size () <= 2)
+ throw new IllegalArgumentException ("Blank response.");
+
+ Map<LibraryItemProperty, String> properties = new HashMap<LibraryItemProperty, String> ();
+
+ for (int i = 0; i < response.size () - 1; i++)
+ {
+ // TODO: fan out impl. details to separate class
+ if (response.get (i)
+ .startsWith (Directive.ITEM_PROPERTY.toString ()))
+ {
+ String[] responseTuple = response.get (i).split (":=");
+
+ properties.put (LibraryItemProperty.getFromSQL (responseTuple[1]),
+ responseTuple[2]);
+ }
+ }
+
+ return new LibraryItem (properties);
+ }
+ else
+ throw new IllegalArgumentException ("Malformed response.");
+ }
}
diff --git a/src/uk/org/ury/library/item/LibraryItem.java b/src/uk/org/ury/library/item/LibraryItem.java
new file mode 100644
index 0000000..d2a790b
--- /dev/null
+++ b/src/uk/org/ury/library/item/LibraryItem.java
@@ -0,0 +1,26 @@
+/**
+ *
+ */
+package uk.org.ury.library.item;
+
+
+import java.util.Map;
+
+import uk.org.ury.database.DatabaseItem;
+
+
+/**
+ * An item in the URY library.
+ *
+ * @author Matt Windsor
+ */
+
+public class LibraryItem extends DatabaseItem<LibraryItemProperty,
+ String>
+{
+ public
+ LibraryItem (Map<LibraryItemProperty, String> properties)
+ {
+ super (properties);
+ }
+} \ No newline at end of file
diff --git a/src/uk/org/ury/library/item/LibraryItemProperty.java b/src/uk/org/ury/library/item/LibraryItemProperty.java
new file mode 100644
index 0000000..44f5f22
--- /dev/null
+++ b/src/uk/org/ury/library/item/LibraryItemProperty.java
@@ -0,0 +1,62 @@
+package uk.org.ury.library.item;
+
+/**
+ * The parameters that are stored in the LibraryItem.
+ *
+ * @author Matt Windsor
+ */
+
+public enum LibraryItemProperty
+ {
+ // Constant SQL identifier
+ TITLE ("title"),
+ ALBUM ("album"),
+ ARTIST ("artist"),
+ LABEL ("label"),
+ STATUS ("status"),
+ MEDIUM ("medium"),
+ FORMAT ("format"),
+ DATE_RELEASED ("datereleased"),
+ DATE_ADDED ("dateadded"),
+ DATE_EDITED ("dateedited"),
+ SHELF_LETTER ("shelfletter"),
+ SHELF_NUMBER ("shelfnumber"),
+ CD_ID ("cdid"),
+ IS_DIGITISED ("digitised"),
+ IS_CLEAN ("clean");
+
+
+ public final String sql;
+
+
+ private
+ LibraryItemProperty (String sql)
+ {
+ this.sql = sql;
+ }
+
+
+ /**
+ * Retrieve a LibraryItemProperty given its SQL identifier.
+ *
+ * @param string The SQL identifier.
+ * @return The first property to match.
+ *
+ * @throws IllegalArgumentException if no matches were
+ * found.
+ */
+
+ public static LibraryItemProperty
+ getFromSQL (String string)
+ {
+ // TODO: Better exception?
+
+ for (LibraryItemProperty prop : values ())
+ {
+ if (prop.sql.equals (string))
+ return prop;
+ }
+
+ throw new IllegalArgumentException ("Nonexistent property SQL.");
+ }
+ }; \ No newline at end of file
diff --git a/src/uk/org/ury/library/viewer/LibraryTableModel.java b/src/uk/org/ury/library/viewer/LibraryTableModel.java
new file mode 100644
index 0000000..1ce5709
--- /dev/null
+++ b/src/uk/org/ury/library/viewer/LibraryTableModel.java
@@ -0,0 +1,184 @@
+/**
+ *
+ */
+package uk.org.ury.library.viewer;
+
+import java.util.List;
+
+import javax.swing.table.AbstractTableModel;
+
+import uk.org.ury.database.exceptions.MissingPropertyException;
+import uk.org.ury.library.item.LibraryItem;
+import uk.org.ury.library.item.LibraryItemProperty;
+
+
+/**
+ * A table model for the library viewer.
+ *
+ * @author Matt Windsor
+ */
+
+public class LibraryTableModel extends AbstractTableModel
+{
+
+ /**
+ *
+ */
+
+ private static final long serialVersionUID = -1744980619128903509L;
+
+ private List<LibraryItem> data;
+
+
+ /**
+ * Construct a new table model.
+ *
+ * @param data The list of data on which the model will be based.
+ */
+
+ public
+ LibraryTableModel (List<LibraryItem> data)
+ {
+ this.data = data;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.swing.table.TableModel#getColumnCount()
+ */
+
+ @Override
+ public int
+ getColumnCount ()
+ {
+ return 6;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.swing.table.TableModel#getRowCount()
+ */
+
+ @Override
+ public int
+ getRowCount ()
+ {
+ return data.size ();
+ }
+
+
+ /**
+ * @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)
+ */
+
+ @Override
+ public Object
+ getValueAt (int rowIndex, int columnIndex)
+ {
+ LibraryItem li = data.get (rowIndex);
+
+ try
+ {
+ String[] columnData = {li.get (LibraryItemProperty.TITLE),
+ li.get (LibraryItemProperty.ARTIST),
+ li.get (LibraryItemProperty.ALBUM)};
+
+ switch (columnIndex)
+ {
+ default: // Title, artist, album, unknown
+
+ if (columnIndex >= columnData.length)
+ return "Unknown";
+ else
+ return columnData[columnIndex];
+
+ case 3: // Medium
+
+ // TODO: Make this less kludge-y
+
+ String mediumString = li.get (LibraryItemProperty.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: // Clean?
+
+ // Return true if marked true, false if marked false or unknown etc.
+
+ String cleanString = li.get (LibraryItemProperty.IS_CLEAN);
+
+ // TODO: Nicer way of showing this
+
+ if (cleanString.equals ("y"))
+ return "Yes";
+ else if (cleanString.equals ("n"))
+ return "No";
+ else
+ return "???";
+
+ case 5: // isDigitised
+
+ // Return true if marked true, false if marked false or unknown etc.
+
+ String digitisedString = li.get (LibraryItemProperty.IS_DIGITISED);
+
+ if (digitisedString.equals ("t"))
+ return true;
+ else
+ return false;
+ }
+ }
+ catch (MissingPropertyException e)
+ {
+ return "Unknown";
+ }
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.swing.table.TableModel#getColumnName(int, int)
+ */
+
+ @Override
+ public String
+ getColumnName (int index)
+ {
+ switch (index)
+ {
+ case 0:
+ return "Title";
+ case 1:
+ return "Artist";
+ case 2:
+ return "Album";
+ case 3:
+ return "Medium";
+ case 4:
+ return "Clean?";
+ case 5:
+ return "On system?";
+ default:
+ return "ERROR";
+ }
+ }
+}
diff --git a/src/uk/org/ury/library/viewer/LibraryViewer.java b/src/uk/org/ury/library/viewer/LibraryViewer.java
index a98fa54..9587d5e 100644
--- a/src/uk/org/ury/library/viewer/LibraryViewer.java
+++ b/src/uk/org/ury/library/viewer/LibraryViewer.java
@@ -1,27 +1,21 @@
package uk.org.ury.library.viewer;
-import java.lang.reflect.InvocationTargetException;
-
import java.util.ArrayList;
import java.util.List;
-import javax.swing.SwingUtilities;
-
import uk.org.ury.config.ConfigReader;
import uk.org.ury.database.DatabaseDriver;
import uk.org.ury.database.UserClass;
import uk.org.ury.database.exceptions.MissingCredentialsException;
import uk.org.ury.database.exceptions.QueryFailureException;
import uk.org.ury.frontend.AbstractFrontendModule;
-import uk.org.ury.frontend.FrontendError;
-import uk.org.ury.frontend.FrontendFrame;
import uk.org.ury.frontend.FrontendMaster;
import uk.org.ury.frontend.FrontendModulePanel;
-
-import uk.org.ury.library.LibraryItem;
+import uk.org.ury.frontend.exceptions.UICreationFailureException;
import uk.org.ury.library.LibraryUtils;
import uk.org.ury.library.exceptions.EmptySearchException;
+import uk.org.ury.library.item.LibraryItem;
public class LibraryViewer extends AbstractFrontendModule
{
@@ -33,7 +27,6 @@ public class LibraryViewer extends AbstractFrontendModule
private DatabaseDriver dd;
private List<LibraryItem> libraryList;
private LibraryViewerPanel panel;
- private FrontendFrame frame;
private ConfigReader config;
@@ -53,64 +46,9 @@ public class LibraryViewer extends AbstractFrontendModule
System.out.println(e);
}
- frame = null;
libraryList = new ArrayList<LibraryItem> ();
panel = null;
}
-
-
- /**
- * Initialise the library viewer frontend as an applet.
- */
-
- public void
- init ()
- {
- frame = null;
- libraryList = new ArrayList<LibraryItem> ();
- panel = null;
-
-
- try
- {
- SwingUtilities.invokeAndWait (new Runnable ()
- {
- public void
- run ()
- {
- panel.setOpaque (true);
- setContentPane (panel);
-
- runFrontend (null);
- }
-
- });
- }
- catch (InterruptedException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace ();
- }
- catch (InvocationTargetException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace ();
- }
- }
-
-
- /**
- * Run the library viewer frontend as an applet.
- */
-
- public void
- start ()
- {
- frame = null;
- panel = new LibraryViewerPanel (this, null);
-
- add (panel);
- }
/**
@@ -129,14 +67,22 @@ public class LibraryViewer extends AbstractFrontendModule
catch (MissingCredentialsException e)
{
// TODO: Privilege de-escalation
- FrontendError.reportFatal (e.getMessage (), frame);
+ master.fatalError (e.getMessage ());
}
catch (Exception f)
{
- FrontendError.reportFatal (f.getMessage (), frame);
+ master.fatalError (f.getMessage ());
}
- panel = new LibraryViewerPanel (this, master);
+ try
+ {
+ panel = new LibraryViewerPanel (this, master);
+ }
+ catch (UICreationFailureException e)
+ {
+ master.fatalError (e.getMessage ());
+ }
+
return panel;
}
@@ -152,19 +98,16 @@ public class LibraryViewer extends AbstractFrontendModule
*
* @throws EmptySearchException if the search string is
* empty or null (from LibraryUtils.search).
+ *
+ * @throws QueryFailureException if the search query
+ * fails (from LibraryUtils.search).
*/
public void
- doSearch (String search) throws EmptySearchException
+ doSearch (String search)
+ throws EmptySearchException, QueryFailureException
{
- try
- {
- libraryList = LibraryUtils.search (dd, search);
- }
- catch (QueryFailureException e)
- {
- FrontendError.reportFatal (e.getMessage (), frame);
- }
+ libraryList = LibraryUtils.search (dd, search);
}
diff --git a/src/uk/org/ury/library/viewer/LibraryViewerPanel.java b/src/uk/org/ury/library/viewer/LibraryViewerPanel.java
index 7638822..e453095 100644
--- a/src/uk/org/ury/library/viewer/LibraryViewerPanel.java
+++ b/src/uk/org/ury/library/viewer/LibraryViewerPanel.java
@@ -14,9 +14,10 @@ import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingWorker;
+import uk.org.ury.database.exceptions.QueryFailureException;
import uk.org.ury.frontend.FrontendMaster;
import uk.org.ury.frontend.FrontendModulePanel;
-import uk.org.ury.library.LibraryTableModel;
+import uk.org.ury.frontend.exceptions.UICreationFailureException;
import uk.org.ury.library.exceptions.EmptySearchException;
@@ -59,10 +60,13 @@ public class LibraryViewerPanel extends FrontendModulePanel
* @param viewer The LibraryViewer controlling this LibraryViewerPanel.
*
* @param master The FrontendMaster driving the frontend.
+ *
+ * @throws UICreationFailureException if the UI creation fails.
*/
public
LibraryViewerPanel (LibraryViewer viewer, FrontendMaster master)
+ throws UICreationFailureException
{
super (viewer, "library_viewer_gui.xml", master);
@@ -138,6 +142,10 @@ public class LibraryViewerPanel extends FrontendModulePanel
{
master.doSearch (searchField.getText ());
}
+ catch (QueryFailureException e)
+ {
+ searchFailureMessage = "Search failed: " + e.getMessage ();
+ }
catch (EmptySearchException e)
{
searchFailureMessage = "Please type in a search term.";
diff --git a/src/uk/org/ury/library/viewer/library_viewer_gui.xml b/src/uk/org/ury/library/viewer/library_viewer_gui.xml
index 6b7e745..5177e3f 100644
--- a/src/uk/org/ury/library/viewer/library_viewer_gui.xml
+++ b/src/uk/org/ury/library/viewer/library_viewer_gui.xml
@@ -1,13 +1,11 @@
<?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 constraints="BorderLayout.NORTH" border="EmptyBorder(5,5,5,5)">
+ <label text="Search for:" labelfor="searchField" displayedmnemonic="VK_F" />
<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" />
+ <button id="searchButton" text="Search" mnemonic="VK_S" action="search" />
</hbox>
<hbox constraints="BorderLayout.CENTER" border="EmptyBorder(0,5,0,5)">
@@ -16,14 +14,14 @@
</scrollpane>
<panel id="searchingPanel" constraints="BorderLayout.CENTER" visible="false"
layout="BorderLayout">
- <label id="searchingLabel" text="Searching..." font="Verdana-BOLD-16"
+ <label id="searchingLabel" text="Searching..."
constraints="BorderLayout.CENTER" horizontalalignment="CENTER" />
<progressbar id="searchingProgressBar" indeterminate="true"
constraints="BorderLayout.SOUTH" />
</panel>
<panel id="messagePanel" constraints="BorderLayout.CENTER" visible="false"
layout="BorderLayout">
- <label id="messageLabel" text="Searching..." font="Verdana-BOLD-16"
+ <label id="messageLabel" text="You shouldn't see this."
constraints="BorderLayout.CENTER" horizontalalignment="CENTER" />
</panel>
</hbox>