Javadoc, small bugfix in levels.xml
[AntiTD.git] / src / se / umu / cs / dit06ajnajs / ATDView.java
blob3ebc68227134514bb335cabdbef83e793ce1724f
1 package se.umu.cs.dit06ajnajs;
3 import java.awt.AlphaComposite;
4 import java.awt.BorderLayout;
5 import java.awt.Color;
6 import java.awt.Graphics2D;
7 import java.awt.Graphics;
8 import java.awt.Image;
9 import java.awt.event.ActionListener;
10 import java.awt.event.MouseListener;
11 import java.awt.event.WindowListener;
12 import java.awt.geom.Rectangle2D;
13 import java.awt.image.BufferedImage;
14 import java.util.logging.Logger;
16 import javax.swing.BoxLayout;
17 import javax.swing.JComponent;
18 import javax.swing.JFrame;
19 import javax.swing.JLabel;
20 import javax.swing.JMenu;
21 import javax.swing.JMenuBar;
22 import javax.swing.JMenuItem;
23 import javax.swing.JOptionPane;
24 import javax.swing.JPanel;
25 import javax.swing.JTextArea;
27 import java.util.EventListener;
28 import javax.swing.JButton;
29 import javax.swing.DefaultListModel;
31 import se.umu.cs.dit06ajnajs.agent.AgentPrototypeFactory;
32 import javax.swing.JList;
33 import javax.swing.ListSelectionModel;
34 import se.umu.cs.dit06ajnajs.agent.Unit;
35 import javax.swing.SwingUtilities;
37 import se.umu.cs.dit06ajnajs.level.MapSquare;
39 /**
40 * ATDView is the view of this game, it creates a JFrame and fills it with
41 * menues and components that make up the entire interface of this game.
43 * @author Anton Johansson (dit06ajn@cs.umu.se)
44 * @author Andreas Jakobsson (dit06ajs@cs.umu.se)
45 * @version 1.0
47 public class ATDView {
48 private static Logger logger = Logger.getLogger("AntiTD");
50 private ATDModel model;
52 // Components
53 private JFrame frame;
54 private JTextArea scoreboard;
55 private JLabel messageLabel;
56 //private JLabel scoreboard;
58 private GameComponent gameComponent;
59 private Graphics2D gameGraphics;
61 // Menu
62 private JMenuItem newGameMenuItem;
63 private JMenuItem restartLevelMenuItem;
64 private JMenuItem pausMenuItem;
65 private JMenuItem muteMenuItem;
66 private JMenuItem quitMenuItem;
67 private JMenuItem helpMenuItem;
68 private JMenuItem aboutMenuItem;
70 // GameController
71 private JButton releaseUnitsButton;
73 private JList unitList;
75 /**
76 * Creates a new <code>ATDView</code> instance. Saves the supplied model as
77 * a field and calls createAndShowGUI().
79 * @param model The model used for this game. Used to get information from.
81 public ATDView(ATDModel model) {
82 this.model = model;
83 createAndShowGUI();
86 /**
87 * Create and show GUI used by this application.
89 private void createAndShowGUI() {
90 this.gameComponent = new GameComponent();
92 JPanel mainPanel = new JPanel(new BorderLayout());
94 mainPanel.add(createControlPanel(), BorderLayout.EAST);
95 mainPanel.add(createMenu(), BorderLayout.NORTH);
96 mainPanel.add(gameComponent, BorderLayout.CENTER);
98 this.frame = new JFrame();
99 frame.setTitle("AntiTD");
100 frame.add(mainPanel);
101 frame.pack();
102 frame.setVisible(true);
106 * Creates the JPanel containg Components to control the game.
108 * @return The JPanel containg Components to control the game.
110 private JPanel createControlPanel() {
111 JPanel resultPanel = new JPanel(new BorderLayout());
113 // JList unitTypes
114 DefaultListModel unitTypesListModel = new DefaultListModel();
115 AgentPrototypeFactory factory = AgentPrototypeFactory.getInstance();
116 for (String type : factory.getUnitTypes()) {
117 Unit unit = factory.createUnit(type);
118 unitTypesListModel.addElement(unit);
120 this.unitList= new JList(unitTypesListModel);
121 unitList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
122 // Set one index as selected
123 unitList.setSelectedIndex(0);
124 resultPanel.add(unitList, BorderLayout.NORTH);
126 JPanel shopPanel = new JPanel();
128 shopPanel.setLayout(new BoxLayout(shopPanel, BoxLayout.Y_AXIS));
129 // Scoreboard
130 scoreboard = new JTextArea("Credit:\t0\nScore:\t0\nCleared Units:\t0/0",1,10);
131 scoreboard.setOpaque(false);
132 scoreboard.setEditable(false);
134 // MessageArea
135 this.messageLabel = new JLabel();
136 resultPanel.add(messageLabel, BorderLayout.CENTER);
138 // Release Button
139 this.releaseUnitsButton = new JButton("Release Units");
141 shopPanel.add(scoreboard);
142 shopPanel.add(releaseUnitsButton);
144 resultPanel.add(shopPanel, BorderLayout.SOUTH);
145 return resultPanel;
149 * Creates the MenuBar used by this application.
151 * @return The MenuBar used by this application.
153 private JMenuBar createMenu() {
154 JMenuBar menubar = new JMenuBar();
156 // Menu AntiTD
157 JMenu antiTDMenu = new JMenu("AntiTD");
159 // TODO change name depending on if a game is running or not.
160 this.newGameMenuItem = new JMenuItem("New Game");
161 antiTDMenu.add(newGameMenuItem);
163 this.restartLevelMenuItem = new JMenuItem("Restart level");
164 antiTDMenu.add(restartLevelMenuItem);
166 this.pausMenuItem = new JMenuItem("Pause");
167 antiTDMenu.add(pausMenuItem);
169 this.muteMenuItem = new JMenuItem("Mute");
170 antiTDMenu.add(muteMenuItem);
172 this.quitMenuItem = new JMenuItem("Quit");
173 antiTDMenu.add(quitMenuItem);
175 // Menu Help
176 JMenu helpMenu = new JMenu("Help");
178 this.helpMenuItem = new JMenuItem("Help");
179 helpMenu.add(helpMenuItem);
181 this.aboutMenuItem = new JMenuItem("About");
182 helpMenu.add(aboutMenuItem);
184 // Add menus to menubar
185 menubar.add(antiTDMenu);
186 menubar.add(helpMenu);
187 return menubar;
191 * Returns the Graphics used to update visual information about Agents in
192 * the game.
194 * @return The Graphics used by Agents on the Level.
196 public Graphics getGameGraphics() {
197 return gameGraphics;
201 * Returns the type of the currently selected Unit.
203 * @return Type of the currently selected Unit.
205 public String getSelectedUnitType() {
206 return ((Unit) this.unitList.getSelectedValue()).getType();
210 * Updates the backgroundimage used, for example when MapSquare are changed
211 * during gameplay.
213 public void updateBackgroundImage() {
214 this.gameComponent.updateBackgroundImage();
218 * Updates the backgroundimage with new information from supplied MapSquare,
219 * for example when MapSquare are changed during gameplay.
221 * @param square A MapSquare with new informatin to be painted.
223 public void updateBackgroundImage(MapSquare square) {
224 this.gameComponent.updateBackgroundImage(square);
228 * Calls repaint on the GameComponent.
230 public void repaintGame() {
231 gameComponent.repaint();
235 * Update and repaint Pause menu information.
237 public void updatePauseMenu(final String TEXT) {
238 SwingUtilities.invokeLater(new Runnable() {
239 public void run() {
240 ATDView.this.pausMenuItem.setText(TEXT);
246 * Update and repaint Pause menu information.
248 public void updateMuteMenu(final String TEXT) {
249 SwingUtilities.invokeLater(new Runnable() {
250 public void run() {
251 ATDView.this.muteMenuItem.setText(TEXT);
257 * Prints a message to messageLabel, previous message is erased.
259 public void printMessage(final String TEXT) {
260 SwingUtilities.invokeLater(new Runnable() {
261 public void run() {
262 ATDView.this.messageLabel.setText(TEXT);
268 * Updates the numbers on the scoreboard
270 public void updateScoreboard() {
271 SwingUtilities.invokeLater(new Runnable() {
272 public void run() {
273 scoreboard.setText("Credit:\t" + model.getCredit() + "\n" +
274 "Score:\t" + model.getScore() + "\n" +
275 "Cleared units:\t" + model.getNumOfClearedUnits()
276 + "/" + model.getUnitsToWin());
281 public String promtForHighScoreEntry() {
282 String message = "Want to send in a highscore, what's your username?";
283 String title = "Enter highscore";
284 String result = JOptionPane.showInputDialog(
285 frame, message, title, JOptionPane.PLAIN_MESSAGE);
286 return result;
290 * Prompts user to play next level or restart current level
291 * @return 0 for option next level
292 * @return 1 for option restart current level
294 public int showLevelCompleteDialog() {
295 String title = "Level completed";
296 String message = "Congratulations! You have completed this level.";
297 String[] options = new String[2];
298 options[0] = "Next level";
299 options[1] = "Restart level";
301 int index = JOptionPane.showOptionDialog(frame,
302 message,
303 title,
304 JOptionPane.YES_NO_OPTION,
305 JOptionPane.QUESTION_MESSAGE,
306 null, //do not use a custom Icon
307 options, //the titles of buttons
308 options[0]); //default button title
309 return index;
313 * Prompts user to start a new game or quit application
314 * @return 0 for option new game
315 * @return 1 for option quit application
318 public int showLevelLostDialog() {
319 String title = "Level lost";
320 String message = "You failed to complete the level.\n" +
321 "Play a new game or quit application";
322 String[] options = new String[2];
323 options[0] = "Play new game";
324 options[1] = "Quit application";
326 int index = JOptionPane.showOptionDialog(frame,
327 message,
328 title,
329 JOptionPane.YES_NO_OPTION,
330 JOptionPane.QUESTION_MESSAGE,
331 null, //do not use a custom Icon
332 options, //the titles of buttons
333 options[0]); //default button title
334 return index;
338 public void showAboutDialog() {
339 // TODO Auto-generated method stub
340 String title = "About";
341 String message = "*** Anti-tower Defence (alfa) ***" +
342 "\n\nCreated by:\n" +
343 "Andreas Jakobsson (dit06ajs@cs.umu.se)\n" +
344 "Anton Johansson (dit06ajn@cs.umu.se)";
345 JOptionPane.showMessageDialog(frame,
346 message,
347 title,
348 JOptionPane.INFORMATION_MESSAGE,
349 null);
352 public void showHelpDialog() {
353 // TODO Auto-generated method stub
354 String title = "Help";
355 JTextArea message = new JTextArea("Instructions\n" +
356 "The goal for Anti-tower Defence is to release units " +
357 "from start squares in such a way that they reach goal " +
358 "squares without being killed by towers. When enough " +
359 "units has made it to goal squares you have completed " +
360 "the level\n",1,40);
361 message.setOpaque(false);
362 message.setEditable(false);
363 message.setLineWrap(true);
364 JOptionPane.showMessageDialog(frame,
365 message,
366 title,
367 JOptionPane.INFORMATION_MESSAGE,
368 null);
372 * GameComponent is the componenent on which the Level and all Units and
373 * Towers is shown.
375 private class GameComponent extends JComponent {
376 private Image backgroundImage;
377 // TODO: Se if its possible to change to Image
378 private BufferedImage gameImage;
380 private int width;
381 private int height;
383 public GameComponent() {
384 super();
385 this.width = (int) model.getMapDimension().getWidth();
386 this.height = (int) model.getMapDimension().getHeight();
387 this.setPreferredSize(model.getMapDimension());
389 // Background Image
390 this.backgroundImage = model.getMapImage();
392 // Game Image
393 this.gameImage = new BufferedImage(width, height,
394 BufferedImage.TYPE_INT_ARGB);
395 ATDView.this.gameGraphics = gameImage.createGraphics();
398 public void updateBackgroundImage() {
399 this.backgroundImage = model.getMapImage();
402 public void updateBackgroundImage(MapSquare square) {
403 Graphics g = this.backgroundImage.getGraphics();
404 square.paint(g);
408 * Ovverrides standard paintComponent, used to only repaint information
409 * about Unit and Tower information.
411 * @param g The Graphics used to update visual information.
413 @Override
414 public void paintComponent(Graphics g) {
415 logger.fine("paintComponent: " + Thread.currentThread().toString());
417 // Draw backgroundImage
418 g.drawImage(backgroundImage, 0, 0, null);
420 // Draw gameImage which should contain updated information from
421 // Controller
422 g.drawImage(gameImage, 0, 0, null);
424 // Clear gameImage image with a big transparent rectangle.
425 Color transparent = new Color(0, 0, 0, 0);
426 gameGraphics.setColor(transparent);
427 gameGraphics.setComposite(AlphaComposite.Src);
428 gameGraphics.fill(new Rectangle2D.Double(0, 0, width, height));
432 /* Set Listener methods ******************************/
434 // TODO: Good way to not cast and not be to specific?
435 public void addClosingListener(EventListener el) {
436 this.quitMenuItem.addActionListener((ActionListener) el);
437 this.frame.addWindowListener((WindowListener) el);
440 // Set menu item listeners
441 public void addNewGameMenuItemListener(ActionListener al) {
442 this.newGameMenuItem.addActionListener(al);
445 public void addRestartLevelMenuItemListener(ActionListener al) {
446 this.restartLevelMenuItem.addActionListener(al);
449 public void addPauseMenuItemListener(ActionListener al) {
450 this.pausMenuItem.addActionListener(al);
453 public void addMuteMenuItemListener(ActionListener al) {
454 this.muteMenuItem.addActionListener(al);
457 public void addHelpMenuItemListener(ActionListener al) {
458 this.helpMenuItem.addActionListener(al);
461 public void addAboutMenuItemListener(ActionListener al) {
462 this.aboutMenuItem.addActionListener(al);
465 // Controls
466 public void addReleaseUnitListener(ActionListener al) {
467 this.releaseUnitsButton.addActionListener(al);
470 public void addMapListener(MouseListener ml) {
471 gameComponent.addMouseListener(ml);