001    package breakout;
002    
003    import java.awt.*;
004    import java.awt.event.*;
005    import javax.swing.*;
006    import javax.swing.border.EtchedBorder;
007    
008    /** Manages the user interface for Breakout. 
009      * <BR><BR>
010      * BreakoutUI manages:<ul>
011      *     <li>The message/instructions bar
012      *     <li>The {@link breakout.BoardPanel}
013      *     <li>The Load, Start, and Stop buttons, and their associated actions:<ol>
014      *             <li>Loading a Board from a text file
015      *             <li>Starting the game
016      *             <li>Stopping(pausing) the game
017      *             </ol>
018      *     <li>Loading a Board from code
019      *     </ul>
020      **/
021    public class BreakoutUI extends JFrame implements ActionListener {
022            /** The padding used to get away from the system-added borders to a JFrame. **/
023            public static final int PADDING = 2;
024    
025            private BoardPanel bp;
026            private JLabel stat;
027            
028            private World world;
029    
030            /** Creates a new BreakoutUI and gives it a new BoardPanel with no Board.
031            **/
032            public BreakoutUI() {
033                    super("Breakout");
034                    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
035                    
036                    // initiate widgets
037                    this.stat = new JLabel(" Click \"Load\" to begin.");
038                    JButton loadb = new JButton("Load"),
039                            startb = new JButton("Start"),
040                            quitb = new JButton("Stop");
041                    startb.addActionListener(this);
042                    loadb.addActionListener(this);
043                    quitb.addActionListener(this);
044                    
045                    //initiate top panel
046                    JPanel top = new JPanel();
047                    top.setLayout(new BorderLayout());
048                    top.add(this.stat, BorderLayout.WEST);
049                    Dimension topSize = new Dimension(BoardPanel.PREF_WIDTH, 
050                                                        top.getSize().height + 2*BreakoutUI.PADDING);
051                    
052                    //initiate middle panel
053                    this.bp = new BoardPanel(this);
054                    
055                    //initiate bottom panel
056                    JPanel bottom = new JPanel();
057                    BoxLayout bot = new BoxLayout(bottom, BoxLayout.X_AXIS);
058                    bottom.setLayout(bot);
059                    bottom.add(loadb);
060                    bottom.add(startb);
061                    bottom.add(Box.createHorizontalGlue());
062                    bottom.add(quitb);
063                    
064                    //put middle and bottom panels together
065                    JPanel allBottom = new JPanel();
066                    BoxLayout bot2 = new BoxLayout(allBottom, BoxLayout.Y_AXIS);
067                    allBottom.setLayout(bot2);
068                    allBottom.add(this.bp);
069                    allBottom.add(bottom);
070                    Dimension allBot = new Dimension(BoardPanel.PREF_WIDTH, 
071                                                     BoardPanel.PREF_HEIGHT+loadb.getPreferredSize().height);
072                    allBottom.setSize(allBot.width,allBot.height);
073                    allBottom.setMaximumSize(allBot);
074                    allBottom.setMinimumSize(allBot);
075                    
076                    //put middle-bottom and top panels together
077                    JPanel all = new JPanel();
078                    BoxLayout allb = new BoxLayout(all, BoxLayout.Y_AXIS);
079                    all.setLayout(allb);
080                    all.add(top);
081                    all.add(allBottom);
082                    Dimension alld = new Dimension(top.getSize().height+allBottom.getSize().height,
083                                                   BoardPanel.PREF_WIDTH);
084                    all.setSize(alld);
085                    all.setMaximumSize(alld);
086                    all.setMinimumSize(alld);
087                    
088                    //add "all" panel to the ContentPane of this JFrame
089                    Container thisC = this.getContentPane();
090                    thisC.setLayout(new FlowLayout());
091                    thisC.add(all);
092                    
093                    this.pack();
094                    this.show();
095            }
096            
097            /** Sets up a new World with the specified Board and this BreakoutUI.  
098              * @param b The Board object to be loaded.
099            **/
100            public void loadBoard(Board b) {
101                this.world = new World(b, this);
102                this.bp.repaint();
103                this.stat.setText(" Press \"Start\" to play.");
104            }
105            /** Loads a new Board from a properly formatted text file.
106            **/
107            public void loadBoard() {
108                Board b = new LoaderUI(this, ".").load();
109                if(b != null) this.loadBoard(b);
110            }
111            
112            /** Winning the game.
113              * Stops the World thread, and puts the appropriate message in the message box.
114            **/
115            public void win() { 
116                this.world.stop();
117                this.stat.setText(" You won!");
118            }
119            /** Losing the game.
120              * Stops the World thread, and puts the appropriate message in the message box.
121            **/
122            public void lose() { 
123                this.world.stop();
124                this.stat.setText(" You lost.");
125            }
126            
127            /** Gets the World used by this BreakoutUI. 
128              * @return a label for the World object used by this BreakoutUI.
129            **/
130            public World getWorld() {
131                return this.world;
132            }
133            /** Gets the BoardPanel used by this BreakoutUI.
134              * @return a label for the BoardPanel object used by this BreakoutUI.
135            **/
136            public BoardPanel getBoardPanel() {
137                return this.bp;
138            }
139            
140            /** Manages button presses. **/
141            public void actionPerformed(ActionEvent ae) {
142                    if(ae.getActionCommand().equals("Load")) {
143                            this.loadBoard();
144                    } else if(ae.getActionCommand().equals("Start")) {
145                            if(this.world != null) {
146                                this.world.start();
147                                this.stat.setText(" ");
148                            } else {
149                                System.err.println("BreakoutUI Error: Load board before pressing \"Start\".");
150                                this.stat.setText(" Please press \"Load\" first.");
151                            }
152                    } else if(ae.getActionCommand().equals("Stop")) {
153                            if(this.world != null) {
154                                this.world.stop();
155                            }
156                    }
157            }
158    }