import edu.neu.ccs.*; import edu.neu.ccs.gui.*; import edu.neu.ccs.codec.*; import edu.neu.ccs.console.*; import edu.neu.ccs.filter.*; import edu.neu.ccs.jpf.*; import edu.neu.ccs.parser.*; import edu.neu.ccs.pedagogy.*; import edu.neu.ccs.quick.*; import edu.neu.ccs.util.*; import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import java.awt.font.*; import java.awt.image.*; import javax.swing.*; import javax.swing.border.*; import java.io.*; import java.util.*; import java.math.*; import java.beans.*; import java.lang.reflect.*; import java.net.URL; import java.util.regex.*; import java.text.ParseException; public class Thomas_CardTricks extends DisplayPanel implements JPTConstants { protected final int BUFFERSIZE = 650; // square window for painting protected BufferedPanel window = new BufferedPanel(BUFFERSIZE, BUFFERSIZE); protected Action resetCards = new SimpleAction("Reset") { public void perform() { ResetCards(); } }; protected Action randomRotateTranslate = new SimpleAction("Translate and Rotate") { public void perform() { RandomTranslateAndRotate(); } }; protected Action rotateAsGroup = new SimpleAction("Rotate as Group") { public void perform() { RandomRotateAsGroup(); } }; protected Action clear = new SimpleAction("Clear") { public void perform() { clear(); } }; // button panel protected ActionsPanel buttonPanel = new ActionsPanel(new Action[] {randomRotateTranslate, rotateAsGroup, resetCards, clear}); protected MouseAction mouseMoved = new MouseAction("Mouse Moved") { public void mouseActionPerformed(MouseEvent mevt) { mouseMoved(mevt); } }; // mouse pressed action protected MouseAction mousePressed = new MouseAction("Mouse Pressed") { public void mouseActionPerformed(MouseEvent mevt) { mousePressed(mevt); } }; // mouse dragged action protected MouseAction mouseDragged = new MouseAction("Mouse Dragged") { public void mouseActionPerformed(MouseEvent mevt) { mouseDragged(mevt); } }; // mouse released action protected MouseAction mouseReleased = new MouseAction("Mouse Released") { public void mouseActionPerformed(MouseEvent mevt) { mouseReleased(mevt); } }; // main panel protected TablePanel mainPanel = new TablePanel( new Object[] { new Display(buttonPanel, null, "Controls"), new Display(window, null, "Graphics")}, VERTICAL, 5, 5, NORTH); MouseActionAdapter adapter = window.getMouseActionAdapter(); ImagePaintableLite[] cards; PaintableSequence cardSequence; Paintable rotatePoint = new ShapePaintable(new XCircle(getCenter().x, getCenter().y, 4), PaintMode.FILL, Color.BLUE); public Thomas_CardTricks() { window.installSimpleMouseActions(true); ResetCards(); add(mainPanel); addActions(); } // method: mouseMoved protected void mouseMoved(MouseEvent mevt) { // Make sure the rotatePoint stays at the top window.getPaintableSequence().shiftPaintableToTop(rotatePoint); } // method: mousePressed protected void mousePressed(MouseEvent mevt) { mouseMoved(mevt); } // method: mouseDragged protected void mouseDragged(MouseEvent mevt) { mouseMoved(mevt); } protected void mouseReleased(MouseEvent mevt) { mouseMoved(mevt); } // add various actions protected void addActions() { // add the mouse actions for the graphics window adapter.addMouseMovedAction(mouseMoved); adapter.addMousePressedAction(mousePressed); adapter.addMouseDraggedAction(mouseDragged); adapter.addMouseReleasedAction(mouseReleased); } private void ResetCards() { ResetCards(true); } protected void ResetCards(boolean doRepaint) { this.cards = WebImageTools.readImagesAsPaintableLite("http://www.ccs.neu.edu/jpt/images/jfitz_cards_jpg/", "imagelist.txt"); this.cardSequence = new PaintableSequence(cards); // obtain a permutation for randomizing the cards int[] permutation = ProbStatTools.randomPermutation(cards.length); window.clearSequence(); int wmax = getMaxWidth(); int hmax = getMaxHeight(); for (int i = 0; i < cards.length; i++) { // pick a random card using the permutation int k = permutation[i]; // compute a random position for this card int x = MathUtilities.randomInt(5, wmax); int y = MathUtilities.randomInt(5, hmax); // move this card cards[k].move(x, y); } window.appendSequence(cards); // Add center point not in the main cardSequence rotatePoint.moveCenterTo(rotatePoint.getOriginalCenter()); window.addPaintableAtTop(rotatePoint); if (doRepaint) window.repaint(); } protected void RandomTranslateAndRotate() { // exit if the cards could not be or have not been read if (this.cards == null) return; // Reshow cards if the graphics have been cleared if (window.getPaintableSequence().length() == 0) ResetCards(false); cardSequence.setMutateAsItems(); cardSequence.addPostMutation(Mutator.randomTranslateRotate(getMaxWidth(), 180)); //window.clearSequence(); EnsureAllCardsVisible(); //window.appendSequence(cards); window.repaint(); } protected void RandomRotateAsGroup() { // exit if the cards could not be or have not been read if (this.cards == null) return; // Reshow cards if the graphics have been cleared if (window.getPaintableSequence().length() == 0) ResetCards(false); cardSequence.setMutateAsGroup(); // Get the coordinates of the rotate point int x = (int)rotatePoint.getCenter().getX(); int y = (int)rotatePoint.getCenter().getY(); System.out.println(x + ", " + y); // Rotate a random angle about the rotate point cardSequence.addPostMutation(TransformFactory.randomRotate( x, y, 180)); window.repaint(); } // method: clear graphics window protected void clear() { window.clearPanelAndSequence(); window.repaint(); } private void EnsureAllCardsVisible() { int wmax = getMaxWidth(); int hmax = getMaxHeight(); // Make sure all cards are at least partially visible for (int i = 0; i < cards.length; i++) { double cardX = cards[i].getCorner().x; double cardY = cards[i].getCorner().y; if ((cardX < 0) || (cardY < 0)) { if (cardX < 0) cardX = -cardX; if (cardY < 0) cardY = -cardY; cards[i].moveCenterTo(cardX, cardY); } if ((cardX > wmax) && (cardY > hmax)) cards[i].move(wmax - cardX, hmax - cardY); else if (cardX > wmax) cards[i].move(wmax - cardX, cardY); else if (cardY > hmax) cards[i].move(cardX, hmax - cardY); } } private XPoint2D getCenter() { return new XPoint2D(window.getBufferWidth() / 2.0, window.getBufferHeight() / 2.0); } private int getMaxWidth() { return getMaxDimension(window.getBufferWidth(), cards[0].getImageWidth(), 5); } private int getMaxHeight() { return getMaxDimension(window.getBufferHeight(), cards[0].getImageHeight(), 5); } private int getMaxDimension(int windowDimension, int imageDimension, int minDimension) { return windowDimension - imageDimension - minDimension; } public static void main(String[] args) { JPTFrame.createQuickJPTFrame("Card Tricks", new Thomas_CardTricks()); } }