001package bradleyross.library.applets; 002//import java.util.Date; 003import java.util.Vector; 004import java.util.Date; 005import java.io.File; 006import java.io.FileInputStream; 007import java.io.FileNotFoundException; 008import java.io.IOException; 009import java.io.StringReader; 010import java.io.LineNumberReader; 011import java.awt.Container; 012import java.awt.Canvas; 013import java.awt.Color; 014import java.awt.Dimension; 015import java.awt.Graphics; 016import java.awt.GridLayout; 017import java.awt.event.MouseEvent; 018import java.awt.event.ActionEvent; 019import java.awt.event.ActionListener; 020import java.awt.event.MouseListener; 021import java.awt.event.AdjustmentListener; 022import java.awt.event.AdjustmentEvent; 023import java.awt.image.BufferedImage; 024import javax.swing.JApplet; 025import javax.swing.JScrollPane; 026import javax.swing.JScrollBar; 027import javax.swing.BoundedRangeModel; 028import javax.swing.JFrame; 029import javax.swing.JPanel; 030import javax.swing.JTextArea; 031import javax.swing.JButton; 032import javax.swing.BoxLayout; 033import java.net.MalformedURLException; 034import java.net.URL; 035import javax.imageio.ImageIO; 036import bradleyross.library.helpers.FileHelpers; 037import bradleyross.library.helpers.RandomHelpers; 038/** 039 * Concentration game. 040 * 041 * @see JPanel 042 * @see JFrame 043 * @see Container 044 * @author Bradley Ross 045 */ 046public class Concentration extends JApplet 047{ 048 /** 049 * Panel containing the actual game. 050 * <p>It is 051 * divided into tiles.</p> 052 */ 053 GamePanel gamePanel = null; 054 /** 055 * Main panel for the game. 056 * 057 * <p>The value is set by the {@link #init() } method to 058 * the content panel of the main widow for the applet. 059 * The {link #gamePanel} panel is part of the content 060 * pane.</p> 061 */ 062 Container contentPane = null; 063 /** 064 * Optional frame for displaying diagnostic information. 065 * 066 * <p>This frame only appears if the Debug parameter for the 067 * applet is set to a value greater than zero.</p> 068 */ 069 JFrame debugFrame = null; 070 /** 071 * True if class is called as a JApplet. 072 * 073 * <p>If the class is called as a standalone application, the 074 * value is set to false.</p> 075 * @see #setAppletMode(boolean) 076 */ 077 boolean appletMode = true; 078 /** 079 * Setter for applietMode. 080 * 081 * @param value Value to be used for appletMode 082 */ 083 public void setAppletMode( boolean value) 084 { 085 appletMode = value; 086 } 087 /** 088 * Provided for compliance with Serializable interface. 089 */ 090 private static final long serialVersionUID = 1L; 091 /** 092 * Root of directory or URL containing images. 093 */ 094 protected URL imageRoot = null; 095 /** 096 * Panel containing text area with debugging information. 097 */ 098 protected secondPanel debugPanel = null; 099 /** 100 * This is the latest id number to be used with one of the tiles. 101 * 102 */ 103 private static int latestCounter = 1000; 104 /** 105 * Controls amount of diagnostic output. 106 * <p>If the value is greater than zero, the 107 * {@link #debugFrame} is created as a second 108 * window on the display to show the 109 * diagnostic messages.</p> 110 * @see #setDebugLevel(int) 111 * @see #getDebugLevel() 112 */ 113 protected int debugLevel = 0; 114 /** 115 * Setter for debugLevel. 116 * @param value Value to be used for debugLevel 117 * @see #debugLevel 118 */ 119 public void setDebugLevel(int value) 120 { debugLevel = value; } 121 /** 122 * Getter for debugLevel. 123 * @return Value of debugLevel 124 * @see #debugLevel 125 */ 126 public int getDebugLevel() 127 { return debugLevel; } 128 /** 129 * Not sure if this is still used. 130 */ 131 protected Container mainPanel = null; 132 /** 133 * Object containing the game panel. 134 * <p>This panel contains all of the individual tiles.</p> 135 */ 136 protected Concentration game = null; 137 /** 138 * Vector object containing the images to be placed on the tiles. 139 */ 140 Vector<ImageInstance> imageList = new Vector<ImageInstance>(); 141 /** 142 * Array of the tiles on the game panel. 143 */ 144 Tile tileList[] = null; 145 /** 146 * Number of tiles horizontally. 147 */ 148 protected int tilesWidth = 6; 149 /** 150 * Number of tiles vertically. 151 */ 152 protected int tilesHeight = 6; 153 /** 154 * Length of height and width of cell in pixels. 155 */ 156 protected int cellWidth = 100; 157 /** 158 * Distance between cells in pixels. 159 */ 160 protected int cellMargin = 10; 161 /** 162 * Number of tiles remaining that have yet to be matched 163 */ 164 protected int numberRemaining = 0; 165 /** 166 * URL name to be used to obtain the list of image URL's. 167 */ 168 protected String imageListUrl = null; 169 /** 170 * String containing the list of images. 171 */ 172 protected String imageListString = null; 173 /** 174 * Displays messages if debugLevel is greater 175 * than 0. 176 * 177 * @param message 178 * @see #debugLevel 179 * @see #debugFrame 180 */ 181 protected void logMessage(String message) 182 { 183 if (debugLevel > 0) 184 { 185 debugPanel.writeMessage(message + "\n"); 186 /* 187 debugFrame.repaint(10l); 188 textBlock.repaint(10l); 189 */ 190 } 191 } 192 /** 193 * Causes thread for a number of milliseconds 194 * @param length Time to wait in milliseconds 195 */ 196 protected void sleeper(int length) 197 { 198 if (length <= 0) { return; } 199 long startTime = System.currentTimeMillis(); 200 long endTime = startTime + (long) length; 201 long currentTime = System.currentTimeMillis(); 202 for (int i = 0; i < 15; i++) 203 { 204 currentTime = System.currentTimeMillis(); 205 if (currentTime >= endTime) { break; } 206 try 207 { 208 Thread.sleep((int)(endTime - currentTime)); 209 } 210 catch (InterruptedException e) 211 { ; } 212 } 213 logMessage("sleeper: " + Integer.toString(length) + " " + 214 Long.toString(currentTime - startTime)); 215 System.out.println("Sleep program didn't reach end"); 216 } 217 public String[][] getParameterInfo() 218 { 219 String[][] info = { 220 { "CellWidth", "integer", "Width of cell in pixels" }, 221 { "CellMargin", "integer", "Width of cell margin in pixels" }, 222 { "Debug", "integer", "Amount of diagnostic output" } 223 }; 224 return info; 225 } 226 /** 227 * These are the individual squares for the game. 228 * 229 * <p>The gamePanel object serves as the listener 230 * for all of the Tile objects.</p> 231 * @author Bradley Ross 232 * 233 * @see #game 234 * 235 */ 236 protected class Tile extends Canvas 237 { 238 /** Indicates that "card back" is shown. */ 239 protected static final int INITIAL = 0; 240 /** Indicates that image to be matched is shown, */ 241 protected static final int IMAGE = 1; 242 /** Indicates that card has been removed after being matched. */ 243 protected static final int REVEALED = 2; 244 /** Indicates that status of card is unknown. */ 245 protected static final int UNKNOWN = -1; 246 /** Indicate current status of the tile. */ 247 protected int status = UNKNOWN; 248 // protected int requestedStatus = REVEALED; 249 /** 250 * ID value for tile. 251 */ 252 protected int counter; 253 /** 254 * Pointer to a member of the imageList vector. 255 * @see #imageList 256 */ 257 protected int imageNumber; 258 /** 259 * Value to satisfy {@link java.io.Serializable} interface. 260 */ 261 private static final long serialVersionUID = 1L; 262 public Tile(int id) 263 { 264 super(); 265 counter = id; 266 if (debugLevel > 4) 267 { logMessage("Creating Tile object - parameter for constructor is " + 268 Integer.toString(counter)); } 269 setPreferredSize(new Dimension(this.getWidth(), this.getHeight())); 270 setMinimumSize(new Dimension(this.getWidth(), this.getHeight())); 271 } 272 public Tile() 273 { 274 super(); 275 latestCounter++; 276 counter = latestCounter; 277 if (debugLevel > 4) 278 { logMessage("Creating Tile object - no arguments for constructor"); } 279 setPreferredSize(new Dimension(cellWidth + cellMargin, cellWidth + cellMargin)); 280 this.setVisible(true); 281 if (this.getGraphics() != null) 282 { paint(this.getGraphics()); } 283 } 284 /** 285 * Getter for counter 286 * @see #counter 287 * @return Value of counter 288 */ 289 public int getCounter() 290 { return counter; } 291 /** 292 * Getter for imageNumber 293 * @see #imageNumber 294 * @return Value of imageNumber 295 */ 296 public int getImageNumber() 297 { return imageNumber; } 298 /** 299 * Setter for imageNumber. 300 * @param value Value to be used for imageNumber 301 * @see #imageNumber 302 */ 303 public void setImageNumber(int value) 304 { imageNumber = value; } 305 /** 306 * Setter for status. 307 * 308 * @param newStatus Value to be used for {@link #status} 309 */ 310 public void setStatus(int newStatus) 311 { 312 if (newStatus == UNKNOWN) 313 { status = UNKNOWN; } 314 else if (status != newStatus) 315 { 316 status = newStatus; 317 logMessage("Tile.setStatus requesting repaint of tile " + Integer.toString(counter)); 318 repaint(); 319 } 320 } 321 /** 322 * Getter for status. 323 * @return {@link #status} 324 */ 325 public int getStatus() 326 { return status; } 327 /** 328 * This class allows requests to repaint the tile to be tracked. 329 */ 330 public void repaint() 331 { 332 if (debugLevel > 4) 333 { 334 logMessage("Repaint requested for tile " + Integer.toString(counter) + 335 " : " + new Date().toString()); 336 } 337 super.repaint(); 338 } 339 /** 340 * Draws on tile depending on status. 341 * 342 */ 343 public void paint(Graphics g) 344 { 345 /* if (requestedStatus == status) { return; } */ 346 logMessage("Painting tile " + Integer.toString(counter) + " : " + 347 new Date().toString()); 348 super.paint(g); 349 if (status == INITIAL) 350 { 351 int working = cellMargin / 2; 352 g.setColor(Color.red); 353 g.fillRect(working, working, cellWidth, cellWidth); 354 g.setColor(Color.blue); 355 g.fillRect(2 * working, 2 * working, cellWidth - cellMargin, cellWidth - cellMargin); 356 g.setColor(Color.magenta); 357 g.fillRect(3 * working, 3 * working, cellWidth - 2 * cellMargin, cellWidth - 2 * cellMargin); 358 g.setColor(Color.cyan); 359 g.fillRect(4 * working, 4 * working, cellWidth - 3 * cellMargin, cellWidth - 3 * cellMargin); 360 } 361 else if (status == IMAGE) 362 { 363 g.drawImage(imageList.elementAt(imageNumber).getImage(), cellMargin / 2, cellMargin / 2, cellWidth, cellWidth, this); 364 } 365 else if (status == REVEALED) 366 { 367 g.setColor(Color.gray); 368 g.fillRect(0, 0, cellWidth + cellMargin, cellWidth + cellMargin); 369 } 370 } 371 } 372 /** 373 * Instance of a BufferedImage for use with the game. 374 * @author Bradley Ross 375 * @see javax.imageio.ImageIO#read(InputStream) 376 * 377 */ 378 protected class ImageInstance 379 { 380 /** 381 * Image to be displayed as part of game. 382 */ 383 protected BufferedImage instance = null; 384 /** 385 * Getter for image 386 * @return Image 387 */ 388 public BufferedImage getImage() 389 { return instance; } 390 /** 391 * Setter for image. 392 * @param value Image to be used. 393 */ 394 public void setImage(BufferedImage value) 395 { instance = value; } 396 /** 397 * URL indicating the location of the image for the 398 * tile. 399 * @see #getImageLocation() 400 * @see #setImageLocation(URL) 401 */ 402 protected URL imageLocation; 403 public URL getImageLocation() 404 { return imageLocation; } 405 public void setImageLocation(URL value) 406 { imageLocation = value; } 407 /** 408 * URL indicating the location of the web page describing 409 * the image on the tile. 410 * @see #getDescLocation() 411 * @see #setDescLocation(URL) 412 */ 413 protected URL descLocation; 414 public URL getDescLocation() 415 { return descLocation; } 416 public void setDescLocation(URL value) 417 { descLocation = value; } 418 /** 419 * Index in {@link #tileList} of first location of image. 420 */ 421 protected int firstLocation = -1; 422 /** 423 * Getter for firstLocation. 424 * @return Index in tileList of first location of image. 425 */ 426 public int getFirstLocation() 427 { return firstLocation; } 428 /** 429 * Setter for firstLocation. 430 * 431 * @param value Index in tileList to be used for first location of image. 432 */ 433 public void setFirstLocation(int value) 434 { firstLocation = value; } 435 /** 436 * Index in {@link #tileList} of second location of image. 437 */ 438 protected int secondLocation = -1; 439 /** 440 * Getter for secondLocation 441 * @return Index in tileList of second location of image 442 */ 443 public int getSecondLocation() 444 { return secondLocation; } 445 /** 446 * Setter for secondLocation 447 * @param value Index in tileList to be used for second location of image 448 */ 449 public void setSecondLocation(int value) 450 { secondLocation = value; } 451 /* 452 * Constructor for imageInstance defining file for image. 453 * @param source File containing image 454 */ 455 public ImageInstance (File source) 456 { 457 try 458 { 459 instance = javax.imageio.ImageIO.read(new FileInputStream(source)); 460 } 461 catch (FileNotFoundException e) 462 { 463 logMessage("Unable to find file while " + 464 " instantiating ImageInstance"); 465 logMessage(e.getClass().getName() + " : " + 466 e.getMessage()); 467 e.printStackTrace(); 468 } 469 catch (IOException e) 470 { 471 logMessage(e.getClass().getName() + " : " + 472 e.getMessage()); 473 e.printStackTrace(); 474 } 475 } 476 public ImageInstance (BufferedImage image) 477 { 478 instance = image; 479 480 } 481 /** 482 * Deprecated constructor. 483 * @param width Width of image in pixels 484 * @param height Height of image in pixels 485 * @param source Source of image 486 * @deprecated 487 */ 488 public ImageInstance (int width, int height, File source) 489 { 490 try 491 { 492 instance = javax.imageio.ImageIO.read(new FileInputStream(source)); 493 } 494 catch (FileNotFoundException e) 495 { 496 System.out.println(e.getClass().getName() + " : " + 497 e.getMessage()); 498 e.printStackTrace(); 499 } 500 catch (IOException e) 501 { 502 System.out.println(e.getClass().getName() + " : " + 503 e.getMessage()); 504 e.printStackTrace(); 505 } 506 } 507 } 508 /** 509 * Playing area for the Concentration game. 510 * @author Bradley Ross 511 * 512 */ 513 protected class GamePanel extends JPanel implements MouseListener 514 { 515 /** 516 * For compliance with Serializable interface, 517 */ 518 private static final long serialVersionUID = 1L; 519 /** 520 * The constructor for GamePanel instantiates the individual tiles 521 * on the game panel. 522 * <p>This is where the randomization of the order of the images 523 * would be carried out.</p> 524 * @see RandomHelpers 525 */ 526 public GamePanel() 527 { 528 super(); 529 logMessage("Constructing GamePanel object"); 530 layout = new GridLayout(0, tilesWidth, 0, 0); 531 layout.setHgap(0); 532 layout.setVgap(0); 533 numberRemaining = tilesWidth * tilesHeight; 534 setBackground(Color.gray); 535 setLayout(layout); 536 tileList = new Tile[tilesWidth * tilesHeight]; 537 int imageOrder[] = RandomHelpers.createRandomOrder(imageList.size()); 538 int tileOrder[] = RandomHelpers.createRandomOrder(tilesWidth * tilesHeight); 539 logMessage("There are " + Integer.toString(imageList.size()) + 540 " images"); 541 logMessage("There are " + Integer.toString(tileList.length) + 542 " tiles"); 543 for (int i = 0; i < tilesHeight * tilesWidth; i++) 544 { 545 int select = tileOrder[i]; 546 tileList[i] = new Tile(i); 547 int imageSelect = imageOrder[select / 2]; 548 tileList[i].setImageNumber(imageOrder[select / 2]); 549 add(tileList[i]); 550 if (select % 2 == 0) 551 { imageList.elementAt(imageSelect).setFirstLocation(i); } 552 else 553 { imageList.elementAt(imageSelect).setSecondLocation(i); } 554 tileList[i].setStatus(Tile.INITIAL); 555 } 556 557 logMessage("Constructor for gamePanel now complete"); 558 } 559 /** 560 * Actions upon winning game. I may have to place the processes in a separate 561 * thread, because any sleep operations in this class seems to shut down the 562 * entire applet. 563 */ 564 565 void reward() 566 { 567 int tiles = tilesWidth * tilesHeight; 568 logMessage("Reward started " + new Date().toString()); 569 for (int i = 0; i < tiles; i++) 570 { tileList[i].setStatus(Tile.IMAGE); } 571 } 572 573 /** 574 * Executed when tile is clicked. 575 */ 576 public void mouseClicked(MouseEvent e) 577 { 578 if (numberRemaining < 2) 579 { 580 randomize(); 581 // paintChildren(getGraphics()); 582 return; 583 } 584 Tile source = (Tile) e.getSource(); 585 if (numberShowing == 0 && source.getStatus() == Tile.INITIAL) 586 { 587 firstShowing = source.getCounter(); 588 source.setStatus(Tile.IMAGE); 589 numberShowing = 1; 590 } 591 else if (numberShowing == 0 && source.getStatus() == Tile.IMAGE) 592 { 593 if (debugLevel > 0) 594 { 595 logMessage("Aplication error"); 596 } 597 System.exit(1); 598 } 599 else if (numberShowing == 0 && source.getStatus() == Tile.REVEALED) 600 { ; } 601 else if (numberShowing == 1 && source.getStatus() == Tile.INITIAL) 602 { 603 secondShowing = source.getCounter(); 604 source.setStatus(Tile.IMAGE); 605 numberShowing = 2; 606 } 607 else if (numberShowing == 1 && (source.getStatus() == Tile.IMAGE || 608 source.getStatus() == Tile.REVEALED)) 609 { 610 tileList[firstShowing].setStatus(Tile.INITIAL); 611 numberShowing = 0; 612 firstShowing = -1; 613 } 614 else if (numberShowing == 2 && (source.getStatus() == Tile.IMAGE || 615 source.getStatus() == Tile.REVEALED)) 616 { 617 if (tileList[firstShowing].getImageNumber() == tileList[secondShowing].getImageNumber()) 618 { 619 tileList[firstShowing].setStatus(Tile.REVEALED); 620 tileList[secondShowing].setStatus(Tile.REVEALED); 621 numberRemaining = numberRemaining - 2; 622 } 623 else 624 { 625 tileList[firstShowing].setStatus(Tile.INITIAL); 626 tileList[secondShowing].setStatus(Tile.INITIAL); 627 } 628 firstShowing = -1; 629 secondShowing = -1; 630 numberShowing = 0; 631 } 632 else if (numberShowing == 2 && source.getStatus() == Tile.INITIAL) 633 { 634 if (tileList[firstShowing].getImageNumber() == tileList[secondShowing].getImageNumber()) 635 { 636 tileList[firstShowing].setStatus(Tile.REVEALED); 637 tileList[secondShowing].setStatus(Tile.REVEALED); 638 source.setStatus(Tile.IMAGE); 639 numberRemaining = numberRemaining - 2; 640 } 641 else 642 { 643 tileList[firstShowing].setStatus(Tile.INITIAL); 644 tileList[secondShowing].setStatus(Tile.INITIAL); 645 source.setStatus(Tile.IMAGE); 646 } 647 tileList[firstShowing].repaint(100l); 648 tileList[secondShowing].repaint(100l); 649 source.repaint(100l); 650 firstShowing = source.getCounter(); 651 secondShowing = -1; 652 numberShowing = 1; 653 } 654 else 655 { 656 System.out.println("Unknown case"); 657 } 658 // this.repaint(100l); 659 logMessage(Integer.toString(source.getCounter()) + " clicked - " + 660 Integer.toString(numberShowing) + " showing - " + 661 "Squares: (" + 662 Integer.toString(firstShowing) + ", " + 663 Integer.toString(secondShowing) + "), Remaining: " + 664 Integer.toString(numberRemaining)); 665 if (numberRemaining < 2) 666 { 667 logMessage("Puzzle has been solved " + new Date().toString()); 668 reward(); 669 } 670 } 671 /** 672 * Required for implementing MouseListener interface. 673 * 674 */ 675 public void mouseEntered(MouseEvent e) 676 { ; } 677 /** 678 * Required for implementing MouseListener interface. 679 */ 680 public void mouseExited(MouseEvent e) 681 { ; } 682 /** 683 * Required for implementing MouseListener interface. 684 */ 685 public void mousePressed(MouseEvent e) 686 { ; } 687 /** 688 * Required for implementing MouseListener interface. 689 */ 690 public void mouseReleased(MouseEvent e) 691 { ; } 692 /** 693 * Allows tracking and manipulation of paintComponents calls. 694 */ 695 public void paintComponents(Graphics g) 696 { 697 logMessage("paintComponents triggered for game panel - " + 698 new Date().toString()); 699 super.paintComponents(g); 700 } 701 /** 702 * Allows tracking and manipulation of requests to repaint panel. 703 */ 704 public void repaint() 705 { 706 logMessage("Repaint requested for game panel : " + 707 new Date().toString()); 708 super.repaint(); 709 } 710 /** 711 * Randomize order of tiles and reset to initial conditions. 712 */ 713 public void randomize() 714 { 715 logMessage("Starting randomize"); 716 int imageOrder[] = RandomHelpers.createRandomOrder(imageList.size()); 717 int tileOrder[] = RandomHelpers.createRandomOrder(tilesWidth * tilesHeight); 718 logMessage("There are " + Integer.toString(imageList.size()) + 719 " images"); 720 logMessage("There are " + Integer.toString(tileList.length) + 721 " tiles"); 722 for (int i = 0; i < tilesHeight * tilesWidth; i++) 723 { 724 int select = tileOrder[i]; 725 int imageSelect = imageOrder[select / 2]; 726 tileList[i].setImageNumber(imageOrder[select / 2]); 727 if (select % 2 == 0) 728 { imageList.elementAt(imageSelect).setFirstLocation(i); } 729 else 730 { imageList.elementAt(imageSelect).setSecondLocation(i); } 731 tileList[i].setStatus(Tile.UNKNOWN); 732 tileList[i].setStatus(Tile.INITIAL); 733 } 734 firstShowing = -1; 735 secondShowing = -1; 736 numberShowing = 0; 737 numberRemaining = tilesWidth * tilesHeight; 738 } 739 } /* End of gamePanel */ 740 /** 741 * Panel for displaying diagnostic listings when debugLevel greater than 0. 742 * @author Bradley Ross 743 * 744 */ 745 protected class secondPanel extends JPanel implements ActionListener, AdjustmentListener 746 { 747 /** 748 * Dummy field to satisfy Serializable interface. 749 */ 750 private static final long serialVersionUID = 1L; 751 /** 752 * Button used to reset game by randomizing positions of tiles 753 * and showing card backs for all squares. 754 */ 755 protected JButton resetButton = new JButton("Reset Game"); 756 /** 757 * Button used to clear text area. 758 */ 759 protected JButton clearButton = new JButton("Clear Text"); 760 /** 761 * Scrolling area containing the text area. 762 */ 763 protected JScrollPane scrollPane = null; 764 /** 765 * Vertical scroll bar for the scrolling pane. 766 */ 767 protected JScrollBar scrollBar = null; 768 /** 769 * Used for debugging messages. 770 */ 771 JTextArea textBlock = null; 772 /** 773 * Object containing bounds and values for vertical scroll bar. 774 */ 775 protected BoundedRangeModel rangeModel = null; 776 /** 777 * Add a message to the text area and move the scroll bar to the 778 * bottom of the scrolling area. 779 * <p>Since the upper bound of the vertical scrollbar setting is constantly 780 * changing as material is added to the box, it is necessary to get the 781 * current maximum value of the scroll bar setting.</p> 782 * @param text Text to be added 783 */ 784 public void writeMessage(String text) 785 { 786 textBlock.append(text); 787 scrollBar.setValue(scrollBar.getModel().getMaximum() - scrollBar.getModel().getExtent()); 788 } 789 public secondPanel() 790 { 791 JPanel buttons = new JPanel(); 792 buttons.setLayout(new BoxLayout(buttons, BoxLayout.X_AXIS)); 793 this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); 794 textBlock = new JTextArea(10, 50); 795 resetButton.setName("reset"); 796 clearButton.setName("clear"); 797 buttons.add(resetButton); 798 buttons.add(clearButton); 799 add(buttons); 800 scrollPane = new JScrollPane(textBlock); 801 scrollBar = scrollPane.getVerticalScrollBar(); 802 rangeModel = scrollBar.getModel(); 803 add(scrollPane); 804 textBlock.setVisible(true); 805 resetButton.addActionListener(this); 806 clearButton.addActionListener(this); 807 scrollBar.addAdjustmentListener(this); 808 textBlock.setText((String) null); 809 // scrollBar.setValue(rangeModel.getMinimum()); 810 writeMessage("Minimum: " + Integer.toString(rangeModel.getMinimum()) + " " + 811 " Maximum: " + Integer.toString(rangeModel.getMaximum()) + "\n"); 812 writeMessage("Extent: " + Integer.toString(rangeModel.getExtent()) + 813 " Value: " + Integer.toString(rangeModel.getValue()) + "\n"); 814 } 815 /** 816 * Take action when button is clicked. 817 * @param e Action event generated when button is clicked 818 */ 819 public void actionPerformed(ActionEvent e) 820 { 821 if (e.getSource() == (Object) resetButton) 822 { 823 logMessage("Reset button clicked"); 824 gamePanel.randomize(); 825 } 826 else if (e.getSource() == (Object) clearButton) 827 { 828 textBlock.setText((String) null); 829 logMessage("Clear button clicked"); 830 writeMessage("Minimum: " + Integer.toString(rangeModel.getMinimum()) + " " + 831 " Maximum: " + Integer.toString(rangeModel.getMaximum()) + "\n"); 832 writeMessage("Extent: " + Integer.toString(rangeModel.getExtent()) + 833 " Value: " + Integer.toString(rangeModel.getValue()) + "\n"); 834 try 835 { 836 Thread.sleep(1); 837 } 838 catch (InterruptedException e1) 839 { 840 e1.printStackTrace(); 841 } 842 writeMessage("Minimum: " + Integer.toString(rangeModel.getMinimum()) + " " + 843 " Maximum: " + Integer.toString(rangeModel.getMaximum()) + "\n"); 844 writeMessage("Extent: " + Integer.toString(rangeModel.getExtent()) + 845 " Value: " + Integer.toString(rangeModel.getValue()) + "\n"); 846 } 847 } 848 /** 849 * Action to be taken when the scrollbar is used to move within the scrolling 850 * area. 851 * @param e Event representing action to be monitored 852 */ 853 public void adjustmentValueChanged(AdjustmentEvent e) 854 { 855 if (debugLevel < 10) { return; } 856 if (e.getValueIsAdjusting()) { return; } 857 textBlock.append(" " + Integer.toString(e.getValue()) + " "); 858 } 859 } 860 GridLayout layout = null; 861 /** 862 * Number of tiles currently displaying picture. 863 */ 864 protected int numberShowing = 0; 865 /** 866 * Index in tileList of first tile displaying picture. 867 */ 868 protected int firstShowing = -1; 869 /** Index in tileList of second tile displaying picture. */ 870 protected int secondShowing = -1; 871 BufferedImage image1 = null; 872 BufferedImage image2 = null; 873 /** 874 * Constructor . 875 */ 876 public Concentration(int width, int height) 877 { 878 tilesWidth = width; 879 tilesHeight = height; 880 game = this; 881 } 882 public Concentration() 883 { 884 885 logMessage("Running constructor without parameters - " + new Date().toString()); 886 game = this; 887 tilesWidth = 6; 888 tilesHeight = 6; 889 890 } 891 /** 892 * Construct a dummy image. 893 * @param value 894 * @return Image 895 */ 896 protected BufferedImage buildTestImage (int value) 897 { 898 BufferedImage image = new BufferedImage(cellWidth + cellMargin, cellWidth + cellMargin, BufferedImage.TYPE_3BYTE_BGR); 899 Graphics g = image.getGraphics(); 900 g.setColor(Color.white); 901 g.fillRect(0, 0, 110, 110); 902 g.setColor(Color.blue); 903 g.fillRect (5, 5, 100, 100); 904 g.setColor(Color.lightGray); 905 g.fillRect ( 20, 20, 60, 60); 906 g.setColor(Color.blue); 907 g.fillRect(30, 30, 40, 40); 908 g.drawString(Integer.toString(value), 60, 60); 909 return image; 910 } 911 /** 912 * Executed when being called as applet. 913 */ 914 public void init() 915 { 916 if (appletMode && debugLevel > 0) 917 { System.out.println("Running in applet mode"); } 918 else if (!appletMode && debugLevel > 0) 919 { System.out.println("Not running in applet mode"); } 920 if (appletMode) 921 { 922 String value = null; 923 value = getParameter("ImageList"); 924 if (value != null) 925 { 926 imageListUrl = value; 927 } 928 else 929 { 930 imageListUrl = "images.txt"; 931 } 932 value = null; 933 value = getParameter("CellWidth"); 934 if (value != null) 935 { 936 cellWidth = Integer.parseInt(value); 937 } 938 value = null; 939 value = getParameter("CellMargin"); 940 if (value != null) 941 { 942 cellMargin = Integer.parseInt(value); 943 } 944 value = null; 945 value = getParameter("Debug"); 946 int working = debugLevel; 947 if (value != null) 948 { 949 try 950 { 951 working = Integer.parseInt(value); 952 } 953 catch (Exception e) 954 { working = debugLevel; } 955 debugLevel = working; 956 } 957 } 958 if (debugLevel > 0) 959 { 960 debugFrame = new JFrame(); 961 debugPanel = new secondPanel(); 962 debugFrame.add(debugPanel); 963 debugPanel.setVisible(true); 964 logMessage("Debugging History\n"); 965 debugFrame.setSize(new Dimension(700, 700)); 966 debugFrame.setVisible(true); 967 logMessage("DebugLevel is " + Integer.toString(debugLevel)); 968 } 969 contentPane = getContentPane(); 970 game = this; 971 image1 = new BufferedImage(110, 110, BufferedImage.TYPE_3BYTE_BGR); 972 Graphics g = image1.getGraphics(); 973 g.setColor(Color.red); 974 g.fillRect (cellMargin / 2, cellMargin / 2, cellWidth, cellWidth); 975 /* 976 g.setColor(Color.pink); 977 g.fillRect ( 20, 20, 70, 70); 978 */ 979 g.setColor(Color.gray); 980 if (appletMode) 981 { 982 imageRoot = getDocumentBase(); 983 984 logMessage("Document base is " + imageRoot.toString()); 985 986 } 987 else 988 { imageRoot = null; } 989 990 try 991 { 992 URL temp = new URL(imageRoot, imageListUrl); 993 String list = FileHelpers.readTextFile(temp); 994 StringReader input = new StringReader(list); 995 LineNumberReader reader = new LineNumberReader(input); 996 String line = null; 997 while (true) 998 { 999 line = reader.readLine(); 1000 if (line == null) {break; } 1001 tempRead1(line); 1002 } 1003 } 1004 catch (MalformedURLException e) 1005 { 1006 e.printStackTrace(); 1007 } 1008 catch (IOException e) 1009 { 1010 e.printStackTrace(); 1011 } 1012 1013 // tempRead2(); 1014 gamePanel = new GamePanel(); 1015 for (int i = 0; i < tilesWidth * tilesHeight; i++) 1016 { tileList[i].addMouseListener((MouseListener) gamePanel); } 1017 contentPane.add(gamePanel); 1018 logMessage("Init procedure complete"); 1019 1020 } 1021 /** 1022 * Restart the game. 1023 1024 public void restart() 1025 { 1026 logMessage("***** ***** Restart triggered"); 1027 tileList = new Tile[tilesWidth*tilesHeight]; 1028 imageList = new Vector<ImageInstance>(); 1029 try 1030 { 1031 URL temp = new URL(imageRoot, imageListUrl); 1032 String list = FileHelpers.readTextFile(temp); 1033 StringReader input = new StringReader(list); 1034 LineNumberReader reader = new LineNumberReader(input); 1035 String line = null; 1036 while (true) 1037 { 1038 line = reader.readLine(); 1039 if (line == null) {break; } 1040 tempRead1(line); 1041 } 1042 } 1043 catch (MalformedURLException e) 1044 { 1045 logMessage("Malformed URL while reading image"); 1046 e.printStackTrace(); 1047 } 1048 catch (IOException e) 1049 { 1050 logMessage("IOException while reading image"); 1051 e.printStackTrace(); 1052 } 1053 contentPane.removeAll(); 1054 gamePanel = new GamePanel(); 1055 for (int i = 0; i < tilesWidth * tilesHeight; i++) 1056 { 1057 tileList[i].addMouseListener((MouseListener) gamePanel); 1058 } 1059 contentPane.add(gamePanel); 1060 logMessage("Restart finished"); 1061 1062 } 1063*/ 1064 /** 1065 * Remove the debugging window if debugLevel was greater than 0. 1066 */ 1067 public void stop() 1068 { 1069 if (debugLevel > 0) 1070 { 1071 logMessage("Entering stop method\n"); 1072 debugFrame.setVisible(false); 1073 debugFrame.dispose(); 1074 } 1075 } 1076 /** 1077 * Processes an image. }. 1078 * @param item File name to be processed 1079 */ 1080 protected void tempRead1(String item) 1081 { 1082 if (!appletMode) 1083 { 1084 String fullName = "/Applications/Tomcat/webapps/test/" + item; 1085 imageList.add(new ImageInstance(new File(fullName))); 1086 } 1087 else if (appletMode) 1088 { 1089 // imageList.add(new ImageInstance(image1)); 1090 1091 try 1092 { 1093 imageList.add(new ImageInstance(ImageIO.read(new URL(imageRoot, item )))); 1094 } 1095 catch (MalformedURLException e) 1096 { 1097 logMessage("Unable to parse " + imageRoot.toString() + " : " + 1098 item + " - Malformed URL exception"); 1099 1100 e.printStackTrace(); 1101 } 1102 catch (IOException e) 1103 { 1104 logMessage("Unable to parse " + imageRoot.toString() + " : " + 1105 item + " - IO exception"); 1106 1107 e.printStackTrace(); 1108 } 1109 } 1110 logMessage(item + " processed"); 1111 } 1112}