1 /* 2 * PlanComponentTest.java 31 mai 2006 3 * 4 * Copyright (c) 2006 Emmanuel PUYBARET / eTeks <info@eteks.com>. All Rights 5 * Reserved. 6 * 7 * This program is free software; you can redistribute it and/or modify it under 8 * the terms of the GNU General Public License as published by the Free Software 9 * Foundation; either version 2 of the License, or (at your option) any later 10 * version. 11 * 12 * This program is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 15 * details. 16 * 17 * You should have received a copy of the GNU General Public License along with 18 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 19 * Place, Suite 330, Boston, MA 02111-1307 USA 20 */ 21 package com.eteks.sweethome3d.junit; 22 23 import java.awt.BorderLayout; 24 import java.awt.Point; 25 import java.awt.event.ActionEvent; 26 import java.awt.event.ActionListener; 27 import java.awt.event.InputEvent; 28 import java.awt.event.KeyEvent; 29 import java.util.ArrayList; 30 import java.util.Collection; 31 import java.util.List; 32 import java.util.Locale; 33 34 import javax.swing.ImageIcon; 35 import javax.swing.JButton; 36 import javax.swing.JComponent; 37 import javax.swing.JFrame; 38 import javax.swing.JScrollPane; 39 import javax.swing.JToggleButton; 40 import javax.swing.JToolBar; 41 import javax.swing.undo.UndoManager; 42 import javax.swing.undo.UndoableEditSupport; 43 44 import junit.extensions.abbot.ComponentTestFixture; 45 import abbot.tester.ComponentLocation; 46 import abbot.tester.JComponentTester; 47 48 import com.eteks.sweethome3d.io.DefaultUserPreferences; 49 import com.eteks.sweethome3d.model.CollectionEvent; 50 import com.eteks.sweethome3d.model.CollectionListener; 51 import com.eteks.sweethome3d.model.DimensionLine; 52 import com.eteks.sweethome3d.model.Home; 53 import com.eteks.sweethome3d.model.Selectable; 54 import com.eteks.sweethome3d.model.UserPreferences; 55 import com.eteks.sweethome3d.model.Wall; 56 import com.eteks.sweethome3d.swing.PlanComponent; 57 import com.eteks.sweethome3d.swing.SwingViewFactory; 58 import com.eteks.sweethome3d.viewcontroller.PlanController; 59 import com.eteks.sweethome3d.viewcontroller.PlanView; 60 import com.eteks.sweethome3d.viewcontroller.ViewFactory; 61 62 /** 63 * Tests {@link com.eteks.sweethome3d.swing.PlanComponent plan} component and 64 * its {@link com.eteks.sweethome3d.viewcontroller.PlanController controller}. 65 * @author Emmanuel Puybaret 66 */ 67 public class PlanComponentTest extends ComponentTestFixture { testPlanComponentWithMouse()68 public void testPlanComponentWithMouse() { 69 // 1. Create a frame that displays a PlanComponent instance of 70 // a new home at 540 pixels by 400 preferred size, and a tool bar 71 // with a mode toggle button, an undo button and a redo button 72 final PlanTestFrame frame = new PlanTestFrame(); 73 // Show home plan frame 74 showWindow(frame); 75 PlanComponent planComponent = (PlanComponent)frame.planController.getView(); 76 assertEquals("Wrong preferred width", 540, planComponent.getWidth()); 77 78 // Build an ordered list of walls added to home 79 final ArrayList<Wall> orderedWalls = new ArrayList<Wall>(); 80 frame.home.addWallsListener(new CollectionListener<Wall>() { 81 public void collectionChanged(CollectionEvent<Wall> ev) { 82 if (ev.getType() == CollectionEvent.Type.ADD) { 83 orderedWalls.add(ev.getItem()); 84 } 85 } 86 }); 87 88 // 2. Use WALL_CREATION mode 89 JComponentTester tester = new JComponentTester(); 90 tester.actionClick(frame.modeButton); 91 assertEquals("Current mode isn't " + PlanController.Mode.WALL_CREATION, 92 PlanController.Mode.WALL_CREATION, frame.planController.getMode()); 93 // Click at (30, 30), (270, 31), (269, 170), then double click at (30, 171) 94 tester.actionClick(planComponent, 30, 30); 95 tester.actionClick(planComponent, 270, 31); 96 tester.actionClick(planComponent, 269, 170); 97 tester.actionClick(planComponent, 30, 171, InputEvent.BUTTON1_MASK, 2); 98 // Check 3 walls were created at (20, 20), (500, 20), (500, 300) and (20, 300) coordinates 99 Wall wall1 = orderedWalls.get(0); 100 assertCoordinatesEqualWallPoints(20, 20, 500, 20, wall1); 101 Wall wall2 = orderedWalls.get(1); 102 assertCoordinatesEqualWallPoints(500, 20, 500, 300, wall2); 103 Wall wall3 = orderedWalls.get(2); 104 assertCoordinatesEqualWallPoints(500, 300, 20, 300, wall3); 105 // Check the thickness and the height of first wall 106 assertEquals("Wrong wall tickness", frame.preferences.getNewWallThickness(), wall1.getThickness()); 107 assertEquals("Wrong wall height", frame.preferences.getNewWallHeight(), wall1.getHeight()); 108 assertEquals("Wrong wall height at end", null, wall1.getHeightAtEnd()); 109 // Check they are joined to each other end point 110 assertWallsAreJoined(null, wall1, wall2); 111 assertWallsAreJoined(wall1, wall2, wall3); 112 assertWallsAreJoined(wall2, wall3, null); 113 // Check they are selected 114 assertSelectionContains(frame.home, wall1, wall2, wall3); 115 116 // 3. Click at (30, 170), then double click at (50, 50) without magnetism 117 tester.actionClick(planComponent, 30, 170); 118 tester.actionKeyPress(TestUtilities.getMagnetismToggleKey()); 119 tester.actionClick(planComponent, 50, 50, InputEvent.BUTTON1_MASK, 2); 120 tester.actionKeyRelease(TestUtilities.getMagnetismToggleKey()); 121 // Check a forth wall was created at (20, 300), (60, 60) coordinates 122 Wall wall4 = orderedWalls.get(orderedWalls.size() - 1); 123 assertCoordinatesEqualWallPoints(20, 300, 60, 60, wall4); 124 assertSelectionContains(frame.home, wall4); 125 assertWallsAreJoined(wall3, wall4, null); 126 127 // 4. Use SELECTION mode 128 tester.actionClick(frame.modeButton); 129 // Check current mode is SELECTION 130 assertEquals("Current mode isn't " + PlanController.Mode.SELECTION, 131 PlanController.Mode.SELECTION, frame.planController.getMode()); 132 // Give focus to plan component 133 tester.actionFocus(planComponent); 134 // Press the delete key 135 tester.actionKeyStroke(KeyEvent.VK_DELETE); 136 // Check plan contains only the first three walls 137 assertHomeContains(frame.home, wall1, wall2, wall3); 138 139 // 5. Use WALL_CREATION mode 140 tester.actionClick(frame.modeButton); 141 // Click at (31, 29), then double click at (30, 170) 142 tester.actionClick(planComponent, 31, 29); 143 tester.actionClick(planComponent, 30, 170, InputEvent.BUTTON1_MASK, 2); 144 // Check a new forth wall was created at (20, 20), (20, 300) coordinates 145 wall4 = orderedWalls.get(orderedWalls.size() - 1); 146 assertCoordinatesEqualWallPoints(20, 20, 20, 300, wall4); 147 // Check its end points are joined to the first and third wall 148 assertWallsAreJoined(wall1, wall4, wall3); 149 150 // 6. Use SELECTION mode 151 tester.actionClick(frame.modeButton); 152 // Drag and drop cursor from (200, 100) to (300, 180) 153 tester.actionMousePress(planComponent, 154 new ComponentLocation(new Point(200, 100))); 155 tester.actionMouseMove(planComponent, 156 new ComponentLocation(new Point(300, 180))); 157 tester.actionMouseRelease(); 158 // Check the selected walls are the second and third ones 159 assertSelectionContains(frame.home, wall2, wall3); 160 161 // 7. Press twice right arrow key 162 tester.actionKeyStroke(KeyEvent.VK_RIGHT); 163 tester.actionKeyStroke(KeyEvent.VK_RIGHT); 164 // Check the 4 walls coordinates are (20, 20), (504, 20), (504, 300), (24, 300) 165 assertCoordinatesEqualWallPoints(20, 20, 504, 20, wall1); 166 assertCoordinatesEqualWallPoints(504, 20, 504, 300, wall2); 167 assertCoordinatesEqualWallPoints(504, 300, 24, 300, wall3); 168 assertCoordinatesEqualWallPoints(20, 20, 24, 300, wall4); 169 170 // 8. Click at (272, 40) with Shift key depressed 171 tester.actionKeyPress(KeyEvent.VK_SHIFT); 172 tester.actionClick(planComponent, 272, 40); 173 tester.actionKeyRelease(KeyEvent.VK_SHIFT); 174 // Check the second wall was removed from selection 175 assertSelectionContains(frame.home, wall3); 176 177 // 9. Drag cursor from (50, 30) to (50, 50) 178 tester.actionMousePress(planComponent, 179 new ComponentLocation(new Point(50, 30))); 180 tester.actionMouseMove(planComponent, 181 new ComponentLocation(new Point(50, 50))); 182 // Check first wall is selected and that it moved 183 assertSelectionContains(frame.home, wall1); 184 assertCoordinatesEqualWallPoints(20, 60, 504, 60, wall1); 185 // Lose focus 186 tester.actionKeyStroke(KeyEvent.VK_TAB); 187 // Check the wall didn't move at end 188 assertCoordinatesEqualWallPoints(20, 20, 504, 20, wall1); 189 190 // 10. Click 6 times on undo button 191 for (int i = 0; i < 6; i++) { 192 tester.invokeAndWait(new Runnable() { 193 public void run() { 194 frame.undoButton.doClick(); 195 } 196 }); 197 } 198 // Check home doesn't contain any wall 199 assertHomeContains(frame.home); 200 201 // 11. Click 6 times on redo button 202 for (int i = 0; i < 6; i++) { 203 tester.invokeAndWait(new Runnable() { 204 public void run() { 205 frame.redoButton.doClick(); 206 } 207 }); 208 } 209 // Check plan contains the four wall 210 assertHomeContains(frame.home, wall1, wall2, wall3, wall4); 211 // Check they are joined to each other end point 212 assertWallsAreJoined(wall4, wall1, wall2); 213 assertWallsAreJoined(wall1, wall2, wall3); 214 assertWallsAreJoined(wall2, wall3, wall4); 215 assertWallsAreJoined(wall1, wall4, wall3); 216 // Check the second and the third wall are selected 217 assertSelectionContains(frame.home, wall2, wall3); 218 219 // 12. Reverse directions of selected walls 220 float xStartWall2 = wall2.getXStart(); 221 float yStartWall2 = wall2.getYStart(); 222 float xStartWall3 = wall3.getXStart(); 223 float yStartWall3 = wall3.getYStart(); 224 float xEndWall3 = wall3.getXEnd(); 225 float yEndWall3 = wall3.getYEnd(); 226 tester.invokeAndWait(new Runnable() { 227 public void run() { 228 frame.reverseDirectionButton.doClick(); 229 } 230 }); 231 // Check the second and the third wall are still selected 232 assertSelectionContains(frame.home, wall2, wall3); 233 // Check wall2 and wall3 were reserved 234 assertCoordinatesEqualWallPoints(xStartWall3, yStartWall3, xStartWall2, yStartWall2, wall2); 235 assertCoordinatesEqualWallPoints(xEndWall3, yEndWall3, xStartWall3, yStartWall3, wall3); 236 assertWallsAreJoined(wall3, wall2, wall1); 237 assertWallsAreJoined(wall4, wall3, wall2); 238 239 // 13. Select first wall 240 tester.actionClick(planComponent, 100, 100); // Give focus first 241 tester.actionClick(planComponent, 40, 30); 242 // Drag cursor from (30, 30) to (50, 50) without magnetism 243 tester.actionMousePress(planComponent, 244 new ComponentLocation(new Point(30, 30))); 245 tester.actionMouseMove(planComponent, 246 new ComponentLocation(new Point(50, 50))); 247 tester.actionKeyPress(TestUtilities.getMagnetismToggleKey()); 248 tester.waitForIdle(); 249 tester.actionMouseRelease(); 250 tester.actionKeyRelease(TestUtilities.getMagnetismToggleKey()); 251 // Check wall start point moved to (60, 60) 252 assertCoordinatesEqualWallPoints(60, 60, 504, 20, wall1); 253 assertCoordinatesEqualWallPoints(60, 60, 24, 300, wall4); 254 255 // 14. Select first wall 256 tester.actionClick(planComponent, 60, 50); 257 assertSelectionContains(frame.home, wall1); 258 // Split first wall in two walls 259 tester.actionClick(frame.splitButton); 260 Wall wall5 = orderedWalls.get(orderedWalls.size() - 2); 261 Wall wall6 = orderedWalls.get(orderedWalls.size() - 1); 262 assertSelectionContains(frame.home, wall5); 263 assertCoordinatesEqualWallPoints(60, 60, 282, 40, wall5); 264 assertCoordinatesEqualWallPoints(282, 40, 504, 20, wall6); 265 assertWallsAreJoined(wall4, wall5, wall6); 266 assertWallsAreJoined(wall5, wall6, wall2); 267 assertFalse("Split wall still present in home", frame.home.getWalls().contains(wall1)); 268 // Check walls have a new id 269 assertFalse("Walls have same id", wall1.getId().equals(wall5.getId())); 270 assertFalse("Walls have same id", wall1.getId().equals(wall6.getId())); 271 assertFalse("Walls have same id", wall5.getId().equals(wall6.getId())); 272 // Undo operation and check undone state 273 tester.actionClick(frame.undoButton); 274 assertSelectionContains(frame.home, wall1); 275 assertCoordinatesEqualWallPoints(60, 60, 504, 20, wall1); 276 assertWallsAreJoined(wall4, wall1, wall2); 277 assertTrue("Split wall not present in home", frame.home.getWalls().contains(wall1)); 278 assertFalse("Wall still present in home", frame.home.getWalls().contains(wall5)); 279 assertFalse("Wall still present in home", frame.home.getWalls().contains(wall6)); 280 } 281 testPlanComponentWithKeyboard()282 public void testPlanComponentWithKeyboard() throws InterruptedException { 283 // 1. Create a frame that displays a PlanComponent instance 284 PlanTestFrame frame = new PlanTestFrame(); 285 // Show home plan frame 286 showWindow(frame); 287 PlanComponent planComponent = (PlanComponent)frame.planController.getView(); 288 289 // Build an ordered list of walls added to home 290 final ArrayList<Wall> orderedWalls = new ArrayList<Wall>(); 291 frame.home.addWallsListener(new CollectionListener<Wall>() { 292 public void collectionChanged(CollectionEvent<Wall> ev) { 293 if (ev.getType() == CollectionEvent.Type.ADD) { 294 orderedWalls.add(ev.getItem()); 295 } 296 } 297 }); 298 299 // 2. Create walls with keyboard 300 frame.planController.setMode(PlanController.Mode.WALL_CREATION); 301 assertEquals("Current mode isn't " + PlanController.Mode.WALL_CREATION, 302 PlanController.Mode.WALL_CREATION, frame.planController.getMode()); 303 planComponent.requestFocus(); 304 JComponentTester tester = new JComponentTester(); 305 tester.waitForIdle(); 306 assertTrue("Plan component doesn't have focus", planComponent.hasFocus()); 307 tester.actionKeyStroke(KeyEvent.VK_ENTER); 308 // Enter the coordinates of the start point 309 tester.actionKeyString("10"); 310 tester.actionKeyStroke(KeyEvent.VK_TAB); 311 tester.actionKeyString("21"); 312 tester.actionKeyStroke(KeyEvent.VK_ENTER); 313 // Enter the length of the wall 314 tester.actionKeyString("200"); 315 tester.actionKeyStroke(KeyEvent.VK_ENTER); 316 // Create a wall with same length 317 Thread.sleep(500); 318 tester.actionKeyStroke(KeyEvent.VK_ENTER); 319 // Create a wall with same length, an angle at 270� and a thickness of 7,55 cm 320 tester.actionKeyStroke(KeyEvent.VK_DOWN); 321 tester.actionKeyStroke(KeyEvent.VK_HOME); 322 tester.actionKeyString("27"); 323 tester.actionKeyStroke(KeyEvent.VK_DELETE); // Remove the 9 digit 324 tester.actionKeyStroke(KeyEvent.VK_UP); 325 tester.actionKeyStroke(KeyEvent.VK_UP); 326 tester.actionKeyStroke(KeyEvent.VK_END); 327 tester.actionKeyString("5 "); 328 tester.actionKeyStroke(KeyEvent.VK_ENTER); 329 tester.actionKeyStroke(KeyEvent.VK_ESCAPE); 330 // Check created walls 331 assertEquals("Wrong walls count", 3, frame.home.getWalls().size()); 332 Wall wall1 = orderedWalls.get(0); 333 assertCoordinatesEqualWallPoints(10, 21, 210, 21, wall1); 334 Wall wall2 = orderedWalls.get(1); 335 assertCoordinatesEqualWallPoints(210, 21, 210, 221, wall2); 336 assertEquals("Wrong wall thickness", wall1.getThickness(), wall2.getThickness()); 337 Wall wall3 = orderedWalls.get(2); 338 assertCoordinatesEqualWallPoints(210, 221, 410, 221, wall3); 339 assertEquals("Wrong wall thickness", 340 Float.parseFloat(String.valueOf(wall1.getThickness()) + "5"), wall3.getThickness()); 341 assertWallsAreJoined(wall1, wall2, wall3); 342 assertSelectionContains(frame.home, wall1, wall2, wall3); 343 344 // 3. Mix mouse and keyboard to create other walls 345 tester.actionClick(planComponent, 300, 200); 346 tester.actionMouseMove(planComponent, 347 new ComponentLocation(new Point(310, 200))); 348 tester.actionKeyStroke(KeyEvent.VK_ENTER); 349 // Enter the length and the angle of the wall 350 tester.actionKeyString("100"); 351 tester.actionKeyStroke(KeyEvent.VK_TAB); 352 tester.actionKeyString("315"); 353 tester.actionKeyStroke(KeyEvent.VK_ENTER); 354 // Create 3 walls with same length 355 Thread.sleep(500); 356 tester.actionKeyStroke(KeyEvent.VK_ENTER); 357 Thread.sleep(500); 358 tester.actionKeyStroke(KeyEvent.VK_ENTER); 359 // Take control with mouse 360 tester.actionMouseMove(planComponent, 361 new ComponentLocation(new Point(200, 200))); 362 tester.actionKeyPress(TestUtilities.getMagnetismToggleKey()); 363 Wall wall7 = orderedWalls.get(7); 364 assertCoordinatesEqualWallPoints(wall7.getXStart(), wall7.getYStart(), 365 planComponent.convertXPixelToModel(200), 366 planComponent.convertYPixelToModel(200), wall7); 367 tester.waitForIdle(); 368 tester.actionKeyRelease(TestUtilities.getMagnetismToggleKey()); 369 // Take control again with keyboard and close the walls square 370 tester.actionKeyStroke(KeyEvent.VK_ENTER); 371 tester.actionKeyString("100"); 372 tester.actionKeyStroke(KeyEvent.VK_TAB); 373 tester.actionKeyString("90"); 374 tester.actionKeyStroke(KeyEvent.VK_ENTER); 375 // Check created walls 376 assertEquals("Wrong walls count", 7, frame.home.getWalls().size()); 377 Wall wall4 = orderedWalls.get(4); 378 Wall wall5 = orderedWalls.get(5); 379 Wall wall6 = orderedWalls.get(6); 380 assertSelectionContains(frame.home, wall4, wall5, wall6, wall7); 381 assertWallsAreJoined(wall6, wall7, wall4); 382 383 // 4. Create a dimension line with keyboard 384 frame.planController.setMode(PlanController.Mode.DIMENSION_LINE_CREATION); 385 assertEquals("Current mode isn't " + PlanController.Mode.DIMENSION_LINE_CREATION, 386 PlanController.Mode.DIMENSION_LINE_CREATION, frame.planController.getMode()); 387 tester.actionClick(planComponent, 200, 300); 388 tester.actionKeyStroke(KeyEvent.VK_ENTER); 389 tester.actionKeyString("250"); // x start 390 tester.actionKeyStroke(KeyEvent.VK_ENTER); 391 tester.actionKeyString("200"); // length 392 tester.actionKeyStroke(KeyEvent.VK_TAB); 393 tester.actionKeyString("45"); // angle 394 tester.actionKeyStroke(KeyEvent.VK_ENTER); 395 tester.actionKeyString("50"); // offset 396 tester.actionKeyStroke(KeyEvent.VK_ENTER); 397 398 399 Collection<DimensionLine> dimensionLines = frame.home.getDimensionLines(); 400 assertEquals("Incorrect dimension lines count", 1, dimensionLines.size()); 401 DimensionLine dimensionLine = dimensionLines.iterator().next(); 402 assertTrue("Incorrect X start " + 250 + " " + dimensionLine.getXStart(), 403 Math.abs(250 - dimensionLine.getXStart()) < 1E-10); 404 assertTrue("Incorrect Y start " + 560 + " " + dimensionLine.getYStart(), 405 Math.abs(560 - dimensionLine.getYStart()) < 1E-10); 406 assertTrue("Incorrect X end " + 391.421 + " " + dimensionLine.getXEnd(), 407 Math.abs(391.421 - dimensionLine.getXEnd()) < 1E-3); 408 assertTrue("Incorrect Y end " + 418.579 + " " + dimensionLine.getYEnd(), 409 Math.abs(418.579 - dimensionLine.getYEnd()) < 1E-3); 410 assertTrue("Incorrect offset " + 50 + " " + dimensionLine.getYEnd(), 411 Math.abs(50 - dimensionLine.getOffset()) < 1E-10); 412 } 413 414 /** 415 * Asserts the start point and the end point of 416 * <code>wall</code> are at (<code>xStart</code>, <code>yStart</code>), (<code>xEnd</code>, <code>yEnd</code>). 417 */ assertCoordinatesEqualWallPoints(float xStart, float yStart, float xEnd, float yEnd, Wall wall)418 private void assertCoordinatesEqualWallPoints(float xStart, float yStart, float xEnd, float yEnd, Wall wall) { 419 assertTrue("Incorrect X start " + xStart + " " + wall.getXStart(), 420 Math.abs(xStart - wall.getXStart()) < 1E-4); 421 assertTrue("Incorrect Y start " + yStart + " " + wall.getYStart(), 422 Math.abs(yStart - wall.getYStart()) < 1E-4); 423 assertTrue("Incorrect X end " + xEnd + " " + wall.getXEnd(), 424 Math.abs(xEnd - wall.getXEnd()) < 1E-4); 425 assertTrue("Incorrect Y end " + yEnd + " " + wall.getYEnd(), 426 Math.abs(yEnd - wall.getYEnd()) < 1E-4); 427 } 428 429 /** 430 * Asserts <code>wall</code> is joined to <code>wallAtStart</code> 431 * and <code>wallAtEnd</code>. 432 */ assertWallsAreJoined(Wall wallAtStart, Wall wall, Wall wallAtEnd)433 private void assertWallsAreJoined(Wall wallAtStart, Wall wall, Wall wallAtEnd) { 434 assertSame("Incorrect wall at start", wallAtStart, wall.getWallAtStart()); 435 assertSame("Incorrect wall at end", wallAtEnd, wall.getWallAtEnd()); 436 } 437 438 /** 439 * Asserts <code>home</code> contains <code>walls</code>. 440 */ assertHomeContains(Home home, Wall ... walls)441 private void assertHomeContains(Home home, Wall ... walls) { 442 Collection<Wall> planWalls = home.getWalls(); 443 assertEquals("Home walls incorrect count", 444 walls.length, planWalls.size()); 445 for (Wall wall : walls) { 446 assertTrue("Wall doesn't belong to plan", planWalls.contains(wall)); 447 } 448 } 449 450 /** 451 * Asserts <code>walls</code> are the current selected ones in <code>home</code>. 452 */ assertSelectionContains(Home home, Wall ... walls)453 private void assertSelectionContains(Home home, 454 Wall ... walls) { 455 List<Selectable> selectedItems = home.getSelectedItems(); 456 assertEquals(walls.length, selectedItems.size()); 457 for (Wall wall : walls) { 458 assertTrue("Wall not selected", selectedItems.contains(wall)); 459 } 460 } 461 main(String [] args)462 public static void main(String [] args) { 463 JFrame frame = new PlanTestFrame(); 464 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 465 frame.setVisible(true); 466 } 467 468 private static class PlanTestFrame extends JFrame { 469 private final UserPreferences preferences; 470 private final Home home; 471 private final PlanController planController; 472 private final JToggleButton modeButton; 473 private final JButton undoButton; 474 private final JButton redoButton; 475 private final JButton reverseDirectionButton; 476 private final JButton splitButton; 477 PlanTestFrame()478 public PlanTestFrame() { 479 super("Plan Component Test"); 480 // Create model objects 481 this.home = new Home(); 482 this.home.getCompass().setVisible(false); 483 Locale.setDefault(Locale.FRANCE); 484 this.preferences = new DefaultUserPreferences(); 485 ViewFactory viewFactory = new SwingViewFactory() { 486 @Override 487 public PlanView createPlanView(Home home, UserPreferences preferences, PlanController controller) { 488 return new PlanComponent(home, preferences, controller); 489 } 490 }; 491 UndoableEditSupport undoSupport = new UndoableEditSupport(); 492 final UndoManager undoManager = new UndoManager(); 493 undoSupport.addUndoableEditListener(undoManager); 494 this.planController = new PlanController(this.home, this.preferences, viewFactory, null, undoSupport); 495 // Add plan component to frame at its preferred size 496 add(new JScrollPane((JComponent)this.planController.getView())); 497 // Create a toggle button for plan component mode 498 this.modeButton = new JToggleButton(new ImageIcon( 499 getClass().getResource("resources/Add16.gif"))); 500 // Add listeners to modeButton that manages plan planController mode 501 this.modeButton.addActionListener(new ActionListener() { 502 public void actionPerformed(ActionEvent ev) { 503 if (modeButton.isSelected()) { 504 planController.setMode(PlanController.Mode.WALL_CREATION); 505 } else { 506 planController.setMode(PlanController.Mode.SELECTION); 507 } 508 } 509 }); 510 // Create an undo button 511 this.undoButton = new JButton(new ImageIcon( 512 getClass().getResource("resources/Undo16.gif"))); 513 this.undoButton.addActionListener(new ActionListener() { 514 public void actionPerformed(ActionEvent ev) { 515 undoManager.undo(); 516 } 517 }); 518 // Create a redo button 519 this.redoButton = new JButton(new ImageIcon( 520 getClass().getResource("resources/Redo16.gif"))); 521 this.redoButton.addActionListener(new ActionListener() { 522 public void actionPerformed(ActionEvent ev) { 523 undoManager.redo(); 524 } 525 }); 526 this.reverseDirectionButton = new JButton("Reverse"); 527 this.reverseDirectionButton.addActionListener(new ActionListener() { 528 public void actionPerformed(ActionEvent ev) { 529 planController.reverseSelectedWallsDirection(); 530 } 531 }); 532 this.splitButton = new JButton("Split"); 533 this.splitButton.addActionListener(new ActionListener() { 534 public void actionPerformed(ActionEvent ev) { 535 planController.splitSelectedWall(); 536 } 537 }); 538 // Add a tool bar to the frame with mode toggle button, 539 // undo and redo buttons 540 JToolBar toolBar = new JToolBar(); 541 toolBar.add(this.modeButton); 542 toolBar.add(this.undoButton); 543 toolBar.add(this.redoButton); 544 toolBar.add(this.reverseDirectionButton); 545 toolBar.add(this.splitButton); 546 // Add the tool bar at top of the window 547 add(toolBar, BorderLayout.NORTH); 548 // Pack frame to ensure home plan component is at its preferred size 549 pack(); 550 } 551 } 552 } 553