home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 14 / IOPROG_14.ISO / soft / sdkjava / sdkjava.exe / SDKJava.cab / AFC102 / Samples / Puzzle15 / Src / Pz15ControlPanel.java < prev    next >
Encoding:
Java Source  |  1998-03-05  |  7.7 KB  |  337 lines

  1. //
  2. // (c) 1997 Microsoft Corporation.    All rights reserved.
  3. //
  4. import java.awt.Event;
  5. import com.ms.ui.*;
  6. import com.ms.fx.*;
  7.  
  8. class Pz15ControlPanel extends UIPanel implements Pz15Consts, Pz15Callbacks, Runnable
  9. {
  10.     public    boolean            appmodal = true;
  11.     private Pz15GamePanel    gameboard;
  12.     private UIFrame            frame;
  13.     private Pz15Options        props;
  14.     private Pz15Data        puzzle;
  15.     private Pz15Menu        menu;
  16.     private Pz15InfoPanel    info;
  17.     private Pz15Solver        pzsolver;
  18.     private Thread            solver;
  19.     private boolean            can_undo, can_restart;
  20.     private boolean            solversuspended = false;
  21.  
  22.     public Pz15ControlPanel(UIApplet applet, UIFrame frame)
  23.     {
  24.         setLayout(new UIBorderLayout(0,0));
  25.  
  26.         // Options Property Pages
  27.         if ( applet != null )
  28.             this.frame = FxToolkit.getHelperUIFrame();
  29.         else
  30.             this.frame = frame;
  31.  
  32.  
  33.         props = new Pz15Options(this.frame, "Game...", true, UIPropertyDialog.MEDIUM);
  34.         props.addPage("...Options", new Pz15PropGame(props));
  35.         props.addPage("...Navigation", new Pz15PropNav(props));
  36.  
  37.         can_undo = false; can_restart = false;
  38.  
  39.         puzzle = new Pz15Data();
  40.  
  41.         // Initialized load on demand images
  42.         Pz15Images.init(applet, frame);
  43.  
  44.         gameboard = new Pz15GamePanel(puzzle, this);
  45.         gameboard.drawBlank();
  46.         menu = new Pz15Menu(this, applet == null);
  47.         info = new Pz15InfoPanel();
  48.         //
  49.         // Create instance of solver whether he is used or not.
  50.         //      pzsolver will always be instantiated, solver (the thread )
  51.         //      will only be instantiated if needed.
  52.         //
  53.         pzsolver = new Pz15Solver();
  54.         pzsolver.registerCallback(this, this.frame);
  55.  
  56.         add(menu, "North");
  57.         UIPanel pnl = new UIPanel();
  58.         pnl.setLayout(new UISplitLayout(UISplitLayout.HORIZONTAL,300));
  59.         pnl.add(gameboard, "nw"); pnl.add(info, "se");
  60.         add(pnl, "Center");
  61.     }
  62.  
  63.     public void run()
  64.     {
  65.         // Display Options
  66.         Object ret = props.display();
  67.         if ( (ret instanceof IUIComponent) &&
  68.                 (((IUIComponent)ret).getID() != UIButtonBar.ID_CANCEL) ) {
  69.             // Scramble puzzle according to user input
  70.             puzzle.genNew(props.numscramble);
  71.             // Start new game
  72.             newGame();
  73.         }
  74.         else
  75.             setMarqueeString(MRQ_START, S_RESET);
  76.         // Turn on marquee
  77.         info.marquee.is_on = true;
  78.         // give focus to gameboard
  79.         gameboard.requestFocus();
  80.     }
  81.  
  82.     public void initialize()
  83.     {
  84.         Thread th = new Thread(this);
  85.         th.start();
  86.     }
  87.  
  88.     public void hideProperties()
  89.     {
  90.         if ( props != null )
  91.             props.setVisible(false);
  92.     }
  93.  
  94.     public void restartGame()
  95.     {
  96.         puzzle.init();
  97.         reset();
  98.         // If solver hasn't solved the puzzle, it will update marquee with progress.
  99.         if ( pzsolver.solved )
  100.             setMarqueeString(MRQ_OPTIMALFND, S_OPTFND);
  101.     }
  102.  
  103.     public void newGame()
  104.     {
  105.         stopSolver(); // You can call stop on an already stopped thread
  106.         puzzle.genNew(props.numscramble);
  107.         reset();
  108.         enableShowSolution(false);
  109.         setOptMoves(puzzle.initial_cost, puzzle.solved);
  110.         startSolver();
  111.     }
  112.  
  113.     private void reset()
  114.     {
  115.         gameboard.removeAll();
  116.         gameboard.draw();
  117.         gameboard.setVisible(true);
  118.         gameboard.setInitialFocus();
  119.         setNumMoves(0);
  120.         setMinMoves(puzzle.initial_cost);
  121.         enableUndo(false);
  122.         enableRestart(false);
  123.     }
  124.  
  125.     private void initSolver()
  126.     {
  127.         pzsolver.genNew(puzzle.original);
  128.         solver = new Thread(pzsolver, "Solver");
  129.         solver.setPriority(Thread.MIN_PRIORITY);
  130.         solver.start();
  131.         setMarqueeString(MRQ_SEARCHING + " 0 nodes.", S_RESET);
  132.     }
  133.  
  134.     private void startSolver()
  135.     {
  136.         if ( props.cpuactive ) {
  137.             if ( solver != null ) {
  138.                 // you can't start a thread that has been stopped, you need
  139.                 //    to create a new instance
  140.                 stopSolver();
  141.                 initSolver();
  142.             }
  143.             else if ( !pzsolver.solved )
  144.                 initSolver();
  145.         }
  146.         else {
  147.             stopSolver();
  148.             solver = null;
  149.             setMarqueeString(MRQ_NOTSEARCHING, S_RESET);
  150.         }
  151.     }
  152.  
  153.     public void stopSolver()
  154.     {
  155.         if ( solver != null )
  156.             solver.stop();
  157.     }
  158.  
  159.     public void undoMove()
  160.     {
  161.         if ( puzzle.solved )
  162.             return;
  163.  
  164.         if ( puzzle.movstk.size() > 0 ) {
  165.             Object move = puzzle.movstk.peek();
  166.             if ( move instanceof Integer ) {
  167.                 int mov = -((Integer)move).intValue();
  168.                 gameboard.update(mov);
  169.             }
  170.         }
  171.     }
  172.  
  173.     public void displayOptionsDialog()
  174.     {
  175.         if ( solver != null ) {
  176.             synchronized (this) {
  177.                 if ( solver.isAlive() ) {
  178.                     solver.suspend();
  179.                     solversuspended = true;
  180.                 }
  181.             }
  182.         }
  183.  
  184.         info.marquee.is_on = false;
  185.  
  186.         PropsThread propsthr = new PropsThread(props, this);
  187.         propsthr.start();
  188.     }
  189.  
  190.     public void doOptionsFinished()
  191.     {
  192.         info.marquee.is_on = true;
  193.  
  194.         gameboard.requestFocus();
  195.  
  196.         if ( props.cpuactive ) {
  197.             if ( !pzsolver.solved ) {
  198.                 if ( solversuspended )
  199.                     solver.resume();
  200.                 else
  201.                     startSolver();
  202.             }
  203.         }
  204.         else {
  205.             if ( solversuspended )
  206.                 solver.stop();
  207.             pzsolver.solved = false;
  208.         }
  209.     }
  210.  
  211.     public void setOptMoves(int nmoves, boolean optimal)
  212.     {
  213.         if ( optimal )
  214.             info.optmoves.setName("Exactly " + nmoves + " moves");
  215.         else
  216.             info.optmoves.setName("At least " + nmoves + " moves");
  217.     }
  218.  
  219.     public void displayOptimalSolution()
  220.     {
  221.         info.marquee.is_on = false;
  222.         pzsolver.displayOptimalSolution();
  223.         info.marquee.is_on = true;
  224.         gameboard.requestFocus();
  225.     }
  226.  
  227.     public void setMarqueeString(String str, int state)
  228.     {
  229.         info.mrqstr = str;
  230.         // if we are already displaying the correct string do not reset
  231.         if ( (state == S_RESET) || ((state != S_NORESET) && (state != info.marquee.state)) )
  232.             info.marquee.reset = true;
  233.         info.marquee.state = state;
  234.     }
  235.  
  236.     public void congratulate()
  237.     {
  238.         String str = new String(CONGRATS_STR1);
  239.  
  240.         if ( pzsolver.solved )
  241.             str += CONGRATS_OPT;
  242.         else
  243.             str += CONGRATS_STR2;
  244.  
  245.         UIMessageBox mbox = new UIMessageBox(frame, "Congratulations!", str,
  246.                                                 Pz15Images.get(CONGRATS),
  247.                                                 new UIButtonBar(UIButtonBar.OK,
  248.                                                                 UIButtonBar.RAISED));
  249.         mbox.setFont(new FxFont("Dialog", FxFont.PLAIN, 14));
  250.         info.marquee.is_on = false;
  251.         mbox.doModal();
  252.         info.marquee.is_on = true;
  253.     }
  254.  
  255.     public void setNumMoves(int nmoves)    { info.nummoves.setName("" + nmoves); }
  256.  
  257.     public void setMinMoves(int nmoves)    { info.minmoves.setName("" + nmoves); }
  258.  
  259.     public void enableUndo(boolean enable)
  260.     {
  261.         can_undo = enable;
  262.         menu.enable(ID_UNDO, enable);
  263.     }
  264.  
  265.     public void enableRestart(boolean enable)
  266.     {
  267.         can_restart = enable;
  268.         menu.enable(ID_RESTART, enable);
  269.     }
  270.  
  271.     public int getNavMode() { return props.navmode; }
  272.  
  273.     public boolean getSolverStatus() { return pzsolver.solved; }
  274.  
  275.     public int getOptimalCost() { return pzsolver.costbound; }
  276.  
  277.     public void enableShowSolution(boolean enable) { menu.enable(ID_SOLUTION, enable); }
  278.  
  279.     public boolean keyDown(Event e, int key)
  280.     {
  281.         if ( e.modifiers == 0 ) {
  282.             switch ( key ) {
  283.             case Event.F2: newGame(); break;
  284.             case Event.F4: if ( can_restart ) restartGame(); break;
  285.             case Event.F3: if ( pzsolver.solved ) displayOptimalSolution(); break;
  286.             case Event.F7: displayOptionsDialog(); break;
  287.             default: return super.keyDown(e, key);
  288.             }
  289.         }
  290.         else if ( e.modifiers == Event.CTRL_MASK ) {
  291.             switch ( key ) {
  292.             case 'x'-'a'+1:
  293.                 stopSolver();
  294.                 System.exit(0);
  295.                 break;
  296.             case 'z'-'a'+1:
  297.                 if ( can_undo ) undoMove();
  298.                 return true;
  299.             default:
  300.                 return super.keyDown(e, key);
  301.             }
  302.         }
  303.         return true; // keyDown was handled if we get to here
  304.     }
  305.  
  306.     public boolean handleEvent(Event evt)
  307.     {
  308.         if ( appmodal )
  309.             return true;
  310.         else
  311.             return super.handleEvent(evt);
  312.     }
  313.  
  314.     public void requestFocus() { gameboard.requestFocus(); }
  315. }
  316.  
  317. class PropsThread extends Thread
  318. {
  319.     private Pz15Options props;
  320.     private Pz15ControlPanel pzctrl;
  321.  
  322.     public PropsThread(Pz15Options pzopts, Pz15ControlPanel ctrl)
  323.     {
  324.         props = pzopts;
  325.         pzctrl = ctrl;
  326.     }
  327.         
  328.     public void run()
  329.     {
  330.         pzctrl.appmodal = true;
  331.         props.display();
  332.         pzctrl.doOptionsFinished();
  333.         pzctrl.appmodal = false;
  334.     }
  335. }
  336.  
  337.