Commits

CMPT 371 - Team 2 committed a7bbb3d

UI: added About window.

Hackily done and probably looks horrible on other platforms, but it looks OK on
the school computers.

Comments (0)

Files changed (4)

src/ca/usask/cs/giraffe/images/icon/icon_win32-gnulinux-256.png

Removed
Old image

src/ca/usask/cs/giraffe/images/icon/icon_win32-gnulinux_256.png

Added
New image

src/ca/usask/cs/giraffe/ui/About.java

+/* ui/About.java
+ * 
+ */
+package ca.usask.cs.giraffe.ui;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+/**
+ * A simple "About Giraffe" window that displays program information about
+ * Giraffe such as:
+ * <ul>
+ *     <li>Program version</li>
+ *     <li>Authors</li>
+ *     <li>Licensing information</li>
+ * </ul>
+ * <p>
+ * This class is the only example of a singleton in Giraffe as we prefer to
+ * avoid bad design patterns!
+ * <p>
+ * FIXME - this window's layout is disgustingly, hackily coded. It looks nice, 
+ * but it could be so much better (this was thrown together in about half an hour...)
+ * 
+ * @author Alex Mair (ajm513@mail.usask.ca)
+ */
+public class About extends JFrame {
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * The singleton instance of the About window.
+	 */
+	private static About window;
+	
+	/**
+	 * The OK button. Needed so it can receive keyboard focus.
+	 */
+	private JButton okButton;
+	
+	/**
+	 * Our listener.
+	 */
+	private AboutWindowListener listener;
+	
+	/**
+	 * The text displayed below the GIRAFFE icon, before the authors. Each array
+	 * entry is one line.
+	 */
+	final private static String[] aboutText={
+		"GIRAFFE - a learning tool for beginner programmers.",
+		"Final CMPT 370 Submission Copy",
+		"(git revision FIXME - HASH NUMBER GOES HERE!!!"
+	};
+	
+	/**
+	 * The text that preceeds the list of {@link #authors}
+	 */
+	final private static String authorsHeader="Written by:\n";
+			
+	/**
+	 * The jerks who wrote GIRAFFE.
+	 */
+	final private static String[] authors={
+		// Hmm, alex wonders if anyone else will notice that he put his name first  ;)
+		"Logan Cool  -  llc242@mail.usask.ca",
+		"Joey Eremondi  -  jse313@mail.usask.ca",
+		"Alex Mair  -  ajm513@mail.usask.ca",
+		"Joanne Traves  -  jet971@mail.usask.ca",
+		"Ivan Vendrov  -  isv452@mail.usask.ca"
+	};
+	
+	/**
+	 * The padding that panels have from their edge components.
+	 */
+	final private int PANEL_XPADDING=16;
+	
+	/**
+	 * The padding in between inner window panels, in pixels.
+	 */
+	final private int PANEL_YPADDING=16;
+	
+	/**
+	 * The padding present on either side of the OK button.
+	 */
+	final private int BUTTON_XPADDING=160;
+	
+	/**
+	 * Default window size.
+	 */
+	final Dimension DEFAULT_WINDOW_SIZE=new Dimension(400,300);
+	
+	/**
+	 * Hidden as this class is a singleton.
+	 * <p>
+	 * Note that the window should be lazily constructed.
+	 * @see #showAboutWindow
+	 */
+	private About() {
+		super();
+		
+		this.listener=new AboutWindowListener();
+		
+		this.setTitle("About GIRAFFE");
+		this.setResizable(false);
+		this.setIconImage(Toolkit.getDefaultToolkit().createImage(ClassLoader.getSystemResource(UI.baseIconPath+"icon_win32-gnulinux_16.png")));
+
+		this.okButton=new JButton("OK");
+		this.okButton.addActionListener(this.listener);
+
+		this.setLayout(new BoxLayout(this.getContentPane(),BoxLayout.PAGE_AXIS));
+		this.add(Box.createRigidArea(new Dimension(400,PANEL_YPADDING)));
+		this.add(new InnerPanel());
+		this.add(Box.createRigidArea(new Dimension(400,PANEL_YPADDING)));
+		
+		this.setSize(this.getPreferredSize());
+	}
+	
+	/**
+	 * Lazily shows the window: it is constructed if needed. The window's OK
+	 * button recieves focus.
+	 * <p>
+	 * <b>This method is not thread-safe.</b> It is assumed that you will call
+	 * this method from within an event-queue processor (such as in {@link MenuBar})
+	 */
+	protected synchronized static void showAboutWindow() {
+		if (window==null)
+			window=new About();
+		window.setVisible(true);
+		window.toFront();
+		window.repaint();
+		window.okButton.requestFocusInWindow();
+	}
+	
+	/**
+	 * The panel that contains the window contents.
+	 */
+	protected class InnerPanel extends JPanel {
+		private static final long serialVersionUID = 1L;
+
+		public InnerPanel() {
+			super(new BorderLayout());
+
+			this.add(new JLabel("",UI.loadImageIcon("icon/icon_win32-gnulinux_256.png"),JLabel.CENTER),
+					BorderLayout.NORTH);
+			this.add(Box.createRigidArea(new Dimension(PANEL_XPADDING,0)),BorderLayout.WEST);
+			this.add(Box.createRigidArea(new Dimension(PANEL_XPADDING,0)),BorderLayout.EAST);
+			this.add(new InfoPanel(),BorderLayout.CENTER);
+			this.add(new ButtonPanel(),BorderLayout.SOUTH);
+		}
+	}
+	
+	/**
+	 * The panel located within {@link #InnerPanel} that holds the author's info.
+	 */
+	protected class InfoPanel extends JPanel {
+		private static final long serialVersionUID = 1L;
+
+		public InfoPanel() {
+			this.setLayout(new BoxLayout(this,BoxLayout.PAGE_AXIS));
+			this.add(Box.createRigidArea(new Dimension(0,PANEL_YPADDING)));
+			for (String s : aboutText){ 
+				this.add(new JLabel(s));
+				this.add(Box.createRigidArea(new Dimension(0,PANEL_YPADDING)));
+			};
+			this.add(new JLabel(authorsHeader));
+			for (int i=0;i<authors.length;++i)
+				this.add(new JLabel("\t"+authors[i]));
+		}
+	}
+	
+	/**
+	 * The panel containing the OK button - ensures it looks good.
+	 * <p>
+	 * This panel assumes the existence of {@link #okButton} before instantiation.
+	 */
+	protected class ButtonPanel extends JPanel {
+		private static final long serialVersionUID = 1L;
+		
+		public ButtonPanel() {
+			super(new BorderLayout());
+			
+			this.add(Box.createRigidArea(new Dimension(0,PANEL_YPADDING)),BorderLayout.NORTH);
+			this.add(Box.createRigidArea(new Dimension(BUTTON_XPADDING,0)),BorderLayout.WEST);
+			this.add(okButton,BorderLayout.CENTER);
+			this.add(Box.createRigidArea(new Dimension(BUTTON_XPADDING,0)),BorderLayout.EAST);
+			this.add(Box.createRigidArea(new Dimension(0,PANEL_YPADDING)),BorderLayout.SOUTH);
+		}
+	}
+	
+	/**
+	 * The listener for the About window. For now, just handles the OK button click.
+	 */
+	protected class AboutWindowListener implements ActionListener {
+		@Override
+		public void actionPerformed(ActionEvent e) {
+			window.dispose();
+		}
+	}
+}

src/ca/usask/cs/giraffe/ui/MenuBar.java

 					GiraffeLogger.warn("Got ABOUT_HELP - not implemented yet. Ignoring.");
 					break;
 				case ABOUT_ABOUT:
-					GiraffeLogger.warn("Got ABOUT_ABOUT - not implemented yet. Ignoring.");
+					About.showAboutWindow();
 					break;
 				}
 			} catch (NullPointerException npe) {