diff options
Diffstat (limited to 'src')
32 files changed, 1814 insertions, 280 deletions
diff --git a/src/uk/org/ury/database/DatabaseItem.java b/src/uk/org/ury/database/DatabaseItem.java new file mode 100644 index 0000000..4f6d34d --- /dev/null +++ b/src/uk/org/ury/database/DatabaseItem.java @@ -0,0 +1,70 @@ +package uk.org.ury.database; + +import java.util.Map; + +import uk.org.ury.database.exceptions.MissingPropertyException; + + +/** + * An abstract class presenting a template for objects serving as + * a data structure for collections of properties retrieved from + * a SQL database. + * + * @param E The enumeration type used as the property list. + * + * @param T The type of datum stored for each property. + * + * @author Matt Windsor + */ + +public abstract class DatabaseItem<E, T> +{ + private Map<E, T> properties; + + /** + * Construct a new item from an existing list of properties. + * + * @param properties The map of properties that the new item will + * inherit. + */ + + public + DatabaseItem (Map<E, T> properties) + { + this.properties = properties; + } + + + /** + * Check whether a property has been set in the item. + * + * @return true if the property has been set; false otherwise. + */ + + public boolean + has (E property) + { + return properties.containsKey (property); + } + + + /** + * Query this item for a property. + * + * @param property The property to query. + * + * @return The property, if it exists. + * + * @throws MissingPropertyException if the property does + * not exist. + */ + + public T + get (E property) throws MissingPropertyException + { + if (properties.containsKey (property)) + return properties.get (property); + else + throw new MissingPropertyException (property.toString ()); + } +} diff --git a/src/uk/org/ury/database/exceptions/MissingPropertyException.java b/src/uk/org/ury/database/exceptions/MissingPropertyException.java new file mode 100644 index 0000000..3766fcf --- /dev/null +++ b/src/uk/org/ury/database/exceptions/MissingPropertyException.java @@ -0,0 +1,47 @@ +/** + * + */ +package uk.org.ury.database.exceptions; + + +/** + * Exception thrown when a DatabaseItem is queried for a property + * that does not exist. + * + * This is (usually) not a fatal error. + * + * @author Matt Windsor + */ + +public class MissingPropertyException extends Exception +{ + /** + * + */ + private static final long serialVersionUID = -7353531873142099828L; + + +/** + * Construct a new MissingPropertyException with a + * default reason. + */ + + public + MissingPropertyException () + { + super ("Query failure."); + } + + + /** + * Construct a new MissingPropertyException. + * + * @param reason The explanation for the exception. + */ + + public + MissingPropertyException (String reason) + { + super (reason); + } +} diff --git a/src/uk/org/ury/database/exceptions/QueryFailureException.java b/src/uk/org/ury/database/exceptions/QueryFailureException.java index d7b3e5b..5293a7c 100644 --- a/src/uk/org/ury/database/exceptions/QueryFailureException.java +++ b/src/uk/org/ury/database/exceptions/QueryFailureException.java @@ -3,6 +3,7 @@ */ package uk.org.ury.database.exceptions; + /** * Exception thrown when the database backend fails to execute * a query. diff --git a/src/uk/org/ury/frontend/FrontendBanner.java b/src/uk/org/ury/frontend/FrontendBanner.java new file mode 100644 index 0000000..f3ce502 --- /dev/null +++ b/src/uk/org/ury/frontend/FrontendBanner.java @@ -0,0 +1,68 @@ +package uk.org.ury.frontend; + +import java.awt.Color; +import java.awt.FlowLayout; + +import javax.swing.BorderFactory; +import javax.swing.ImageIcon; +import javax.swing.JLabel; +import javax.swing.JPanel; + + +/** + * A banner, displaying a title, intended for use at the top of the + * frontend frame. + * + * @author Matt Windsor + */ + +public class FrontendBanner extends JPanel +{ + /** + * + */ + private static final long serialVersionUID = -3636933349004358394L; + + private static final String TITLE_PREFIX = "<html><h1><font color=white>"; + private static final String TITLE_SUFFIX = "</font></h1></html>"; + + private JLabel titleLabel; + + + /** + * Construct a new banner. + * + * @param title The initial title to display in the banner. + */ + + public + FrontendBanner (String title) + { + setLayout (new FlowLayout (FlowLayout.LEFT)); + setBackground (new Color (0, 0, 0)); + + + JLabel logo = new JLabel (new ImageIcon (getClass ().getResource ("images/ury.png"))); + + + titleLabel = new JLabel (TITLE_PREFIX + title + TITLE_SUFFIX); + titleLabel.setBorder (BorderFactory.createEmptyBorder (5, 15, 5, 5)); + + + add (logo); + add (titleLabel); + } + + + /** + * Change the title displayed on the banner. + * + * @param title The new title to display. + */ + + public void + setTitle (String title) + { + titleLabel.setText (TITLE_PREFIX + title + TITLE_SUFFIX); + } +} diff --git a/src/uk/org/ury/frontend/FrontendControlPanel.java b/src/uk/org/ury/frontend/FrontendControlPanel.java new file mode 100644 index 0000000..5b7f486 --- /dev/null +++ b/src/uk/org/ury/frontend/FrontendControlPanel.java @@ -0,0 +1,97 @@ +/** + * + */ +package uk.org.ury.frontend; + + +/** + * Abstract class for frontend module control panels. + * + * Control panels are installed as a means of exposing module + * intercommunication to the user. For example, when the library + * viewer is launched from the playout module, a control panel + * is installed allowing the user to add library items to the + * playout system. + * + * @author Matt Windsor + */ + +public abstract class FrontendControlPanel extends FrontendPanel +{ + /** + * + */ + private static final long serialVersionUID = -5628250552779928189L; + + protected FrontendControlPanel prevCPanel; + protected FrontendModulePanel parent; + protected FrontendModulePanel child; + + + /** + * Alternative constructor allowing an XML file to be used to + * create the layout of the ControlPanel. + * + * This is provided for the benefit of subclasses of this class + * that use it in their default constructors. + * + * @param xmlPath The path, relative from this source file, to the + * XML file from which this panel will read its + * layout. + */ + + public + FrontendControlPanel (String xmlPath) + { + super (xmlPath, null); + } + + + /** + * Set the frontend master to which this panel is bound. + * + * @param master The master to set. + */ + + public void + setMaster (FrontendMaster master) + { + this.master = master; + } + + + /** + * Set the parent and child panels that this ControlPanel + * facilitates intercommunication. + * + * @param parent The panel belonging to the parent module, + * or the module that was switched out in place of + * the child. + * + * @param child The panel belonging to the child module, + * or the module that was switched in in place of + * the parent. + */ + + public void + setPanels (FrontendModulePanel parent, FrontendModulePanel child) + { + this.parent = parent; + this.child = child; + } + + + /** + * Set the previous control panel (if any), so that it can be + * restored when this control panel returns control to the + * parent. + * + * @param cpanel The previous control panel. + */ + + public void + setPreviousCPanel (FrontendControlPanel cpanel) + { + prevCPanel = cpanel; + } +} diff --git a/src/uk/org/ury/frontend/FrontendFrame.java b/src/uk/org/ury/frontend/FrontendFrame.java index 6324512..ef2a31a 100644 --- a/src/uk/org/ury/frontend/FrontendFrame.java +++ b/src/uk/org/ury/frontend/FrontendFrame.java @@ -4,26 +4,20 @@ package uk.org.ury.frontend; import java.awt.BorderLayout; -import java.awt.Color; import java.awt.Container; import java.awt.Dimension; -import java.awt.FlowLayout; -import javax.swing.BorderFactory; -import javax.swing.ImageIcon; import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JPanel; /** - * A frame that hosts a FrontendPanel, used for serving frontend + * A frame that hosts a FrontendModulePanel, used for serving frontend * panels in a window (application mode). * * @author Matt Windsor * */ -public class FrontendFrame extends JFrame +public class FrontendFrame extends JFrame implements FrontendMaster { /** * @@ -31,31 +25,24 @@ public class FrontendFrame extends JFrame private static final long serialVersionUID = 740928181256928433L; - private FrontendPanel parent; + private FrontendBanner banner; + private FrontendModulePanel child; + private FrontendControlPanel cpanel; public - FrontendFrame (FrontendPanel parent) + FrontendFrame (FrontendModulePanel parent) { super (parent.getName ()); setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); - this.parent = parent; + this.child = parent; Container cp = getContentPane (); // Banner - JPanel banner = new JPanel (); - JLabel bannerLabel = new JLabel ("<html><h1><font color=white>" - + parent.getName () + "</font></h1></html>"); - - bannerLabel.setBorder (BorderFactory.createEmptyBorder (5, 15, 5, 5)); - - banner.setLayout (new FlowLayout (FlowLayout.LEFT)); - banner.setBackground (new Color (0, 0, 0)); - banner.add (new JLabel (new ImageIcon (getClass ().getResource ("images/ury.png")))); - banner.add (bannerLabel); + banner = new FrontendBanner (parent.getName ()); // Composition @@ -67,4 +54,180 @@ public class FrontendFrame extends JFrame pack (); setVisible (true); } + + + /** + * Load a module into the frontend frame. + * + * Loading will fail with a fatal error if the class is not found, + * or is not an implementor of FrontendModule. + * + * @param moduleName The fully qualified class-name of the module, + * minus the leading "uk.org.ury." domain. + */ + + @Override + public void + loadModule (String moduleName) + { + Class<?> moduleClass = null; + + try + { + moduleClass = Class.forName ("uk.org.ury." + moduleName); + } + catch (ClassNotFoundException e) + { + FrontendError.reportFatal ("Could not load module: " + e.getMessage (), this); + } + + + if (FrontendModule.class.isAssignableFrom (moduleClass)) + { + FrontendModulePanel temp = child; + + try + { + child = ((FrontendModule) moduleClass.newInstance ()).runFrontend (this); + } + catch (InstantiationException e) + { + FrontendError.reportFatal ("Could not load module: " + e.getMessage (), this); + } + catch (IllegalAccessException e) + { + FrontendError.reportFatal ("Could not load module: " + e.getMessage (), this); + } + + remove (temp); + add (child); + + banner.setTitle (child.getName ()); + pack (); + } + } + + + /** + * Load a module into the frontend frame, additionally installing + * a control panel to communicate with the previous module. + * + * Loading will fail with a fatal error if the class is not found, + * or is not an implementor of FrontendModule. + * + * @param moduleName The fully qualified class-name of the module, + * minus the leading "uk.org.ury." domain. + * + * @param cPanelName The fully qualified class-name of the control + * panel to install, minus the leading + * "uk.org.ury." domain. + */ + + @Override + public void + loadModule (String moduleName, String cPanelName) + { + FrontendModulePanel newParent = child; + loadModule (moduleName); + FrontendModulePanel newChild = child; + + loadControlPanel (cPanelName, newParent, newChild); + } + + + /** + * Load and install a control panel class given the class name. + * + * @param cPanelName The fully qualified class-name of the control + * panel to load, minus the leading + * "uk.org.ury." domain. + * + * @param parent The parent panel in the relationship modelled + * by the control panel interface. + * + * @param child The child panel in the relationship modelled + * by the control panel interface. + */ + + private void + loadControlPanel (String cPanelName, FrontendModulePanel parent, + FrontendModulePanel child) + { + Class<?> cPanelClass = null; + + try + { + cPanelClass = Class.forName ("uk.org.ury." + cPanelName); + } + catch (ClassNotFoundException e) + { + FrontendError.reportFatal ("Could not load control panel: " + e.getMessage (), this); + } + + + if (FrontendControlPanel.class.isAssignableFrom (cPanelClass)) + { + FrontendControlPanel temp = cpanel; + + try + { + cpanel = ((FrontendControlPanel) cPanelClass.newInstance ()); + } + catch (InstantiationException e) + { + FrontendError.reportFatal ("Could not load module: " + e.getMessage (), this); + } + catch (IllegalAccessException e) + { + FrontendError.reportFatal ("Could not load module: " + e.getMessage (), this); + } + + if (temp != null) + remove (temp); + + cpanel.setPanels (parent, child); + cpanel.setMaster (this); + cpanel.setPreviousCPanel (temp); + + add (cpanel, BorderLayout.SOUTH); + pack (); + } + } + + + /** + * Restore an existing module and control panel into the frontend + * frame. + * + * @param mpanel The module panel to restore. + * + * @param cpanel The control panel to restore, if any. A null + * value signifies a lack of control panel. + * + * @throws IllegalArgumentException if the mpanel is null. + */ + + @Override + public void + restoreModule (FrontendModulePanel mpanel, + FrontendControlPanel cpanel) + { + if (mpanel == null) + throw new IllegalArgumentException ("mpanel is null."); + + remove (child); + remove (this.cpanel); + + child = mpanel; + add (child); + banner.setTitle (child.getName ()); + + if (cpanel != null) + add (cpanel, BorderLayout.SOUTH); + + this.cpanel = cpanel; + + pack (); + repaint (); + } } diff --git a/src/uk/org/ury/frontend/FrontendMaster.java b/src/uk/org/ury/frontend/FrontendMaster.java new file mode 100644 index 0000000..c169d04 --- /dev/null +++ b/src/uk/org/ury/frontend/FrontendMaster.java @@ -0,0 +1,65 @@ +/** + * + */ +package uk.org.ury.frontend; + + +/** + * Interface for classes providing the parent unit of a frontend + * session. + * + * This includes the FrontendFrame used in application mode as + * well as applets. + * + * @author Matt Windsor + */ + +public interface FrontendMaster +{ + /** + * Load a module into the frontend frame. + * + * Loading will fail with a fatal error if the class is not found, + * or is not an implementor of FrontendModule. + * + * @param moduleName The fully qualified class-name of the module, + * minus the leading "uk.org.ury." domain. + */ + + public void + loadModule (String moduleName); + + + /** + * Load a module into the frontend frame, additionally installing + * a control panel to communicate with the previous module. + * + * Loading will fail with a fatal error if the class is not found, + * or is not an implementor of FrontendModule. + * + * @param moduleName The fully qualified class-name of the module, + * minus the leading "uk.org.ury." domain. + * + * @param cpanelName The fully qualified class-name of the control + * panel to install, minus the leading + * "uk.org.ury." domain. + */ + + public void + loadModule (String moduleName, String cPanelName); + + + /** + * Restore an existing module and control panel into the frontend + * master. + * + * @param mpanel The module panel to restore. + * + * @param cpanel The control panel to restore. + * + * @throws IllegalArgumentException if either are null. + */ + + public void + restoreModule (FrontendModulePanel mpanel, FrontendControlPanel cpanel); +} diff --git a/src/uk/org/ury/frontend/FrontendModule.java b/src/uk/org/ury/frontend/FrontendModule.java index 407b2db..4d1e3bf 100644 --- a/src/uk/org/ury/frontend/FrontendModule.java +++ b/src/uk/org/ury/frontend/FrontendModule.java @@ -11,7 +11,7 @@ package uk.org.ury.frontend; * * - be runnable standalone, as either an application or an applet; * - * - contain their user interface in a subclass of FrontendPanel + * - contain their user interface in a subclass of FrontendModulePanel * which can be embedded either in a FrontendFrame, a web page * or another module; * @@ -27,5 +27,15 @@ package uk.org.ury.frontend; public interface FrontendModule { - // Space for rent + /** + * Begin execution of the frontend module. + * + * @param master The FrontendMaster driving the frontend. + * + * @return the frontend panel to insert into the + * FrontendMaster. + */ + + public FrontendModulePanel + runFrontend (FrontendMaster master); } diff --git a/src/uk/org/ury/frontend/FrontendModulePanel.java b/src/uk/org/ury/frontend/FrontendModulePanel.java new file mode 100644 index 0000000..148875f --- /dev/null +++ b/src/uk/org/ury/frontend/FrontendModulePanel.java @@ -0,0 +1,90 @@ +/** + * + */ +package uk.org.ury.frontend; + + +/** + * A frontend user interface panel. + * + * All frontend user interfaces should subclass this as their main + * interface space, so that frontend panels can include each other + * and panels can be embedded into application frames or applets. + * + * @author Matt Windsor + * + */ + +public abstract class FrontendModulePanel extends FrontendPanel +{ + /** + * + */ + + private static final long serialVersionUID = 5616222530691425635L; + + private FrontendModule module; + + + /** + * Construct a new, blank FrontendModulePanel. + * + * @param module the module that the panel is viewing. + * + * @param master The FrontendMaster driving the frontend. + */ + + public + FrontendModulePanel (FrontendModule module, FrontendMaster master) + { + super (master); + this.module = module; + } + + + /** + * Construct a FrontendModulePanel using an XML layout manifest. + * + * @param module the module that the panel is viewing. + * + * @param xmlPath The path, relative from this source file, to the + * XML file from which this panel will read its + * layout. + * + * @param master The FrontendMaster driving the frontend. + */ + + public + FrontendModulePanel (FrontendModule module, String xmlPath, + FrontendMaster master) + { + super (xmlPath, master); + this.module = module; + } + + + /** + * @return the name of the panel module. + */ + + public abstract String + getName (); + + + /** + * Retrieve the module that this panel is serving as a view into. + * + * @return the module. + */ + + public FrontendModule + getModule () + { + return module; + } + + + /** + * + */ +} diff --git a/src/uk/org/ury/frontend/FrontendPanel.java b/src/uk/org/ury/frontend/FrontendPanel.java index 6012f22..1617ab0 100644 --- a/src/uk/org/ury/frontend/FrontendPanel.java +++ b/src/uk/org/ury/frontend/FrontendPanel.java @@ -1,32 +1,90 @@ -/** - * - */ package uk.org.ury.frontend; +import java.net.URL; + import javax.swing.JPanel; +import org.swixml.SwingEngine; + + /** - * A frontend user interface panel. + * An extension of JPanel providing common functionality for user + * interface panels in the URY system frontend. * - * All frontend user interfaces should subclass this as their main - * interface space, so that frontend panels can include each other - * and panels can be embedded into application frames or applets. - * - * @author Matt Windsor + * @author Matt Windsor * */ -public abstract class FrontendPanel extends JPanel +public class FrontendPanel extends JPanel { /** * */ - - private static final long serialVersionUID = 5616222530691425635L; + private static final long serialVersionUID = -4481079599056565279L; + protected FrontendMaster master; + + /** + * Construct a new, blank FrontendPanel. + * + * @param master The FrontendMaster driving the frontend. + */ + public - FrontendPanel () + FrontendPanel (FrontendMaster master) { super (); + + this.master = master; + } + + + /** + * Construct a new FrontendPanel from an XML layout. + * + * This is the preferred means of constructing FrontendPanels, and + * uses SWIXml to construct the panel layout. + * + * @param xmlPath The path, relative from this source file, to the + * XML file from which this panel will read its + * layout. + * + * @param master The FrontendMaster driving the frontend. + */ + + public + FrontendPanel (String xmlPath, FrontendMaster master) + { + super (); + + this.master = master; + + + // Acquire path. + + URL path = getClass ().getResource (xmlPath); + + if (path == null) + FrontendError.reportFatal ("UI creation failure: XML layout " + + xmlPath + " does not exist.", null); + + SwingEngine se = new SwingEngine (this); + + + // Custom UI element tag registration. + + se.getTaglib ().registerTag ("hint", HintField.class); + + + // Read the XML. + + try + { + se.insert (path, this); + } + catch (Exception e) + { + FrontendError.reportFatal ("UI creation failure: " + e.getMessage (), null); + } } } diff --git a/src/uk/org/ury/frontend/images/ury.png b/src/uk/org/ury/frontend/images/ury.png Binary files differindex f71a461..b1f85a1 100644 --- a/src/uk/org/ury/frontend/images/ury.png +++ b/src/uk/org/ury/frontend/images/ury.png diff --git a/src/uk/org/ury/library/LibraryItem.java b/src/uk/org/ury/library/LibraryItem.java index 881f840..6156bab 100644 --- a/src/uk/org/ury/library/LibraryItem.java +++ b/src/uk/org/ury/library/LibraryItem.java @@ -6,6 +6,9 @@ package uk.org.ury.library; import java.util.Map; +import uk.org.ury.database.DatabaseItem; +import uk.org.ury.library.LibraryItemProperty; + /** * An item in the URY library. @@ -13,81 +16,12 @@ import java.util.Map; * @author Matt Windsor */ -public class LibraryItem +public class LibraryItem extends DatabaseItem<LibraryItemProperty, + String> { - /** - * The parameters that are stored in the LibraryItem. - * - * @author Matt Windsor - */ - - public enum LibraryProperty - { - // 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"), - ADD_MEMBER_ID ("memberid_add"), - EDIT_MEMBER_ID ("memberid_lastedit"), - ADD_FORENAME ("fnameadd"), - ADD_SURNAME ("snameadd"), - EDIT_FORENAME ("fnameedit"), - EDIT_SURNAME ("snameedit"), - IS_DIGITISED ("digitised"), - IS_CLEAN ("clean"); - - - public final String sql; - - private - LibraryProperty (String sql) - { - this.sql = sql; - } - }; - - - private Map<LibraryProperty, String> properties; - - - /** - * Construct a new library item from an existing list of - * properties. - * - * @param properties The map of properties that the new item will - * inherit. - */ - public - LibraryItem (Map<LibraryProperty, String> properties) - { - this.properties = properties; - } - - - /** - * Query this item for a property. - * - * @param property The property to query. - * @return The property, if it exists, or "Unknown" otherwise. - */ - - public String - get (LibraryProperty property) + LibraryItem (Map<LibraryItemProperty, String> properties) { - if (properties.containsKey (property)) - return properties.get (property); - else - return "Unknown"; - } -} + super (properties); + } +}
\ No newline at end of file diff --git a/src/uk/org/ury/library/LibraryItemProperty.java b/src/uk/org/ury/library/LibraryItemProperty.java new file mode 100644 index 0000000..154e405 --- /dev/null +++ b/src/uk/org/ury/library/LibraryItemProperty.java @@ -0,0 +1,43 @@ +package uk.org.ury.library; + +/** + * 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"), + ADD_MEMBER_ID ("memberid_add"), + EDIT_MEMBER_ID ("memberid_lastedit"), + ADD_FORENAME ("fnameadd"), + ADD_SURNAME ("snameadd"), + EDIT_FORENAME ("fnameedit"), + EDIT_SURNAME ("snameedit"), + IS_DIGITISED ("digitised"), + IS_CLEAN ("clean"); + + + public final String sql; + + + private + LibraryItemProperty (String sql) + { + this.sql = sql; + } + };
\ No newline at end of file diff --git a/src/uk/org/ury/library/LibraryTableModel.java b/src/uk/org/ury/library/LibraryTableModel.java index c648520..f380274 100644 --- a/src/uk/org/ury/library/LibraryTableModel.java +++ b/src/uk/org/ury/library/LibraryTableModel.java @@ -7,7 +7,8 @@ import java.util.List; import javax.swing.table.AbstractTableModel; -import uk.org.ury.library.LibraryItem.LibraryProperty; +import uk.org.ury.database.exceptions.MissingPropertyException; +import uk.org.ury.library.LibraryItemProperty; /** @@ -88,60 +89,67 @@ public class LibraryTableModel extends AbstractTableModel { LibraryItem li = data.get (rowIndex); - switch (columnIndex) + try + { + switch (columnIndex) + { + case 0: // Title + return li.get (LibraryItemProperty.TITLE); + + case 1: // Artist + return li.get (LibraryItemProperty.ARTIST); + + case 2: // Album + return li.get (LibraryItemProperty.ALBUM); + + 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; + + default: + return ""; + } + } + catch (MissingPropertyException e) { - case 0: // Title - return li.get (LibraryProperty.TITLE); - - case 1: // Artist - return li.get (LibraryProperty.ARTIST); - - 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: // Clean? - - // Return true if marked true, false if marked false or unknown etc. - - String cleanString = li.get (LibraryProperty.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 (LibraryProperty.IS_DIGITISED); - - if (digitisedString.equals ("t")) - return true; - else - return false; - - default: - return ""; + return "Unknown"; } } diff --git a/src/uk/org/ury/library/LibraryUtils.java b/src/uk/org/ury/library/LibraryUtils.java index 1c69004..a280738 100644 --- a/src/uk/org/ury/library/LibraryUtils.java +++ b/src/uk/org/ury/library/LibraryUtils.java @@ -12,7 +12,7 @@ import java.util.List; import uk.org.ury.database.DatabaseDriver; import uk.org.ury.database.exceptions.QueryFailureException; -import uk.org.ury.library.LibraryItem.LibraryProperty; +import uk.org.ury.library.LibraryItemProperty; import uk.org.ury.library.exceptions.EmptySearchException; @@ -99,31 +99,49 @@ public class LibraryUtils { while (rs.next ()) { - // Translate SQL columns into a list of properties. - - HashMap<LibraryProperty, String> properties = new HashMap<LibraryProperty, String> (); - - for (LibraryProperty p : LibraryProperty.values ()) - { - try - { - properties.put (p, rs.getString (p.sql)); - } - catch (SQLException e) - { - // Ignore this, as it is almost certainly just a non-existent - // property. - } - } - - results.add (new LibraryItem (properties)); + results.add (translateRow (rs)); } } catch (SQLException e) { throw new QueryFailureException (e.getMessage ()); } - + return results; } -}
\ No newline at end of file + + + /** + * Translate a row retrieved from the database into a LibraryItem. + * + * @param rs The result-set, or database cursor, pointing to the + * row to translate. + * + * @return A new LibraryItem containing the properties extracted + * from the translated row. + */ + + private static LibraryItem + translateRow (ResultSet rs) + { + // Translate SQL columns into a list of properties. + + HashMap<LibraryItemProperty, String> properties = new HashMap<LibraryItemProperty, String> (); + + for (LibraryItemProperty p : LibraryItemProperty.values ()) + { + try + { + properties.put (p, rs.getString (p.sql)); + } + catch (SQLException e) + { + // Ignore this, as it is almost certainly just a non-existent + // property. + } + } + + + return new LibraryItem (properties); + } +} diff --git a/src/uk/org/ury/library/viewer/LibraryViewer.java b/src/uk/org/ury/library/viewer/LibraryViewer.java index 19f94fb..a98fa54 100644 --- a/src/uk/org/ury/library/viewer/LibraryViewer.java +++ b/src/uk/org/ury/library/viewer/LibraryViewer.java @@ -15,6 +15,8 @@ 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; @@ -32,40 +34,28 @@ public class LibraryViewer extends AbstractFrontendModule private List<LibraryItem> libraryList; private LibraryViewerPanel panel; private FrontendFrame frame; - private static ConfigReader config; + private ConfigReader config; /** - * Main function, for running this module as a standalone - * application. - * - * @param args The command-line argument array. - */ - - public static void - main (String[] args) - { - try { - config = new ConfigReader("res/conf.xml"); - } - catch(MissingCredentialsException e) { - System.out.println(e); - } - LibraryViewer lv = new LibraryViewer (); - lv.runFrontendInFrame (); - } - - - /** - * Construct a new LibraryViewer. + * Construct a new LibraryViewer as a frontend object. */ public LibraryViewer () { + try + { + config = new ConfigReader ("res/conf.xml"); + } + catch (MissingCredentialsException e) + { + System.out.println(e); + } + frame = null; libraryList = new ArrayList<LibraryItem> (); - panel = new LibraryViewerPanel (this); + panel = null; } @@ -78,7 +68,7 @@ public class LibraryViewer extends AbstractFrontendModule { frame = null; libraryList = new ArrayList<LibraryItem> (); - panel = new LibraryViewerPanel (this); + panel = null; try @@ -91,7 +81,7 @@ public class LibraryViewer extends AbstractFrontendModule panel.setOpaque (true); setContentPane (panel); - runFrontend (); + runFrontend (null); } }); @@ -117,38 +107,24 @@ public class LibraryViewer extends AbstractFrontendModule start () { frame = null; - panel = new LibraryViewerPanel (this); + panel = new LibraryViewerPanel (this, null); add (panel); } - - - /** - * Run the library viewer frontend in a FrontendFrame. - */ - - public void - runFrontendInFrame () - { - FrontendFrame frame = new FrontendFrame (panel); - this.frame = frame; - - runFrontend (); - } - + /** * Run the library viewer frontend. */ - private void - runFrontend () + public FrontendModulePanel + runFrontend (FrontendMaster master) { dd = null; try { - dd = new DatabaseDriver(config, UserClass.READ_ONLY); + dd = new DatabaseDriver (config, UserClass.READ_ONLY); } catch (MissingCredentialsException e) { @@ -159,6 +135,9 @@ public class LibraryViewer extends AbstractFrontendModule { FrontendError.reportFatal (f.getMessage (), frame); } + + panel = new LibraryViewerPanel (this, master); + return panel; } diff --git a/src/uk/org/ury/library/viewer/LibraryViewerPanel.java b/src/uk/org/ury/library/viewer/LibraryViewerPanel.java index 7057cc0..d6a00d9 100644 --- a/src/uk/org/ury/library/viewer/LibraryViewerPanel.java +++ b/src/uk/org/ury/library/viewer/LibraryViewerPanel.java @@ -4,10 +4,10 @@ package uk.org.ury.library.viewer; -import java.net.URL; import java.util.concurrent.ExecutionException; import javax.swing.JButton; +import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; @@ -15,11 +15,8 @@ import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.SwingWorker; -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.frontend.FrontendMaster; +import uk.org.ury.frontend.FrontendModulePanel; import uk.org.ury.library.LibraryTableModel; import uk.org.ury.library.exceptions.EmptySearchException; @@ -30,25 +27,21 @@ import uk.org.ury.library.exceptions.EmptySearchException; * @author Matt Windsor, Nathan Lasseter */ -public class LibraryViewerPanel extends FrontendPanel +public class LibraryViewerPanel extends FrontendModulePanel { /** * */ private static final long serialVersionUID = -2441616418398056712L; - - - /* Controller of this panel. */ - - private LibraryViewer master; /* Panel widgets exposed by the SwiXML user interface. */ private JTable resultsTable; private JScrollPane resultsPane; - private JPanel messagePanel; + private JPanel messagePanel; private JLabel messageLabel; + private JPanel searchingPanel; private JTextField searchField; private JButton searchButton; @@ -57,49 +50,28 @@ public class LibraryViewerPanel extends FrontendPanel * letting the user know what happened. */ - private String searchFailureMessage = "ALEX!"; + private String searchFailureMessage = "Unknown error."; + /** * Construct a new LibraryViewerPanel. * - * @param inMaster The LibraryViewer controlling this LibraryViewerPanel. + * @param viewer The LibraryViewer controlling this LibraryViewerPanel. + * + * @param master The FrontendMaster driving the frontend. */ public - LibraryViewerPanel (LibraryViewer inMaster) + LibraryViewerPanel (LibraryViewer viewer, FrontendMaster master) { - super (); - - master = inMaster; - - - URL path = getClass ().getResource ("library_viewer_gui.xml"); - - if (path == null) - throw new IllegalArgumentException ("XML file does not exist."); - - SwingEngine se = new SwingEngine (this); - se.getTaglib ().registerTag ("hint", HintField.class); - - + super (viewer, "library_viewer_gui.xml", master); + /* 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. + * See this file for more details. */ - - try - { - se.insert (path, this); - } - catch (Exception e) - { - FrontendError.reportFatal ("UI creation failure: " + e.getMessage (), null); - } - + // Fine-tune table @@ -110,7 +82,7 @@ public class LibraryViewerPanel extends FrontendPanel /** * @return the name of the panel. * - * @see uk.org.ury.frontend.FrontendPanel#getName() + * @see uk.org.ury.frontend.FrontendModulePanel#getName() */ @Override @@ -143,8 +115,10 @@ public class LibraryViewerPanel extends FrontendPanel searchField.setEnabled (false); searchButton.setEnabled (false); resultsPane.setVisible (false); - messageLabel.setText ("Searching..."); - messagePanel.setVisible (true); + messagePanel.setVisible (false); + searchingPanel.setVisible (true); + + final LibraryViewer master = (LibraryViewer) getModule (); SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void> () @@ -207,16 +181,18 @@ public class LibraryViewerPanel extends FrontendPanel searchField.setEnabled (true); searchButton.setEnabled (true); - messagePanel.setVisible (true); + searchingPanel.setVisible (false); if (hasSucceeded == false) { messageLabel.setText (searchFailureMessage); + messagePanel.setVisible (true); } else if (master.getLibraryList ().size () == 0) { messageLabel.setText ("Sorry, but no results were " + "found for that term."); + messagePanel.setVisible (true); } else { 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 60ae0d1..6b7e745 100644 --- a/src/uk/org/ury/library/viewer/library_viewer_gui.xml +++ b/src/uk/org/ury/library/viewer/library_viewer_gui.xml @@ -7,13 +7,20 @@ <textfield id="searchField" mnemonic="VK_F" action="search" /> </hbox> <button id="searchButton" text="Search" mnemonic="VK_S" action="search" - font="Verdana-BOLD-14" /> + 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> + <panel id="searchingPanel" constraints="BorderLayout.CENTER" visible="false" + layout="BorderLayout"> + <label id="searchingLabel" text="Searching..." font="Verdana-BOLD-16" + 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" diff --git a/src/uk/org/ury/show/ShowChannel.java b/src/uk/org/ury/show/ShowChannel.java new file mode 100644 index 0000000..6aa3ee8 --- /dev/null +++ b/src/uk/org/ury/show/ShowChannel.java @@ -0,0 +1,92 @@ +package uk.org.ury.show; + +import java.util.ArrayList; +import java.util.List; + + +/** + * A channel of ShowItems in a show. + * + * @author Matt Windsor + */ + +public class ShowChannel +{ + /* Items enqueued in channel. */ + private List<ShowItem> items; + + + /** + * Construct a new, empty channel. + */ + + public + ShowChannel () + { + items = new ArrayList<ShowItem> (); + } + + + /** + * Add a new item to the channel. + * + * @param index The position at which to add the item. + * + * @param item The new item to add. + * + * @throws IllegalArgumentException if the item is + * null, the index is negative or the index + * is out of bounds. + */ + + public void + add (int index, ShowItem item) + { + if (item == null) + throw new IllegalArgumentException ("Item is null."); + + if (index < 0 || index >= items.size ()) + throw new IllegalArgumentException ("Index " + index + + " out of bounds."); + + items.add (index, item); + } + + + /** + * Add a new item to the end of the channel. + * + * @param item The new item to add. + */ + + public void + add (ShowItem item) + { + if (item == null) + throw new IllegalArgumentException ("Item is null."); + + items.add (item); + } + + + /** + * Retrieve an item from the channel. + * + * @param index The index of the item to retrieve from the channel. + * + * @return the item at the given index in the list. + * + * @throws IllegalArgumentException if the index is negative + * or overflowing. + */ + + public ShowItem + get (int index) + { + if (index < 0 || index >= items.size ()) + throw new IllegalArgumentException ("Index " + index + + " out of bounds."); + + return items.get (index); + } +} diff --git a/src/uk/org/ury/show/ShowItem.java b/src/uk/org/ury/show/ShowItem.java new file mode 100644 index 0000000..be65c80 --- /dev/null +++ b/src/uk/org/ury/show/ShowItem.java @@ -0,0 +1,25 @@ +/** + * + */ +package uk.org.ury.show; + + +import java.util.Map; + +import uk.org.ury.database.DatabaseItem; + + +/** + * An item in the show database. + * + * @author Matt Windsor + */ + +public class ShowItem extends DatabaseItem<ShowItemProperty, String> +{ + public + ShowItem (Map<ShowItemProperty, String> properties) + { + super (properties); + } +} diff --git a/src/uk/org/ury/show/ShowItemProperty.java b/src/uk/org/ury/show/ShowItemProperty.java new file mode 100644 index 0000000..a722a21 --- /dev/null +++ b/src/uk/org/ury/show/ShowItemProperty.java @@ -0,0 +1,26 @@ +package uk.org.ury.show; + + +/** + * Enumeration of the parameters that are stored in a ShowItem. + * + * @author Matt Windsor + */ + +public enum ShowItemProperty + { + // Constant SQL identifier + NAME1 ("name1"), + NAME2 ("name2"), + POSITION ("positionid"); + + + public final String sql; + + + private + ShowItemProperty (String sql) + { + this.sql = sql; + } + };
\ No newline at end of file diff --git a/src/uk/org/ury/show/ShowUtils.java b/src/uk/org/ury/show/ShowUtils.java new file mode 100644 index 0000000..11a5dad --- /dev/null +++ b/src/uk/org/ury/show/ShowUtils.java @@ -0,0 +1,153 @@ +/** + * + */ +package uk.org.ury.show; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import uk.org.ury.database.DatabaseDriver; +import uk.org.ury.database.exceptions.QueryFailureException; + +import uk.org.ury.show.ShowItem; +import uk.org.ury.show.ShowItemProperty; + + +/** + * A set of common utility routines to facilitate the extraction of + * show items from the show storage areas of the URY database. + * + * @author Matt Windsor + * + */ + +public class ShowUtils +{ + /** + * The number of channels reserved for show items. + * + * TODO: move this somewhere more appropriate. + */ + + public static final int NUM_CHANNELS = 3; + + + // Maximum number of results to pull from database + private static final int MAX_RESULTS = 50; + + + /** + * Given a show and a channel, retrieve a list of all show items + * bound to that channel for the show. + * + * @param db The database to query. + * + * @param showID The unique number that identifies the show. + * + * @param channel The index of the channel to query. + * + * @throws IllegalArgumentException if the database is + * null, the show ID is negative or the + * channel index falls out of bounds. + * + * @throws QueryFailureException if the database backend + * yielded an error while executing the search + * query. + * + * @return a list of ShowItems extracted from the show and + * channel. The list may be empty. + */ + + public static List<ShowItem> + getChannelList (DatabaseDriver db, int showID, int channel) + throws QueryFailureException + { + if (db == null) + throw new IllegalArgumentException ("Database handle is null."); + + if (showID < 0) + throw new IllegalArgumentException ("Show ID is negative."); + + if (channel < 0 || channel >= NUM_CHANNELS) + throw new IllegalArgumentException ("Channel index is out of bounds."); + + List<ShowItem> results = new ArrayList<ShowItem> (); + + + ResultSet rs = null; + + Object[] params = {showID, channel}; + + try + { + rs = db.executeQuery ("SELECT name1, name2, positionid" + + " FROM baps_show" + + " INNER JOIN baps_listing" + + " ON baps_show.showid" + + " = baps_listing.showid" + + " INNER JOIN baps_item" + + " ON baps_listing.listingid" + + " = baps_show.showid" + + " WHERE baps_show.showid" + + " = ?" + + " AND baps_listing.channel" + + " = ?", params, MAX_RESULTS); + } + catch (SQLException e) + { + throw new QueryFailureException (e.getMessage ()); + } + + try + { + while (rs.next ()) + { + results.add (translateRow (rs)); + } + } + catch (SQLException e) + { + throw new QueryFailureException (e.getMessage ()); + } + + return results; + } + + + /** + * Translate a row retrieved from the database into a LibraryItem. + * + * @param rs The result-set, or database cursor, pointing to the + * row to translate. + * + * @return A new LibraryItem containing the properties extracted + * from the translated row. + */ + + private static ShowItem + translateRow (ResultSet rs) + { + // Translate SQL columns into a list of properties. + + HashMap<ShowItemProperty, String> properties = new HashMap<ShowItemProperty, String> (); + + for (ShowItemProperty p : ShowItemProperty.values ()) + { + try + { + properties.put (p, rs.getString (p.sql)); + } + catch (SQLException e) + { + // Ignore this, as it is almost certainly just a non-existent + // property. + } + } + + + return new ShowItem (properties); + } +}
\ No newline at end of file diff --git a/src/uk/org/ury/show/viewer/ChannelPanel.java b/src/uk/org/ury/show/viewer/ChannelPanel.java new file mode 100644 index 0000000..187aa86 --- /dev/null +++ b/src/uk/org/ury/show/viewer/ChannelPanel.java @@ -0,0 +1,100 @@ +/** + * + */ +package uk.org.ury.show.viewer; + +import java.awt.event.KeyEvent; +import java.net.URL; + +import javax.swing.DefaultListModel; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.ListModel; + +import org.swixml.SwingEngine; + +import uk.org.ury.frontend.FrontendError; +import uk.org.ury.show.ShowChannel; + + +/** + * A panel displaying channel informstion. + * + * @author Matt Windsor. + */ + +public class ChannelPanel extends JPanel +{ + private JLabel channelName; + private JList itemList; + private JButton playButton; + private JButton pauseButton; + private JButton stopButton; + + + /** + * Construct a new ChannelPanel. + * + * This constructor reads the channel panel layout from the + * XML manifest "channel_panel.xml" in the same directory as + * this class file. + * + * @param number The number of the channel. + * + * @param channel The channel whose data the ChannelPanel is viewing. + */ + + public + ChannelPanel (int number, ShowChannel channel) + { + super (); + + // Acquire path. + + URL path = getClass ().getResource ("channel_panel.xml"); + + if (path == null) + FrontendError.reportFatal ("UI creation failure: XML layout does not exist.", null); + + SwingEngine se = new SwingEngine (this); + + + // Read the XML. + + try + { + se.insert (path, this); + } + catch (Exception e) + { + FrontendError.reportFatal ("UI creation failure: " + e.getMessage (), null); + } + + // Tweak buttons to add function key mnemonics, if function keys are available. + + if (number <= 4) + { + int base = number * 3; + + playButton.setText ("Play (F" + (base - 2) + ")"); + playButton.setMnemonic (KeyEvent.VK_F1 + (base - 1)); + playButton.setDisplayedMnemonicIndex (7); + + pauseButton.setText ("Stop (F" + (base - 1) + ")"); + pauseButton.setMnemonic (KeyEvent.VK_F2 + (base - 1)); + pauseButton.setDisplayedMnemonicIndex (7); + + stopButton.setText ("Pause (F" + (base ) + ")"); + stopButton.setMnemonic (KeyEvent.VK_F3 + (base - 1)); + stopButton.setDisplayedMnemonicIndex (8); + } + + // Test stuff + DefaultListModel test = new DefaultListModel (); + test.add (0, "Test"); + itemList.setModel (test); + channelName.setText ("Channel " + number); + } +} diff --git a/src/uk/org/ury/show/viewer/LibraryControlPanel.java b/src/uk/org/ury/show/viewer/LibraryControlPanel.java new file mode 100644 index 0000000..cf5eec2 --- /dev/null +++ b/src/uk/org/ury/show/viewer/LibraryControlPanel.java @@ -0,0 +1,33 @@ +package uk.org.ury.show.viewer; + + +import uk.org.ury.frontend.FrontendControlPanel; + + +/** + * Control panel for the demo system. + * + * @author Matt Windsor + * + */ + +public class LibraryControlPanel extends FrontendControlPanel +{ + + public + LibraryControlPanel () + { + super ("library_control_panel.xml"); + } + + + /** + * Go back to the previous module. + */ + + public void + back () + { + master.restoreModule (parent, prevCPanel); + } +} diff --git a/src/uk/org/ury/show/viewer/ShowViewer.java b/src/uk/org/ury/show/viewer/ShowViewer.java new file mode 100644 index 0000000..8b3f2db --- /dev/null +++ b/src/uk/org/ury/show/viewer/ShowViewer.java @@ -0,0 +1,161 @@ +package uk.org.ury.show.viewer; + +import java.lang.reflect.InvocationTargetException; + +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.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.FrontendModule; +import uk.org.ury.frontend.FrontendModulePanel; + +import uk.org.ury.show.ShowChannel; +import uk.org.ury.show.ShowUtils; + + +/** + * Frontend module for viewing show details. + * + * This serves as the base for the show playout and editor classes, + * but can be used stand-alone as an (admittedly rather pointless) + * module. + * + * @author Matt Windsor + * + */ + +public class ShowViewer extends AbstractFrontendModule +{ + /** + * + */ + + private static final long serialVersionUID = -2782366476480563739L; + private DatabaseDriver dd; + private ShowChannel[] channels; + private ShowViewerPanel panel; + private FrontendFrame frame; + private ConfigReader config; + + + /** + * Construct a new ShowViewer as a frontend object. + */ + + public + ShowViewer () + { + try + { + config = new ConfigReader ("res/conf.xml"); + } + catch (MissingCredentialsException e) + { + System.out.println(e); + } + + frame = null; + channels = new ShowChannel[ShowUtils.NUM_CHANNELS]; + } + + + /** + * Initialise the library viewer frontend as an applet. + */ + + public void + init () + { + frame = null; + channels = new ShowChannel[ShowUtils.NUM_CHANNELS]; + panel = new ShowViewerPanel (this, 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 ShowViewerPanel (this, null); + + add (panel); + } + + + /** + * Run the library viewer frontend. + */ + + @Override + public FrontendModulePanel + runFrontend (FrontendMaster master) + { + dd = null; + + try + { + dd = new DatabaseDriver (config, UserClass.READ_ONLY); + } + catch (MissingCredentialsException e) + { + // TODO: Privilege de-escalation + FrontendError.reportFatal (e.getMessage (), frame); + } + catch (Exception f) + { + FrontendError.reportFatal (f.getMessage (), frame); + } + + panel = new ShowViewerPanel (this, master); + return panel; + } + + + /** + * @return the channel array. + */ + + public ShowChannel[] + getChannels () + { + // TODO Auto-generated method stub + return channels; + } +} diff --git a/src/uk/org/ury/show/viewer/ShowViewerPanel.java b/src/uk/org/ury/show/viewer/ShowViewerPanel.java new file mode 100644 index 0000000..d276420 --- /dev/null +++ b/src/uk/org/ury/show/viewer/ShowViewerPanel.java @@ -0,0 +1,82 @@ +/** + * + */ +package uk.org.ury.show.viewer; + +import javax.swing.JButton; +import javax.swing.JPanel; + +import uk.org.ury.frontend.FrontendMaster; +import uk.org.ury.frontend.FrontendModulePanel; +import uk.org.ury.show.ShowChannel; + + +/** + * Frontend panel providing access to an underlying lshow viewer. + * + * @author Matt Windsor, Nathan Lasseter + */ + +public class ShowViewerPanel extends FrontendModulePanel +{ + /** + * + */ + private static final long serialVersionUID = -2441616418398056712L; + + private JPanel channelGroupPanel; + + /* Panel widgets exposed by the SwiXML user interface. */ + + + /** + * Construct a new ShowViewerPanel. + * + * @param viewer The ShowViewer controlling this LibraryViewerPanel. + * + * @param master The FrontendMaster driving the frontend. + */ + + public + ShowViewerPanel (ShowViewer viewer, FrontendMaster master) + { + super (viewer, "show_viewer_gui.xml", master); + + int channelNumber = 1; + ChannelPanel cp; + + for (ShowChannel channel : viewer.getChannels ()) + { + cp = new ChannelPanel (channelNumber, channel); + + channelGroupPanel.add (cp); + channelNumber++; + } + } + + + /** + * @return the name of the panel. + * + * @see uk.org.ury.frontend.FrontendModulePanel#getName() + */ + + @Override + public String + getName () + { + return "Show Viewer Demo"; + } + + + /** + * Initialise the library viewer for the purposes of adding tracks + * and/or browsing the library. + */ + + public void + search () + { + master.loadModule ("library.viewer.LibraryViewer", "show.viewer.LibraryControlPanel"); + } +} diff --git a/src/uk/org/ury/show/viewer/channel_panel.xml b/src/uk/org/ury/show/viewer/channel_panel.xml new file mode 100644 index 0000000..f739c7a --- /dev/null +++ b/src/uk/org/ury/show/viewer/channel_panel.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<panel border="RaisedBevelBorder" size="100,250"> + <vbox> + <hbox> + <label id ="channelName" + border="EmptyBorder(5,5,5,5)" + text="Channel x" font="Verdana-BOLD-14" /> + </hbox> + <scrollpane id="itemScroller"> + <list id="itemList" /> + </scrollpane> + <hbox> + <button id="playButton" text="Play" /> + <button id="pauseButton" text="Pause" /> + <button id="stopButton" text="Stop" /> + </hbox> + <hbox> + <label text="Name of track" /> + </hbox> + <hbox> + <label text="Duration chart" /> + </hbox> + <hbox> + <hbox border="EtchedBorder"> + <vbox border="EmptyBorder(5,5,5,5)"> + <label text="Elapsed" /> + </vbox> + </hbox> + <hbox border="EtchedBorder"> + <vbox border="EmptyBorder(5,5,5,5)"> + <label text="Remaining" /> + </vbox> + </hbox> + </hbox> + </vbox> +</panel>
\ No newline at end of file diff --git a/src/uk/org/ury/show/viewer/library_control_panel.xml b/src/uk/org/ury/show/viewer/library_control_panel.xml new file mode 100644 index 0000000..79e5777 --- /dev/null +++ b/src/uk/org/ury/show/viewer/library_control_panel.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<panel> + <hbox border="EmptyBorder(0,5,5,5)" size="640,32"> + <button id="backButton" text="Back to Show" mnemonic="VK_B" action="back" + font="Verdana-BOLD-14" /> + <button id="c1Button" text="Add to Channel 1" mnemonic="VK_1" action="addch1" + font="Verdana-BOLD-14" /> + <button id="c2Button" text="Add to Channel 2" mnemonic="VK_2" action="addch2" + font="Verdana-BOLD-14" /> + <button id="c3Button" text="Add to Channel 3" mnemonic="VK_3" action="addch3" + font="Verdana-BOLD-14" /> + </hbox> +</panel> diff --git a/src/uk/org/ury/show/viewer/show_viewer_gui.xml b/src/uk/org/ury/show/viewer/show_viewer_gui.xml new file mode 100644 index 0000000..a4f0f5b --- /dev/null +++ b/src/uk/org/ury/show/viewer/show_viewer_gui.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<panel layout="BorderLayout"> + <hbox constraints="BorderLayout.NORTH" border="EmptyBorder(5,5,5,5)" size="640,32"> + <button id="loadButton" text="Load Show or Template..." mnemonic="VK_L" + action="load" + font="Verdana-BOLD-14" /> + <button id="searchButton" text="Search Record Library" mnemonic="VK_S" + action="search" + font="Verdana-BOLD-14" /> + </hbox> + + <splitpane constraints="BorderLayout.CENTER" border="EmptyBorder(0,5,0,5)" + orientation="0"> + <scrollpane id="binScrollPane"> + <label text="Bins will go here." /> + </scrollpane> + <scrollpane id="channelScrollPane"> + <panel id="channelGroupPanel" /> + </scrollpane> + </splitpane> + + <hbox constraints="BorderLayout.SOUTH" border="EmptyBorder(5,5,5,5)"> + <hint text="Hint goes here." /> + </hbox> +</panel> diff --git a/src/uk/org/ury/testrig/DemoControlPanel.java b/src/uk/org/ury/testrig/DemoControlPanel.java new file mode 100644 index 0000000..7e4b439 --- /dev/null +++ b/src/uk/org/ury/testrig/DemoControlPanel.java @@ -0,0 +1,33 @@ +package uk.org.ury.testrig; + + +import uk.org.ury.frontend.FrontendControlPanel; + + +/** + * Control panel for the demo system. + * + * @author Matt Windsor + * + */ + +public class DemoControlPanel extends FrontendControlPanel +{ + + public + DemoControlPanel () + { + super ("demo_control_panel.xml"); + } + + + /** + * Go back to the previous module. + */ + + public void + back () + { + master.restoreModule (parent, prevCPanel); + } +} diff --git a/src/uk/org/ury/testrig/DemoMenu.java b/src/uk/org/ury/testrig/DemoMenu.java new file mode 100644 index 0000000..bc4636b --- /dev/null +++ b/src/uk/org/ury/testrig/DemoMenu.java @@ -0,0 +1,112 @@ +package uk.org.ury.testrig; + +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JButton; + +import uk.org.ury.frontend.FrontendFrame; +import uk.org.ury.frontend.FrontendModulePanel; + + +/** + * Application frontend, for testing early-stage frontend code. + * + * @author Matt Windsor + * + */ + +public class DemoMenu +{ + private FrontendFrame frame; + + /** + * Main method. + * + * @param args The command-line arguments to the program. These + * will be ignored. + */ + + public static void + main (String[] args) + { + DemoMenu dm = new DemoMenu (); + dm.run (); + } + + + /** + * + */ + + public void + loadModule (String module) + { + frame.loadModule (module, "testrig.DemoControlPanel"); + } + + /** + * Run the demo menu, creating a user interface. + */ + + public void + run () + { + FrontendModulePanel panel = new FrontendModulePanel (null, frame) + { + private static final long serialVersionUID = 1L; + + { + setLayout (new GridLayout (2, 1)); + + JButton lb = new JButton ("Library Viewer Demo"); + JButton sb = new JButton ("Show Viewer Demo"); + + lb.addActionListener (new ActionListener () + { + + @Override + public void + actionPerformed (ActionEvent arg0) + { + loadModule ("library.viewer.LibraryViewer"); + } + + }); + + + sb.addActionListener (new ActionListener () + { + + @Override + public void + actionPerformed (ActionEvent arg0) + { + loadModule ("show.viewer.ShowViewer"); + } + + }); + + + add (lb); + add (sb); + } + + + /** + * @return the name of the module. + */ + + @Override + public String + getName () + { + return "Demo Menu"; + } + }; + + + frame = new FrontendFrame (panel); + } +} diff --git a/src/uk/org/ury/testrig/demo_control_panel.xml b/src/uk/org/ury/testrig/demo_control_panel.xml new file mode 100644 index 0000000..cade1dd --- /dev/null +++ b/src/uk/org/ury/testrig/demo_control_panel.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<panel> + <hbox border="EmptyBorder(0,5,5,5)" size="640,32"> + <button id="backButton" text="Back to Demo Menu" mnemonic="VK_B" action="back" + font="Verdana-BOLD-14" /> + <button id="aboutButton" text="About..." mnemonic="VK_A" action="about" + font="Verdana-BOLD-14" /> + </hbox> +</panel> |