001 package swingui; 002 003 import java.awt.Dimension; 004 import java.awt.GridLayout; 005 import java.awt.event.ActionEvent; 006 import java.awt.event.ActionListener; 007 import java.awt.event.MouseAdapter; 008 import java.awt.event.MouseEvent; 009 import java.util.HashMap; 010 import java.util.HashSet; 011 import java.util.Map; 012 import java.util.Set; 013 014 import javax.swing.JButton; 015 import javax.swing.JPanel; 016 017 import physics3d.GameConstants; 018 import physics3d.Vect3; 019 020 import components.*; 021 022 /** AddPanel is a panel that contains a multitude of buttons for adding, moving, and deleting objects. 023 * <p> 024 * It contains a reference to the currently selected object and has private MouseListener classes 025 * for each type of action. 026 * <p> 027 * When a button on the AddPanel is clicked, the corresponding MouseListener is registered with 028 * the canvas (game play area). Then on subsequent clicks on the canvas, the action corresponsding 029 * to the button will be executed. 030 * <p> 031 * For example, if the user clicks on "Add Square Bumper", the AddSquareListener is registered with 032 * the game area. Then when the user next clicks on an empty space in the gamearea, a square bumper 033 * will be added to that spot. 034 * <p> 035 * @author ruthdhan 036 * 037 */ 038 public class AddPanel extends JPanel { 039 public static final long serialVersionUID = 0; 040 041 //components 042 private JButton addBall, addSquare, addCircle, addTriangle, addLeft, addRight, addAbs; 043 //move and delete 044 private JButton move, delete, select; 045 //the main gui 046 private MainGUI gui; 047 048 //listeners 049 private ButtonListener bl; 050 private AddBallListener abl; 051 private AddSquareListener asl; 052 private AddCircleListener acl; 053 private AddTriangleListener atl; 054 private AddLeftListener all; 055 private AddRightListener arl; 056 private AddAbsListener aal; 057 private MoveListener ml; 058 private DeleteListener dl; 059 private SelectListener sl; 060 061 //the selected object 062 private GameObject selected; 063 064 //static counter 065 private static int ID_NUM = 0; //starts at zero 066 067 /** Create a new AddPanel. Adds all buttons and registers them with listeners. **/ 068 public AddPanel(MainGUI gui) { 069 super(); 070 this.gui = gui; 071 072 //listeners -- one per button 073 bl = new ButtonListener(); 074 abl = new AddBallListener(); 075 asl = new AddSquareListener(); 076 acl = new AddCircleListener(); 077 atl = new AddTriangleListener(); 078 all = new AddLeftListener(); 079 arl = new AddRightListener(); 080 aal = new AddAbsListener(); 081 ml = new MoveListener(); 082 dl = new DeleteListener(); 083 sl = new SelectListener(); 084 085 //initialize components 086 addBall = new JButton("Add Ball"); 087 addBall.addActionListener(bl); 088 089 addSquare = new JButton("Add Square\n Bumper"); 090 addSquare.addActionListener(bl); 091 092 addCircle = new JButton("Add Circle\n Bumper"); 093 addCircle.addActionListener(bl); 094 095 addTriangle = new JButton("Add Triangle\n Bumper"); 096 addTriangle.addActionListener(bl); 097 098 addLeft = new JButton("Add Left\n Flipper"); 099 addLeft.addActionListener(bl); 100 101 addRight = new JButton("Add Right\n Flipper"); 102 addRight.addActionListener(bl); 103 104 addAbs = new JButton("Add \nAbsorber"); 105 addAbs.addActionListener(bl); 106 107 move = new JButton("Move"); 108 move.addActionListener(bl); 109 110 delete = new JButton("Delete"); 111 delete.addActionListener(bl); 112 113 select = new JButton("Select"); 114 select.addActionListener(bl); 115 116 //add to layout 117 this.setLayout(new GridLayout(0, 1)); //1 column 118 this.setPreferredSize(new Dimension(225, 300)); 119 this.setMaximumSize(new Dimension(200, 300)); 120 121 //row 1: ball 122 add(addBall); 123 124 //row 2-3: sq & tri 125 add(addSquare); 126 add(addTriangle); 127 128 //row 4-7: circle & abs 129 add(addCircle); 130 add(addAbs); 131 add(addLeft); 132 add(addRight); 133 134 //row 8: move & del 135 JPanel moveDelPanel = new JPanel(); 136 moveDelPanel.add(move); 137 moveDelPanel.add(delete); 138 add(moveDelPanel); 139 140 //row 9: select 141 add(select); 142 } 143 144 /** enable all buttons on this panel */ 145 public void activate() { 146 addBall.setEnabled(true); 147 addSquare.setEnabled(true); 148 addCircle.setEnabled(true); 149 addTriangle.setEnabled(true); 150 addLeft.setEnabled(true); 151 addRight.setEnabled(true); 152 addAbs.setEnabled(true); 153 move.setEnabled(true); 154 delete.setEnabled(true); 155 select.setEnabled(true); 156 } 157 /** disable all buttons on this panel. now the panel will not intercept keystrokes **/ 158 public void deactivate() { 159 addBall.setEnabled(false); 160 addSquare.setEnabled(false); 161 addCircle.setEnabled(false); 162 addTriangle.setEnabled(false); 163 addLeft.setEnabled(false); 164 addRight.setEnabled(false); 165 addAbs.setEnabled(false); 166 move.setEnabled(false); 167 delete.setEnabled(false); 168 select.setEnabled(false); 169 } 170 171 /** This is what listens for the actual mouse clicks on AddPanel. **/ 172 private class ButtonListener implements ActionListener { 173 public void actionPerformed(ActionEvent e) { 174 //unselects whatever is currently selected 175 if (selected != null) { 176 selected.setSelected(false); 177 selected = null; 178 gui.getCanvas().display(); 179 } 180 gui.getDetailPanel().clear(); 181 if (e.getSource().equals(addBall)) { 182 ////System.out.println("clicked ball"); 183 gui.setCurrentListener(abl); 184 } else if (e.getSource().equals(addSquare)) { 185 ////System.out.println("clicked square"); 186 gui.setCurrentListener(asl); 187 } else if (e.getSource().equals(addCircle)) { 188 ////System.out.println("clicked circle"); 189 gui.setCurrentListener(acl); 190 } else if (e.getSource().equals(addTriangle)) { 191 ////System.out.println("clicked triangle"); 192 gui.setCurrentListener(atl); 193 } else if (e.getSource().equals(addLeft)) { 194 ////System.out.println("clicked left"); 195 gui.setCurrentListener(all); 196 } else if (e.getSource().equals(addRight)) { 197 ////System.out.println("clicked right"); 198 gui.setCurrentListener(arl); 199 } else if (e.getSource().equals(addAbs)) { 200 ////System.out.println("clicked abs"); 201 gui.setCurrentListener(aal); 202 } else if (e.getSource().equals(move)) { 203 ////System.out.println("clicked move"); 204 gui.setCurrentListener(ml); 205 } else if (e.getSource().equals(delete)) { 206 ////System.out.println("clicked delete"); 207 gui.setCurrentListener(dl); 208 } else if (e.getSource().equals(select)) { 209 ////System.out.println("clicked select"); 210 gui.setCurrentListener(sl); 211 } 212 } 213 } 214 215 //true if gridLoc already occupied 216 private boolean gridOccupied(Vect3 gridLoc) { 217 for (GameObject obj : gui.getGameSpace().getObjectsNoWalls()) { 218 for (Vect3 p : obj.getOccupiedPositions()) { 219 if (gridLoc.equals(p)) { 220 ////System.out.println("occupied"); 221 return true; 222 } 223 } 224 } 225 ////System.out.println("not occupied"); 226 return false; 227 } 228 229 //true if any of gls are occupied 230 private boolean gridOccupied(Set<Vect3> gls) { 231 ////System.out.println(" gls " + gls); 232 for (GameObject obj : gui.getGameSpace().getObjectsNoWalls()) { 233 ////System.out.println("opsss: " + obj.getOccupiedPositions()); 234 for (Vect3 p : obj.getOccupiedPositions()) { 235 if (gls.contains(p)) { 236 return true; 237 } 238 } 239 } 240 return false; 241 } 242 243 ///// 244 private class AddBallListener extends MouseAdapter { 245 @Override 246 public void mouseClicked(MouseEvent e) { 247 ////System.out.println("add ball" + e.getX() + ", " + e.getY()); 248 Vect3 p = gui.getGridLocation(e.getX(), e.getY()); 249 250 //add ball "properly" 251 Map<String, String> fmap = new HashMap<String, String>(); 252 fmap.put("x", String.valueOf(p.x() + .5)); 253 fmap.put("y", String.valueOf(p.y() + .5)); 254 fmap.put("z", String.valueOf(p.z() + .5)); 255 fmap.put("orientation", "0"); 256 fmap.put("name", "Ball" + ID_NUM); 257 Ball b = new Ball(fmap, gui.getGameSpace()); 258 259 Set<Vect3> ballOccupied = b.getOccupiedPositions(); 260 if (!gridOccupied(ballOccupied)) { 261 gui.getGameSpace().add(b); 262 //redraws 263 gui.getCanvas().display(); 264 265 //increments ID_NUM 266 ID_NUM ++; 267 } 268 } 269 } 270 271 private class AddSquareListener extends MouseAdapter { 272 @Override 273 public void mouseClicked(MouseEvent e) { 274 ////System.out.println("add square " + e.getX() + ", " + e.getY()); 275 ////System.out.println(gui.getGridLocation(e.getX(), e.getY())); 276 Vect3 p = gui.getGridLocation(e.getX(), e.getY()); 277 // add square bumper 278 if (!gridOccupied(p)) { 279 //creates bumper and puts it in gamespace 280 Map<String, String> fmap = new HashMap<String, String>(); 281 fmap.put("x", String.valueOf(p.x())); 282 fmap.put("y", String.valueOf(p.y())); 283 fmap.put("z", String.valueOf(p.z())); 284 fmap.put("orientation", "0"); 285 fmap.put("name", "SquareBumper" + ID_NUM); 286 SquareBumper sb = new SquareBumper(fmap, gui.getGameSpace()); 287 gui.getGameSpace().add(sb); 288 //redraws 289 gui.getCanvas().display(); 290 291 //increments ID_NUM 292 ID_NUM++; 293 } 294 } 295 } 296 297 private class AddCircleListener extends MouseAdapter { 298 @Override 299 public void mouseClicked(MouseEvent e) { 300 ////System.out.println("add circle"); 301 Vect3 p = gui.getGridLocation(e.getX(), e.getY()); 302 if (!gridOccupied(p)) { 303 //creates bumper and puts it in gamespace 304 Map<String, String> fmap = new HashMap<String, String>(); 305 fmap.put("x", String.valueOf(p.x())); 306 fmap.put("y", String.valueOf(p.y())); 307 fmap.put("z", String.valueOf(p.z())); 308 fmap.put("orientation", "0"); 309 fmap.put("name", "CircleBumper" + ID_NUM); 310 CircleBumper cb = new CircleBumper(fmap, gui.getGameSpace()); 311 gui.getGameSpace().add(cb); 312 //redraws 313 gui.getCanvas().display(); 314 315 // increments ID_NUM 316 ID_NUM++; 317 } 318 } 319 } 320 321 private class AddTriangleListener extends MouseAdapter { 322 @Override 323 public void mouseClicked(MouseEvent e) { 324 ////System.out.println("add triangle"); 325 Vect3 p = gui.getGridLocation(e.getX(), e.getY()); 326 if (!gridOccupied(p)) { 327 //creates bumper and puts it in gamespace 328 Map<String, String> fmap = new HashMap<String, String>(); 329 fmap.put("x", String.valueOf(p.x())); 330 fmap.put("y", String.valueOf(p.y())); 331 fmap.put("z", String.valueOf(p.z())); 332 fmap.put("orientation", "0"); 333 fmap.put("name", "TriangleBumper" + ID_NUM); 334 TriangleBumper tb = new TriangleBumper(fmap, gui.getGameSpace()); 335 gui.getGameSpace().add(tb); 336 //redraws 337 gui.getCanvas().display(); 338 339 340 //increments ID_NUM 341 ID_NUM++; 342 } 343 } 344 } 345 346 347 private class AddLeftListener extends MouseAdapter { 348 @Override 349 public void mouseClicked(MouseEvent e) { 350 ////System.out.println("add left"); 351 Vect3 p = gui.getGridLocation(e.getX(), e.getY()); 352 double r = GameConstants.FLIPPER_RADIUS_FRACTION; 353 //Flipper f = new Flipper(p, p.plus(new Vect3(r, r, 0.5)), Vect3.Z_HAT, Angle.ZERO, "left flipper", gui.getGameSpace()); 354 355 //creates left flipper 356 Map<String, String> fmap = new HashMap<String, String>(); 357 fmap.put("x", String.valueOf(p.x())); 358 fmap.put("y", String.valueOf(p.y())); 359 fmap.put("z", String.valueOf(p.z())); 360 fmap.put("orientation", "0"); 361 fmap.put("name", "LeftFlipper" + ID_NUM); 362 LeftFlipper f = new LeftFlipper(fmap, gui.getGameSpace()); 363 364 //checks if occupied 365 Set<Vect3> fOccupied = f.getOccupiedPositions(); 366 367 if (!gridOccupied(fOccupied)) { 368 gui.getGameSpace().add(f); 369 //redraws 370 gui.getCanvas().display(); 371 372 //increments ID_NUM 373 ID_NUM++; 374 } 375 } 376 } 377 378 private class AddRightListener extends MouseAdapter { 379 @Override 380 public void mouseClicked(MouseEvent e) { 381 ////System.out.println("add left"); 382 Vect3 p = gui.getGridLocation(e.getX(), e.getY()); 383 double r = GameConstants.FLIPPER_RADIUS_FRACTION; 384 //Flipper f = new Flipper(p, p.plus(new Vect3(2*(1-r), r, 0.5)), Vect3.Z_HAT, Angle.ZERO, "left flipper", gui.getGameSpace()); 385 386 //creates right flipper 387 Map<String, String> fmap = new HashMap<String, String>(); 388 fmap.put("x", String.valueOf(p.x())); 389 fmap.put("y", String.valueOf(p.y())); 390 fmap.put("z", String.valueOf(p.z())); 391 fmap.put("orientation", "0"); 392 fmap.put("name", "RightFlipper" + ID_NUM); 393 RightFlipper f = new RightFlipper(fmap, gui.getGameSpace()); 394 395 //checks if occupied 396 Set<Vect3> fOccupied = f.getOccupiedPositions(); 397 398 if (!gridOccupied(fOccupied)) { 399 gui.getGameSpace().add(f); 400 //redraws 401 gui.getCanvas().display(); 402 403 //increments ID_NUM 404 ID_NUM++; 405 } 406 } 407 } 408 409 private class AddAbsListener extends MouseAdapter { 410 @Override 411 public void mouseClicked(MouseEvent e) { 412 ////System.out.println("add abs"); 413 Vect3 p = gui.getGridLocation(e.getX(), e.getY()); 414 415 //creates absorber 416 Map<String, String> fmap = new HashMap<String, String>(); 417 fmap.put("x", String.valueOf(p.x())); 418 fmap.put("y", String.valueOf(p.y())); 419 fmap.put("z", String.valueOf(p.z())); 420 fmap.put("height", "1"); 421 fmap.put("width", "1"); 422 fmap.put("depth", "1"); 423 fmap.put("orientation", "0"); 424 fmap.put("name", "Absorber" + ID_NUM); 425 Absorber a = new Absorber(fmap, gui.getGameSpace()); 426 427 Set<Vect3> aOccupied = a.getOccupiedPositions(); 428 429 if (!gridOccupied(aOccupied)) { 430 ////System.out.println(a.getHeight() + " " + a.getWidth() + " " + a.getDepth() + "" + " absorber height"); 431 gui.getGameSpace().add(a); 432 //redraws 433 gui.getCanvas().display(); 434 435 //increments ID_NUM 436 ID_NUM++; 437 } 438 } 439 } 440 441 private class MoveListener extends MouseAdapter { 442 @Override 443 public void mousePressed(MouseEvent e) { 444 GameSpace gs = gui.getGameSpace(); 445 if (selected == null) { 446 Vect3 gridLoc = gui.getGridLocation(e.getX(), e.getY()); 447 selected = gui.getObjectInGrid(gridLoc); 448 if (selected != null) { 449 selected.setSelected(true); 450 gui.getCanvas().display(); 451 } 452 } else { 453 Vect3 gridLoc = gui.getGridLocation(e.getX(), e.getY()); 454 Vect3 oldLoc = selected.getTLF(); 455 456 //remember old loc and move to new; we'll move back if there's a problem 457 gs.removeObject(selected); 458 if (selected instanceof Ball) 459 selected.setTLF(gridLoc.plus(new Vect3(.5, .5, .5))); 460 else 461 selected.setTLF(gridLoc); 462 463 //if there's a problem, change it back 464 if (!gridOccupied(selected.getOccupiedPositions())) { 465 selected.setSelected(false); 466 //redraws 467 gui.getCanvas().display(); 468 gs.add(selected); //add back and unselect 469 selected = null; 470 } else { 471 selected.setTLF(oldLoc); 472 gs.add(selected); //add to oldloc, leave selected 473 } 474 } 475 } 476 477 } 478 479 private class DeleteListener extends MouseAdapter { 480 @Override 481 public void mouseClicked(MouseEvent e) { 482 GameSpace gs = gui.getGameSpace(); 483 Vect3 gridLoc = gui.getGridLocation(e.getX(), e.getY()); 484 selected = gui.getObjectInGrid(gridLoc); 485 if (selected != null) { 486 gs.removeObject(selected); 487 //redraws 488 gui.getCanvas().display(); 489 ////System.out.println("deleted something"); 490 } 491 } 492 } 493 494 private class SelectListener extends MouseAdapter { 495 @Override 496 public void mouseClicked(MouseEvent e) { 497 //if there's already something selected, clear it 498 if (selected != null) { 499 selected.setSelected(false); 500 gui.getDetailPanel().clear(); 501 } 502 //find out if we clicked on an actual object (or just space) 503 Vect3 gridLoc = gui.getGridLocation(e.getX(), e.getY()); 504 GameSpace gs = gui.getGameSpace(); 505 selected = gui.getObjectInGrid(gridLoc); 506 507 //if there's an object, select & update detail panel 508 if (selected != null) { 509 selected.setSelected(true); 510 gui.getDetailPanel().update(selected); 511 } 512 gui.getCanvas().display(); 513 } 514 } 515 516 517 /** the selected object, before he disaooered 518 * @return the selected 519 */ 520 public GameObject getSelected() { 521 return selected; 522 } 523 524 /** change the text on that emo-boy part 525 * @param selected the selected to set 526 */ 527 public void setSelected(GameObject selected) { 528 this.selected = selected; 529 } 530 531 /** @return a random six-character name **/ 532 public static String randomName() { 533 return "Object"+ID_NUM++; //increment after we use it 534 } 535 }