home *** CD-ROM | disk | FTP | other *** search
/ BUG 15 / BUGCD1998_06.ISO / aplic / jbuilder / jsamples.z / ChessViewer.java < prev    next >
Encoding:
Java Source  |  1997-07-15  |  60.4 KB  |  1,768 lines

  1. //
  2. //
  3. //  ChessViewer.java
  4. //  applet to view a chess pgn file
  5. //
  6. //
  7. package borland.samples.apps.chess.client;
  8.  
  9. import java.awt.* ;
  10. import java.awt.event.*;
  11. import java.net.*;
  12. import java.applet.*;
  13. import java.io.*;
  14. import java.util.*;
  15. import java.beans.*;
  16. import borland.samples.apps.chess.client.board.*;
  17. import borland.jbcl.control.*;
  18. import borland.jbcl.layout.*;
  19. import borland.jbcl.view.*;
  20. import borland.jbcl.model.*;
  21. import borland.jbcl.util.Alignment;
  22. import borland.jbcl.util.VetoException;
  23.  
  24. public class ChessViewer extends Applet implements ModalParent, Runnable
  25. {
  26.   boolean threadFlag = true;
  27.   ColumnView[] columns = new ColumnView[4];
  28.   Button[] navBtn = new Button[8];
  29.   Thread clock;             //This thread does the chessclock
  30.   ClientSender sender;      //This thread sends data to server
  31.   ClientListener ourServer; //the thread that listens to the sever
  32.   boolean imageLoadError = false;
  33.   public boolean isStandalone = false;
  34.   boolean loggedon = false;
  35.   boolean doNothing = false;
  36.   boolean hasListeners = false;
  37.   boolean showLibraryGame = true;
  38.  
  39.   String filename ;
  40.   String myName = "";
  41.   String opponentName;       //null when not a live game
  42.   String challenger;       //opponent's name before the challenge is accepted
  43.  
  44.   int listuse ;   //used as enum PlayerList,LIBRARYLIST,MOVELIST,KIBITZ
  45.   Vector listContents;
  46.   Vector libraryListContents;
  47.   Vector pieceGif;
  48.   String subroutine = "Init";
  49.   String msg = " ";
  50.   int movecount=0;  //index of selected item in playerList
  51.   int count = 0;   // size of List playerList
  52.   int importCount = 0;
  53.   boolean moveToken = true;
  54.   Hashtable libraryHash = new Hashtable();
  55.   boolean blackOnTop = true;
  56.   int[] moveSubscript = new int[8];
  57.   static final int PLAYERLIST  = 1;
  58.   static final int LIBRARYLIST = 2;
  59.   static final int MOVELIST    = 0;
  60.   static final int KIBITZ      = 3;
  61.   static final String PLAYERLIST_LABEL = "Players";
  62.   static final String LIBRARYLIST_LABEL = "Library";
  63.   static final String MOVELIST_LABEL = "Moves";
  64.   boolean okay=true;
  65.   int color = ChessRules.Black; //the color that made the last move
  66.   int yourColor = ChessRules.Black;
  67.   long[] playerTime = new long[2];
  68.   int gameTimeValue;
  69.   long lMoveTime;
  70.   ChessRules game;
  71.   String imageNames ="/images/cmpieces.gif;/images/owlpieces.gif"; //Image parameter default data
  72.   String host = "ghamer2"; //HOST parameter default data
  73.   //URL selectedImage;
  74.   long     opponentsTimeWhenStopped = 0; //other players time when the applet was suspended
  75.   boolean  timerWasStopped = false; //Was the chessclock thread killed because the applet was suspended?
  76.   long     timeStopped =  0;  //the SystemTime when the applet was suspended.
  77.   LogonDialog pDialog;
  78.   Frame f = null;
  79.   static String CREATED_WITH_BORLAND = "Created with Borland JBuilder \r\n";
  80.   static String DESCRIPTION_A_CHESS = "Description: A Chess Server/Viewer ";
  81.   CompositeGridView gridControl1; //more work to setup than a GridControl, but 500k less to deploy and since we
  82.                                   //we do not use a dataset and we are an applet seemed like a good idea
  83.   SplitPanel splitPanel ;
  84.   Button button0;
  85.   Button button1;
  86.   Button button2;
  87.   Button button3;
  88.   Button button4;
  89.   Button button5;
  90.   Button button6;
  91.   Button button7;
  92.   Label        topName;
  93.   Label        bottomName;
  94.   TextField    chatText;
  95.   Panel        statusPanel;
  96.   BorderLayout appletBorderLayout;
  97.   BorderLayout statusPanelBorderLayout;
  98.   Panel statusButtons;
  99.   GridLayout statusButtonsGridLayout;
  100.   Button sbLogon;
  101.   Button sbChoose;
  102.   Button optionsButton;
  103.   Label statusLine;
  104.   TextArea infoText;
  105.   Panel p;
  106.   GridLayout pGridLayout;
  107.   BorderLayout pBorderLayout;
  108.   Panel w;
  109.   BorderLayout wBorderLayout;
  110.   Panel b;
  111.   BorderLayout bBorderLayout;
  112.   EastPanel ep;
  113.   Panel altButtons;
  114.   GridLayout altButtonsGridLayout;
  115.   TabsetPanel listPanel;
  116.   List libraryList;
  117.   List playerList;
  118.   Chessboard theboard;
  119.   Label topTime;
  120.   Label bottomTime;
  121.   Panel timePanel;
  122.   Panel bottomInfo;
  123.   BorderLayout bottomInfoBorderLayout;
  124.   Panel topInfo;
  125.   BorderLayout topInfoBorderLayout;
  126.   Panel statusLinePanel;
  127.   BorderLayout statusLinePanelBorderLayout;
  128.   TextField moveTime;
  129.   TextField gameTime;
  130.   BorderLayout epLayout;
  131.   Label gameTimeLabel;
  132.   Label minutesLabel;
  133.   Label moveTimeLabel;
  134.  
  135.   public ChessViewer()  {
  136.     //System.out.println ("ChessViewer xtor d");
  137.     listContents = new Vector();
  138.     libraryListContents = new Vector();
  139.     game = new ChessRules();
  140.   }
  141.  
  142.   static public void main(String[] args) {
  143.     ChessViewer app = new ChessViewer();
  144.     app.isStandalone = true;
  145.     app.getParameters(args);
  146.     if (args.length == 1 && args[0].equals("?")) {
  147.       String [][] info = app.getParameterInfo();
  148.       if (info != null)
  149.         for (int i=0;i<info.length;i++)
  150.           System.out.println(info[i][0] + "=(" + info[i][0]+ ") " + info[i][2]);
  151.     }
  152.     DecoratedFrame frame = new DecoratedFrame();
  153.     //frame.setLayout(new BorderLayout());
  154.     frame.add(app,BorderLayout.CENTER);
  155.     frame.setTitle("ChessViewer");
  156.     frame.setBounds(0,-500,40,30);
  157.     frame.setVisible(false);
  158.     frame.show();     //needs to happen before Chessboard.setImage() so image observer is real?
  159.  
  160.     app.init();
  161.     frame.pack();
  162.      // Center the frame
  163.     Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
  164.     Dimension frameSize = frame.getPreferredSize();
  165.     if (frameSize.height > screenSize.height)
  166.       frameSize.height = screenSize.height;
  167.     if (frameSize.width > screenSize.width)
  168.       frameSize.width = screenSize.width;
  169.     frame.setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2);
  170.     frame.setVisible(true);
  171.     if (app.pDialog != null)
  172.       app.pDialog.name.requestFocus();
  173.   }
  174.  
  175.   String getParameter(String parmName, String args[]) {
  176.     if (args == null) {
  177.       return getParameter(parmName);
  178.     }
  179.     int i;
  180.     String strArg = parmName + '=';
  181.     String strValue = null;
  182.     for (i = 0; i < args.length; i++) {
  183.       int index = args[i].indexOf('=') + 1;
  184.       if (strArg.equalsIgnoreCase(args[i].substring(0, index))) {
  185.         strValue= args[i].substring(strArg.length());
  186.         if (strValue.startsWith("\"")) {
  187.           strValue = strValue.substring(1);
  188.           if (strValue.endsWith("\""))
  189.             strValue = strValue.substring(0, strValue.length() - 1);
  190.         }
  191.       }
  192.     }
  193.     return strValue;
  194.   }
  195.  
  196.   void getParameters(String args[]) {
  197.     String param;
  198.     param = getParameter(CVS.IMAGENAME, args);
  199.     if (param != null)
  200.       imageNames = param;
  201.     param = getParameter("HOST", args);
  202.     if (param != null)
  203.       host = param;
  204.     param = getParameter(CVS.GAMEPARAMNAME,args);
  205.     if (param != null)
  206.       filename = param;
  207.   }
  208.  
  209.   public String [] [] getParameterInfo() {
  210.     String[][] info = {
  211.     { CVS.IMAGENAME, "String", CVS.SEMICOLON_DELIMITED },
  212.         { CVS.GAMEPARAMNAME, "String", CVS.PGN_FILE_TO_LOAD_VERY},
  213.     { "HOST", "String", CVS.THE_HOSTNAME_OF_THE },
  214.     };
  215.     return info;
  216.   }
  217.  
  218.   public String getAppletInfo() {
  219.     return "Name: ChessViewer\r\n" +
  220.     "Author: Greg Hamer\r\n" +
  221.     ChessViewer.CREATED_WITH_BORLAND +
  222.     ChessViewer.DESCRIPTION_A_CHESS;
  223.   }
  224.  
  225.   public void init() {
  226.     try {
  227.       pieceGif = new Vector();
  228.       int i ;
  229.       if (!isStandalone) {
  230.         getParameters(null);
  231.         host = getCodeBase().getHost(); //Override the parameter since we are an
  232.                                         //applet and this is only server we are
  233.                                         //capable of talking to
  234.       }
  235.       //parse imageNames into Vector pieceGif
  236.       int index = -1;
  237.       while (true) {
  238.         int nextIndex = imageNames.indexOf(';',index+1);
  239.         if (nextIndex == -1)
  240.           nextIndex = imageNames.length();
  241.         String imageName = imageNames.substring(index+1,nextIndex);
  242.         System.out.println("imageName = " + imageName);
  243.         URL imageURL;
  244.         try {
  245.           if (isStandalone)
  246.             if (imageName.startsWith("file://"))
  247.               imageURL = new URL(imageName);
  248.             else
  249.               imageURL = new URL("http",host,imageName);
  250.           else
  251.             imageURL = new URL(getDocumentBase(),imageName);
  252.           pieceGif.addElement(imageURL);
  253.         }
  254.         catch (Exception e) {
  255.           System.out.println( e + host +"  " +  imageName);
  256.         }
  257.         index = nextIndex;
  258.         if (index >= imageNames.length() -1)
  259.           break;
  260.       }
  261.       int j;
  262.       f = ChessViewer.getFrame(this);
  263.       if (f == null)
  264.         System.out.println("Where is the frame?");
  265.       else
  266.         System.out.println("frame title is " + f.getTitle());
  267.       jbInit();
  268.     }
  269.     catch (Exception e ) {
  270.       System.out.println("chessViewer.init " + e);
  271.       e.printStackTrace();
  272.     }
  273.     game.setPieceValues(0,1,theboard.getPiecePosition());
  274.     game.setPieceColors(0,1,theboard.getColorPosition());
  275.     subroutine = "parsePGNFile";
  276.     URL PGNurl = null;
  277.     listuse = KIBITZ;
  278.     String message;
  279.     InputStream is = null;
  280.  
  281.     try {
  282.       if (filename != null) {
  283.         if (isStandalone)
  284.           PGNurl = new URL("http",host,filename);
  285.         else
  286.           PGNurl  = new URL(getDocumentBase(),filename);
  287.         is = PGNurl.openStream();
  288.         if (is != null){
  289.           infoText.setText("");
  290.           Reader reader = new InputStreamReader(is);
  291.           BufferedReader bufferedReader = new BufferedReader(reader);
  292.           game.parsePGNFile (bufferedReader);
  293.           listuse = KIBITZ;
  294.              subroutine = "parsePGNFile done";
  295.         }
  296.         else {
  297.             topName.setText(CVS.COULD_NOT_OPEN + filename);
  298.         }
  299.       }
  300.       else
  301.         System.out.println("no file specified");
  302.       topName.setText(game.getPlayerB());
  303.       bottomName.setText(game.getPlayerW());
  304.       System.out.println("init start thread");
  305.       clock = new Thread(this);
  306.       //clock.setPriority(Thread.NORM_PRIORITY + 1); //to help the images load
  307.       clock.start();
  308.       clock = null; //don't want the opportunity to kill loading the board image.
  309.       System.out.println("init call fillMoveList");
  310.       fillMoveList();
  311.       color = ChessRules.Black;
  312.       System.out.println("init call dispalypos" );
  313.       logonEnable(false);
  314.       displayPos();
  315.       System.out.println("init back from call dispalypos" );
  316.       if (filename == null)
  317.         startsocket();
  318.     }
  319.     catch( IOException x)  {
  320.       message = x.toString() ;
  321.       if (PGNurl != null)
  322.        message = message +  " "+ PGNurl.toString();
  323.       else
  324.         message = CVS.QUESTION_MARKS + message;
  325.       if (bottomName != null)
  326.         bottomName.setText(message);
  327.     }
  328.     catch(Exception e)  {
  329.       System.out.println( "init " + e);
  330.       e.printStackTrace();
  331.       message = e.toString();
  332.       if (topName != null)
  333.         topName.setText(subroutine + count );
  334.       if (bottomName != null)
  335.         bottomName.setText(message);
  336.     }
  337.     try {
  338.       if (is != null)
  339.           is.close();
  340.     }
  341.     catch(Exception e) {}
  342.   }
  343.  
  344.   void jbInit() throws Exception {
  345.     gridControl1 = (CompositeGridView) Beans.instantiate(getClass().getClassLoader(),"borland.jbcl.view.CompositeGridView");
  346.     splitPanel = (SplitPanel) Beans.instantiate(getClass().getClassLoader(),"borland.jbcl.control.SplitPanel");
  347.     button0 = (Button) Beans.instantiate(getClass().getClassLoader(),"java.awt.Button");
  348.     button1 = (Button) Beans.instantiate(getClass().getClassLoader(),"java.awt.Button");
  349.     button2 = (Button) Beans.instantiate(getClass().getClassLoader(),"java.awt.Button");
  350.     button3 = (Button) Beans.instantiate(getClass().getClassLoader(),"java.awt.Button");
  351.     button4 = (Button) Beans.instantiate(getClass().getClassLoader(),"java.awt.Button");
  352.     button5 = (Button) Beans.instantiate(getClass().getClassLoader(),"java.awt.Button");
  353.     button6 = (Button) Beans.instantiate(getClass().getClassLoader(),"java.awt.Button");
  354.     button7 = (Button) Beans.instantiate(getClass().getClassLoader(),"java.awt.Button");
  355.     topName     = (Label)Beans.instantiate(getClass().getClassLoader(),"java.awt.Label");
  356.     bottomName  = (Label)Beans.instantiate(getClass().getClassLoader(),"java.awt.Label");
  357.     chatText    = (TextField) Beans.instantiate(getClass().getClassLoader(),"java.awt.TextField");
  358.     statusPanel = (Panel) Beans.instantiate(getClass().getClassLoader(),"java.awt.Panel");
  359.     appletBorderLayout = (BorderLayout) Beans.instantiate(getClass().getClassLoader(),"java.awt.BorderLayout");
  360.     statusPanelBorderLayout = (BorderLayout) Beans.instantiate(getClass().getClassLoader(),"java.awt.BorderLayout");
  361.     statusButtons = (Panel) Beans.instantiate(getClass().getClassLoader(),"java.awt.Panel");
  362.     statusButtonsGridLayout = (GridLayout)Beans.instantiate(getClass().getClassLoader(),"java.awt.GridLayout");
  363.     sbLogon       = (Button) Beans.instantiate(getClass().getClassLoader(),"java.awt.Button");
  364.     sbChoose      = (Button) Beans.instantiate(getClass().getClassLoader(),"java.awt.Button");
  365.     optionsButton = (Button) Beans.instantiate(getClass().getClassLoader(),"java.awt.Button");
  366.     statusLine = (Label)Beans.instantiate(getClass().getClassLoader(),"java.awt.Label");
  367.     infoText = (TextArea) Beans.instantiate(getClass().getClassLoader(),"java.awt.TextArea");
  368.     p = (Panel) Beans.instantiate(getClass().getClassLoader(),"java.awt.Panel");
  369.     pGridLayout = (GridLayout)Beans.instantiate(getClass().getClassLoader(),"java.awt.GridLayout");
  370.     pBorderLayout = (BorderLayout) Beans.instantiate(getClass().getClassLoader(),"java.awt.BorderLayout");
  371.     w = (Panel) Beans.instantiate(getClass().getClassLoader(),"java.awt.Panel");
  372.     wBorderLayout = (BorderLayout) Beans.instantiate(getClass().getClassLoader(),"java.awt.BorderLayout");
  373.     b = (Panel) Beans.instantiate(getClass().getClassLoader(),"java.awt.Panel");
  374.     bBorderLayout = (BorderLayout) Beans.instantiate(getClass().getClassLoader(),"java.awt.BorderLayout");
  375.     ep = (EastPanel)(Panel) Beans.instantiate(getClass().getClassLoader(),"borland.samples.apps.chess.client.EastPanel");
  376.     altButtons = (Panel) Beans.instantiate(getClass().getClassLoader(),"java.awt.Panel");
  377.     altButtonsGridLayout = (GridLayout)Beans.instantiate(getClass().getClassLoader(),"java.awt.GridLayout");
  378.     listPanel = (TabsetPanel) Beans.instantiate(getClass().getClassLoader(),"borland.jbcl.control.TabsetPanel");
  379.     libraryList = (List)Beans.instantiate(getClass().getClassLoader(),"java.awt.List");
  380.     playerList  = (List)Beans.instantiate(getClass().getClassLoader(),"java.awt.List");
  381.     theboard = (Chessboard) Beans.instantiate(getClass().getClassLoader(),"borland.samples.apps.chess.client.board.Chessboard");
  382.     topTime = (Label)Beans.instantiate(getClass().getClassLoader(),"java.awt.Label");
  383.     bottomTime = (Label)Beans.instantiate(getClass().getClassLoader(),"java.awt.Label");
  384.     timePanel = (Panel) Beans.instantiate(getClass().getClassLoader(),"java.awt.Panel");
  385.     bottomInfo = (Panel) Beans.instantiate(getClass().getClassLoader(),"java.awt.Panel");
  386.     bottomInfoBorderLayout = (BorderLayout) Beans.instantiate(getClass().getClassLoader(),"java.awt.BorderLayout");
  387.     topInfo = (Panel) Beans.instantiate(getClass().getClassLoader(),"java.awt.Panel");
  388.     topInfoBorderLayout  = (BorderLayout) Beans.instantiate(getClass().getClassLoader(),"java.awt.BorderLayout");
  389.     statusLinePanel= (Panel) Beans.instantiate(getClass().getClassLoader(),"java.awt.Panel");
  390.     statusLinePanelBorderLayout = (BorderLayout) Beans.instantiate(getClass().getClassLoader(),"java.awt.BorderLayout");
  391.     moveTime = (TextField) Beans.instantiate(getClass().getClassLoader(),"java.awt.TextField");
  392.     gameTime = (TextField) Beans.instantiate(getClass().getClassLoader(),"java.awt.TextField");
  393.     epLayout = (BorderLayout) Beans.instantiate(getClass().getClassLoader(),"java.awt.BorderLayout");
  394.     gameTimeLabel = (Label)Beans.instantiate(getClass().getClassLoader(),"java.awt.Label");
  395.     minutesLabel  = (Label)Beans.instantiate(getClass().getClassLoader(),"java.awt.Label");
  396.     moveTimeLabel = (Label)Beans.instantiate(getClass().getClassLoader(),"java.awt.Label");
  397.     w.setLayout(wBorderLayout);
  398.     b.setLayout(bBorderLayout);
  399.     w.add(b,BorderLayout.SOUTH);
  400.     pGridLayout.setRows(1);
  401.     pGridLayout.setColumns(4);
  402.     p.setLayout(pGridLayout);
  403.     b.add(p,BorderLayout.CENTER);
  404.  
  405.     button0.setLabel(CVS.BEGINNING_OF_GAME);
  406.     navBtn[0] = button0;
  407.     p.add(button0);
  408.     navBtn[1] = button1;
  409.     button1.setLabel(CVS.BACK_ONE_MOVE);
  410.     p.add(button1);
  411.     navBtn[3] = button3;
  412.     button3.setLabel(CVS.FORWARD_ONE_MOVE);
  413.     p.add(button3);
  414.     navBtn[2] =  button2;
  415.     button2.setLabel(CVS.END_OF_GAME);
  416.     p.add(button2);
  417.     b.add(altButtons,BorderLayout.SOUTH);
  418.     altButtonsGridLayout.setRows(1);
  419.     altButtonsGridLayout.setColumns(4);
  420.     altButtons.setLayout(altButtonsGridLayout);
  421.     navBtn[4] = button4;
  422.     button4.setLabel("Branch 1");
  423.     altButtons.add(button4);
  424.     navBtn[5] = button5;
  425.     button5.setLabel("Branch 2");
  426.     altButtons.add(button5);
  427.     navBtn[6] = button6;
  428.     button6.setLabel("Branch 3");
  429.     altButtons.add(button6);
  430.     navBtn[7] = button7;
  431.     button7.setLabel("Branch 4");
  432.     altButtons.add(button7);
  433.    
  434.     BoardButtonActionAdapter boardButtonActionAdapter = new BoardButtonActionAdapter(this);
  435.     for (int i=0;i<8;i++)
  436.       navBtn[i].addActionListener(boardButtonActionAdapter);
  437.  
  438.     PlayerListAdapter playerListAdapter = new PlayerListAdapter(this);
  439.     playerList.addActionListener(playerListAdapter);
  440.     playerList.addItemListener(playerListAdapter);
  441.     LibraryListAdapter libaryListAdapter = new LibraryListAdapter(this);
  442.  
  443.     libraryList.addActionListener(libaryListAdapter);
  444.     libraryList.addItemListener(libaryListAdapter);
  445.     
  446.     infoText.setRows(6);
  447.     infoText.setColumns(25);
  448.     infoText.setEditable(false);
  449.     statusPanel.setLayout(statusPanelBorderLayout);
  450.     statusLine.setText(CVS.LOGONHINT);
  451.     chatText.setText(CVS.CHATHINT);
  452.     OtherActionAdapter otherActionAdapter =   new OtherActionAdapter(this);
  453.     chatText.addActionListener(otherActionAdapter);
  454.     ep.setLayout(epLayout);
  455.     ep.add(chatText,BorderLayout.NORTH);
  456.  
  457.     statusButtonsGridLayout.setRows(1);
  458.     statusButtonsGridLayout.setColumns(4);
  459.     statusButtons.setLayout(statusButtonsGridLayout);
  460.  
  461.     gameTimeLabel.setText(CVS.GAMEIN);
  462.     timePanel.add (gameTimeLabel);
  463.     gameTimeLabel.setAlignment(Label.RIGHT);
  464.     gameTime.setText(CVS.DEFAULT_GAME_TIME);
  465.     timePanel.add (gameTime);
  466.  
  467.     minutesLabel.setText(CVS.MINUTES );
  468.     timePanel.add  (minutesLabel);
  469.     moveTime.setText(CVS.DEFAULT_MOVE_TIME);
  470.     timePanel.add (moveTime);
  471.  
  472.     moveTimeLabel.setText(CVS.MOVETIME);
  473.     int[] columnSizes = new int[4];
  474.     columnSizes[0] = 40;
  475.     columnSizes[1] = 50;
  476.     columnSizes[2] = 50;
  477.     columnSizes[3] = 100;
  478.     columns[0] = new ColumnView();
  479.     columns[1] = new ColumnView();
  480.     columns[2] = new ColumnView();
  481.     columns[3] = new ColumnView();
  482.     columns[0].setWidth(columnSizes[0]);
  483.     columns[1].setWidth(columnSizes[1]);
  484.     columns[2].setWidth(columnSizes[2]);
  485.     columns[3].setWidth(columnSizes[3]);
  486.     columns[0].setItemPainter(new TextItemPainter());
  487.     columns[3].setItemEditor(new ExpandingTextItemEditor());
  488.     columns[0].setCaption("Move");
  489.     columns[1].setCaption("White");
  490.     columns[2].setCaption("Black");
  491.     columns[3].setCaption("");
  492.     gridControl1.setColumnViews(columns);
  493.     gridControl1.setRowHeaderVisible(false);
  494.     SizeVector columnSizeVector = new VariableSizeVector(columnSizes);
  495.     gridControl1.setColumnSizes(columnSizeVector);
  496.     gridControl1.setRowSizes(new FixedSizeVector(20));
  497.     GC_ColumnHeaderManager columnManager = new GC_ColumnHeaderManager(columns);
  498.     gridControl1.getColumnHeaderView().setViewManager(columnManager);
  499.     gridControl1.getColumnHeaderView().setModel(columnManager);
  500.     gridControl1.setSelection(new SingleMatrixSelection(gridControl1.getSubfocus()));
  501.     gridControl1.addSubfocusListener(new ChessViewer_gridControl1_SubfocusAdapter(this));
  502.     this.setSize(new Dimension(687, 497));
  503.     gridControl1.setModel(game);
  504.     gridControl1.setViewManager(new BasicViewManager(
  505.         new FocusableItemPainter(
  506.             new SelectableTextItemPainter(Alignment.LEFT | Alignment.MIDDLE)),
  507.             new TextItemEditor(Alignment.LEFT | Alignment.MIDDLE)));
  508.     timePanel.add (moveTimeLabel);
  509.     sbChoose.setLabel(CVS.COPY_PASTE);
  510.     statusButtons.add(sbChoose);
  511.     statusButtons.add(optionsButton);
  512.     sbLogon.setLabel(CVS.LOGOFF );
  513.     statusButtons.add(sbLogon);
  514.     sbChoose.addActionListener(otherActionAdapter);
  515.     sbLogon.addActionListener(otherActionAdapter);
  516.  
  517.     statusPanel.add(statusButtons,BorderLayout.CENTER);
  518.     statusPanel.add(timePanel,BorderLayout.NORTH);
  519.  
  520.     optionsButton.addActionListener(otherActionAdapter);
  521.     optionsButton.setLabel(CVS.OPTIONS_);
  522.  
  523.     statusLinePanel.setLayout(statusLinePanelBorderLayout);
  524.     statusLinePanel.add(statusLine,BorderLayout.CENTER);
  525.  
  526.     statusPanel.add(statusLinePanel,BorderLayout.SOUTH);
  527.     ep.add(statusPanel,BorderLayout.SOUTH);
  528.     setLayout(appletBorderLayout);
  529.     add(w,BorderLayout.WEST);
  530.     add(ep,BorderLayout.EAST);
  531.     ep.add(splitPanel, BorderLayout.CENTER);
  532.     splitPanel.add(infoText,  new PaneConstraints("infoText","infoText",PaneConstraints.ROOT,1.0f));
  533.     splitPanel.add(listPanel, new PaneConstraints("listPanel","infoText",PaneConstraints.BOTTOM,0.6f));
  534.  
  535.     listPanel.add(gridControl1, MOVELIST_LABEL);
  536.     listPanel.add(playerList, PLAYERLIST_LABEL);
  537.     listPanel.add(libraryList, LIBRARYLIST_LABEL);
  538.     listPanel.setSelectedTab(PLAYERLIST_LABEL);
  539.     listPanel.setTabsOnTop(false);
  540.     listPanel.setMargins(new Insets(0, 0, 0, 0));
  541.     listPanel.addSubfocusListener(new ChessViewer_listPanel_SubfocusAdapter(this));
  542.     Font boldFont = new Font(getFont().getName(),Font.BOLD,getFont().getSize());
  543.     bottomName = new Label();
  544.     bottomName.setText(game.getPlayerW());
  545.     bottomName.setFont(boldFont);
  546.     topName.setText(game.getPlayerB());
  547.     topName.setFont(boldFont);
  548.     topInfo.setLayout(topInfoBorderLayout);
  549.     topTime.setFont(boldFont);
  550.     bottomInfo.setLayout(bottomInfoBorderLayout);
  551.     bottomTime.setFont(boldFont);
  552.     bottomInfo.add(bottomName,BorderLayout.CENTER);
  553.     bottomInfo.add(bottomTime, BorderLayout.EAST);
  554.     w.add(theboard, BorderLayout.CENTER);
  555.     topInfo.add(topName, BorderLayout.CENTER);
  556.     topInfo.add(topTime, BorderLayout.EAST);
  557.     w.add(topInfo, BorderLayout.NORTH);
  558.     b.add(bottomInfo, BorderLayout.NORTH);
  559.     bottomTime.setText(CVS.ZEROTIME);
  560.     topTime.setText(CVS.ZEROTIME);
  561.     theboard.addActionListener(new ChessboardAdapt(this));
  562.     //so it comes up pretty in the designer; set to something real in run()
  563.     theboard.setImageName("file:///jbuilder/samples/borland/samples/apps/chess/client/images/cmpieces.gif");
  564.   }
  565.  
  566.   public void fillMoveList() {
  567.     try {
  568.       game.generatePositions();
  569.       //System.out.println("FillMoveList returned from generatePositions");
  570.       count = game.getArraySize();
  571.       subroutine= "fillMoveList";
  572.       moveSubscript[0] = 1;
  573.       moveSubscript[1] = 0;
  574.       moveSubscript[2] = count;
  575.       moveSubscript[3] = 0;
  576.       int movenumber;
  577.       for (int i=1;i<=count;i++)    {
  578.         movenumber = game.getMoveNumber(i,0);
  579.         if (movenumber == 0)
  580.           movenumber = game.getMoveNumber(i,1);
  581.         String lineitem =  " " + movenumber +". "+game.getMoveText(i,0)+"  "+game.getMoveText(i,1);
  582.       }
  583.       System.out.println("Added " + count + " lines");
  584.       subroutine= "fillMoveList-end";
  585.     }
  586.     catch (Exception e) {
  587.       System.out.println("fillmovelist " + e);
  588.       e.printStackTrace();
  589.     }
  590.   }
  591.  
  592.   void logonEnable(boolean state) {
  593.     loggedon = state;
  594.     chatText.setEnabled(state);
  595.     if (loggedon)  {
  596.       sbLogon.setEnabled(true); // Once on, only toggle the meaning
  597.       sbLogon.setLabel(CVS.LOGOFF);
  598.     }
  599.     else  {
  600.       if (listuse == ChessViewer.MOVELIST)
  601.         gameOver();
  602.       else
  603.         if (listuse == ChessViewer.PLAYERLIST ||
  604.             listuse == ChessViewer.LIBRARYLIST ) {
  605.           setListButtons (ChessViewer.LIBRARYLIST);
  606.           getLibraryList();
  607.         }
  608.       moveToken = true;
  609.       sbLogon.setLabel(CVS.LOGON);
  610.     }
  611.   }
  612.  
  613.   public void setListListener(PlayerListListener ll){
  614.      ourServer.listListener = ll;
  615.   }
  616.  
  617.   public void removeListListener(){
  618.     ourServer.listListener = null;
  619.   }
  620.  
  621.   public void startsocket() {
  622.     int port = 100;
  623.     System.out.println("startsocket");
  624.     try {
  625.       statusLine.setText("Connecting...");
  626.       Socket kkSocket =  new Socket(host,port);
  627.       PrintWriter os = new PrintWriter(kkSocket.getOutputStream());
  628.       //DataInputStream is = new DataInputStream(kkSocket.getInputStream());
  629.       BufferedReader is = new BufferedReader(new InputStreamReader(kkSocket.getInputStream()));
  630.       String fromServer;
  631.       os.println("Hello");
  632.       os.flush();
  633.       if ((fromServer = is.readLine()) != null) {
  634.         System.out.println("CV" +String.valueOf(port) + "Received: " + fromServer);
  635.         port = new Integer(fromServer).intValue();
  636.       }
  637.       os.close();
  638.       is.close();
  639.       kkSocket.close();
  640.       //kkSocket = new Socket("ghamer", port);
  641.       kkSocket = new Socket(host,port);
  642.       ourServer = new ClientListener(this,kkSocket);
  643.       ourServer.start();
  644.       sender = new  ClientSender(kkSocket);
  645.       sender.start();
  646.       pDialog = new LogonDialog(this);
  647.       pDialog.show();
  648.     }
  649.     catch (UnknownHostException e) {
  650.       statusLine.setText(CVS.CONNECTION_ERROR + e);
  651.       System.err.println(CVS.UNKNOWN_HOST + e);
  652.     }
  653.     catch (Exception e) {
  654.       statusLine.setText(CVS.CONNECTION_ERROR + e);
  655.       System.err.println("startsocket " + e);
  656.       e.printStackTrace();
  657.     }
  658.   }
  659.  
  660.   public void setModal(boolean value)  {
  661.     doNothing = value;
  662.     //System.out.println("SM Chessboard enable = " + !value);
  663.     theboard.setEnabled(!doNothing);
  664.   }
  665.  
  666.   public void setGameButtons()  {
  667.     int i;
  668.     if (listuse == MOVELIST) {
  669.       navBtn[0].setLabel(CVS.OFFER_ABORT);
  670.       navBtn[1].setLabel(CVS.OFFER_DRAW);
  671.       navBtn[2].setLabel(CVS.RESIGN);
  672.       navBtn[3].setLabel(CVS.SUSPEND);
  673.       navBtn[0].setEnabled(true);
  674.       navBtn[1].setEnabled(true);
  675.       navBtn[2].setEnabled(true);
  676.       navBtn[3].setEnabled(true);
  677.       for (i=4;i<8;i++)
  678.         navBtn[i].setVisible(false);
  679.  
  680.     }
  681.     //System.out.println("movecount="+movecount+ " count=" + count);
  682.     if (opponentName != null && listuse != KIBITZ)
  683.       return;
  684.  
  685.     navBtn[0].setEnabled(movecount>0);
  686.     moveSubscript[1] = game.getPreviousSubscript(movecount,color);
  687.     navBtn[1].setEnabled(movecount != 0);
  688.     navBtn[2].setEnabled(movecount<count);
  689.     String message = game.getComment(movecount,color);
  690.     int nxtclr = 0;
  691.     if (color==0)
  692.       nxtclr = 1;
  693.     int initcolor = nxtclr;
  694.  
  695.     int j;
  696.   loops:
  697.     for (i=movecount+color;i<count;i++) { //format the move comment
  698.       for (j=initcolor;j<2;j++) {
  699.         if (game.getMoveNumber(i,j) != 0)
  700.           break loops;
  701.         message = message +  game.getComment(i,j);
  702.       }
  703.       initcolor = 0;
  704.     }
  705.     //infoText.setText(message);  turn on someday when dont need diagnostics
  706.     j = 3;
  707.     boolean moremoves = false;
  708.     for (i=movecount+color;i<=count;i++){ //map the navigation buttons
  709.       if (game.getPreviousSubscript(i,nxtclr) == movecount ||
  710.          (j==3 && game.getMoveNumber(i,nxtclr) != 0)){
  711.           navBtn[j].setLabel(game.getMoveText(i,nxtclr));
  712.         navBtn[j].setVisible(true);
  713.         moremoves = true;
  714.         moveSubscript[j] = i;
  715.         j++;
  716.         if (j > 7)
  717.           break;
  718.       }
  719.     }
  720.     if (moremoves)
  721.       navBtn[3].setEnabled(true); //enable the play button
  722.     else {
  723.       navBtn[3].setLabel(">");
  724.       navBtn[3].setEnabled(false);
  725.       j++;  //never want to hide the play button
  726.     }
  727.     for (i=j;i<8;i++)  //hide the unmapped navigation buttons
  728.       navBtn[i].setVisible(false);
  729.   }
  730.  
  731.   public void tokenMove(String tokenmsg){
  732.     int index = tokenmsg.indexOf(' ');
  733.     int prevsub = Integer.parseInt(tokenmsg.substring(0,index));
  734.     MoveTuple tuple = new MoveTuple(tokenmsg.substring(index+1));
  735.     if (tuple.pieceColor == 0)
  736.       color = 1;
  737.     else
  738.       color = 0;
  739.     movecount = prevsub;
  740.     //    theboard.setPosition(game.getPieceValues(prevsub,color),
  741.     //                   game.getPieceColors(prevsub,color));
  742.     game.setMove(prevsub,color);
  743.     game.moveInfo(tuple,yourColor,false,false);
  744.     updateMoveList();
  745.     System.out.println("tokenMove calling displayPos");
  746.     // displayPos();
  747.   }
  748.  
  749.   void moveInfo()  {
  750.     //System.out.println("moveInfo opponentName=" + opponentName);
  751.     if (listuse == PLAYERLIST || listuse == LIBRARYLIST) {
  752.       listuse = KIBITZ;
  753.       listPanel.setSelectedTab(MOVELIST_LABEL);
  754.     }
  755.     MoveTuple tuple = theboard.getTuple();
  756.     if (game.moveInfo(tuple,yourColor,opponentName != null,!moveToken  &&  hasListeners)) {
  757.       if (!moveToken  &&  hasListeners) {
  758.           sendMsg("TokenMove",String.valueOf(movecount) + " " + tuple.toString());
  759.           return;
  760.       }
  761.       else {
  762.         updateMoveList();
  763.       }
  764.       displayPos();
  765.     }
  766.     else {
  767.       //System.out.println("ChessViewer.moveInfo  reason " + game.getReason());
  768.       theboard.setPosition(game.getPieceValues(movecount,color),
  769.                          game.getPieceColors(movecount,color));
  770.       statusLine.setText(game.getReason());
  771.     }
  772.     //displayPos();
  773.     int gameResult = game.isGameOver();
  774.     if (gameResult > 0 && opponentName != null) {
  775.       String msgType = "Resigned";
  776.       String rslt = "0-1 Checkmate";
  777.       if (gameResult == 1) {
  778.         if (color == ChessRules.Black)
  779.           rslt = "1-0 Checkmate";
  780.       }
  781.       else {
  782.         rslt = "1/2-1/2 Stalemate";
  783.         msgType =  "AcceptDraw";
  784.       }
  785.       sendMsg(msgType,rslt);
  786.       statusLine.setText(rslt); //written when resign msg comes back from server
  787.       gameOver(rslt);
  788.     }
  789.   }
  790.  
  791.   // Update movecount & color  to point to the new move
  792.   // If playing someone, punch the clock and send them the move
  793.   void updateMoveList() {
  794.     movecount = game.getLastMoveNumber();
  795.     color = game.getWhoMovedLast();
  796.     //System.out.println("lastmoveSub = " + movecount + ",color = " + color);
  797.     String moveString;
  798.     String variation = " ";
  799.     gridControl1.setSubfocus(movecount-1,color + 1);
  800.  
  801.     if (count == movecount)  {
  802.       moveString = Integer.toString(game.getMoveNumber(movecount,color))+
  803.                       ". "+game.getMoveText(movecount,0)+"  "+game.getMoveText(movecount,1);
  804.     }
  805.     else {
  806.       int prevsub = game.getPreviousSubscript(movecount,color);
  807.       if (count != prevsub)
  808.         variation = " @" + prevsub + ' ';
  809.       moveString = Integer.toString(game.getMoveNumber(movecount,color))+". "+
  810.       game.getMoveText(movecount,0)+"  "+game.getMoveText(movecount,1);
  811.       count++; //count = newcount;
  812.     }
  813.  
  814.     if (clock != null) {
  815.       synchronized (clock) {
  816.         clock.notify();   //punch the clock
  817.       }
  818.     }
  819.     playerTime[color] = playerTime[color] + lMoveTime ;
  820.     if (/*opponentName != null &&*/ hasListeners && sender != null) {
  821.       //System.out.println("Send kibitzers/opponents the move");
  822.       sendMsg("Move",String.valueOf(playerTime[color]) + variation + moveString);
  823.     }
  824.   }
  825.  
  826.   void sendMsg(String msgid,String[] parm) {
  827.     String msg = PersistString.concat(parm);
  828.     sendMsg(msgid,msg);
  829.   }
  830.  
  831.   void sendMsg(String msgid,String msg)  {
  832.     try {
  833.       System.out.println("Sending " + msgid + " " + msg );
  834.       ServerMessage smsg = new ServerMessage(0,msgid,msg);
  835.       if (sender == null )
  836.         System.out.println("sendMsg - sender is null??");
  837.       else {
  838.         synchronized (sender) {
  839.           sender.msgque.addElement(smsg);
  840.           sender.notify();
  841.         }
  842.         if (msgid.equals("Bye") || msgid.equals("Dead"))  {
  843.           System.out.println("sendMsg setting sender to null");
  844.           sender = null;
  845.         }
  846.       }
  847.     }
  848.     catch (Exception e ) {System.out.println("sendMsg " + e); }
  849.   }
  850.  
  851.   public void logonButton() {
  852.     if (loggedon == true) {
  853.       statusLine.setText(CVS.LOGGED_OFF);
  854.       logonEnable(false);
  855.       libraryList.removeAll();
  856.       libraryListContents.removeAllElements();
  857.       sendMsg("Bye","");
  858.     }
  859.     else {
  860.       if (pDialog == null)
  861.         startsocket();
  862.       else
  863.         pDialog.okButton.requestFocus();
  864.     }
  865.   }
  866.  
  867.   void chooseGame() {
  868.     String [] gameName = libraryList.getSelectedItems();
  869.     String msg = null;
  870.     if (gameName == null) {
  871.        ImportDlg dlg = new ImportDlg(this,getMoves());
  872.        dlg.show();
  873.     }
  874.     else {
  875.     for (int i=0;i<gameName.length;i++) {
  876.        if (libraryHash.containsKey(gameName[i]));
  877.        else
  878.          if (msg == null)
  879.            msg = gameName[i] + "?";
  880.          else
  881.            msg  = msg + gameName[i] + "?";
  882.     }
  883.     if (msg != null)
  884.       sendMsg("GetLibraryGame",msg);
  885.     if (gameName.length == 1)
  886.       showLibraryGame = true;
  887.     else
  888.       showLibraryGame = false;
  889.     if (gameName.length == 1 && msg == null)
  890.        getGame(gameName[0]);
  891.     }
  892.   }
  893.  
  894.   void chooseButton(){
  895.     hasListeners = false;
  896.     if (listuse == PLAYERLIST) {
  897.       String choice = playerList.getSelectedItem();
  898.       int index = playerList.getSelectedIndex();
  899.       if (index == -1) {
  900.         ImportDlg dlg = new ImportDlg(this,getMoves());
  901.         dlg.show();
  902.       }
  903.       else {
  904.         String type = "?";
  905.         type = (String) listContents.elementAt(index);
  906.         if (type.equals("G"))
  907.           sendMsg("Resume",String.valueOf(index));
  908.         else
  909.           if (type.equals("P"))
  910.             challenge(choice);
  911.           else
  912.             watch(choice);
  913.       }
  914.     }
  915.     else {
  916.       if (listuse == LIBRARYLIST)
  917.         chooseGame();
  918.       else
  919.         if (listuse == KIBITZ) {
  920.           ImportDlg dlg = new ImportDlg(this,getMoves());
  921.           dlg.show();
  922.         }
  923.         else {
  924.           sbChoose.setEnabled(false);
  925.           System.out.println("Choose button was enabled when it shouldn't be");
  926.         }
  927.     }
  928.   }
  929.  
  930.   String getMoves() {
  931.      //StringBuffer moves = new StringBuffer("[White \"" + game.getPlayerW() + "\"]" + "[Black \"" + game.getPlayerB() + "\"]\n");
  932.      StringBuffer moves = new StringBuffer(game.getTags());
  933.      //int max = moveList.getItemCount();
  934.      int max = game.getRowCount();
  935.      int count = 0;
  936.      String movePair;
  937.      for (int i= 1;i <= max; i++) {
  938.        //movePair = moveList.getItem(i);
  939.        movePair = " " + game.getMoveNumber(i,0) + ". " + game.getMoveText(i,0) + " " + game.getMoveText(i,1);
  940.        count = count + movePair.length() + 1;
  941.        if (count > 64)  {
  942.          moves.append("\n" + movePair);
  943.          count = movePair.length() ;
  944.        }
  945.        else
  946.          moves.append(movePair);
  947.      }
  948.      return moves.toString();
  949.   }
  950.  
  951.   void getInfo(String linedata){
  952.     sbChoose.setEnabled(true);
  953.     String user = linedata.substring(0,linedata.lastIndexOf(' '));
  954.     if (user.equals(myName))
  955.       sbChoose.setLabel(CVS.UPDATE);
  956.     else {
  957.       sendMsg("Info",user);
  958.       sbChoose.setLabel(CVS.CHALLENGE);
  959.     }
  960.   }
  961.  
  962.   void challenge(String linedata) {
  963.     //strip off rating
  964.     challenger = linedata.substring(0,linedata.lastIndexOf(' '));
  965.     if (challenger.equals(myName))
  966.       sendMsg("Information",challenger);
  967.     else {
  968.       try {
  969.         String[] parm = new String[3];
  970.         parm[0] = gameTime.getText();
  971.         System.out.println("Challenge " + challenger + " " +  parm[0]) ;
  972.         gameTimeValue = Integer.parseInt(parm[0]);
  973.         parm[1] =  moveTime.getText();
  974.         lMoveTime = Long.parseLong(parm[1]) * 1000;
  975.         parm[2] = challenger;
  976.         //String l =  gt +" " + mt +" " + challenger;
  977.         playerTime[0] = gameTimeValue * 60000;
  978.         playerTime[1] = playerTime[0];
  979.         sendMsg("Challenge",PersistString.concat(parm));
  980.  
  981.       }
  982.       catch (NumberFormatException e){
  983.         statusLine.setText(CVS.TIME_CONTROL_FIELDS);
  984.       }
  985.     }
  986.   }
  987.  
  988.   void importGame(String gamePGN) {
  989.     System.out.println("imported game = " + gamePGN);
  990.     if (gamePGN == null || gamePGN.length() < 20)
  991.        statusLine.setText(CVS.PASTE_AND_THEN );
  992.     else {
  993.       importCount++;
  994.       String name = CVS.IMPORTEDGAME + importCount;
  995.       libraryHash.put(name,gamePGN);
  996.       getGame(name);
  997.     }
  998.   }
  999.  
  1000.   void boardOptionsDialog() {
  1001.     try {
  1002.       URL[] imageName = new URL[pieceGif.size()];
  1003.       URL currentImage = theboard.getImageURL();
  1004.       //System.out.println("image array size = " + imageName.length);
  1005.       for (int i= 0;i< pieceGif.size();i++) {
  1006.         imageName[i]  = (URL)pieceGif.elementAt(i);
  1007.         //System.out.println("image " + i + "=" + imageName[i].toString());
  1008.         if (currentImage.sameFile(imageName[i]) && i > 0){
  1009.           imageName[i] = imageName[0];
  1010.           imageName[0] = currentImage;
  1011.         }
  1012.       }
  1013.       //System.out.println("ready to call BoardOptions xtor");
  1014.       BoardOptions dlg;
  1015.       dlg = new BoardOptions(this,f,imageName,theboard);
  1016.         
  1017.       System.out.println("back from xtor");
  1018.       Point y = listPanel.getLocation();
  1019.       //Point x = ep.location();
  1020.       dlg.setLocation(0,y.y);
  1021.       dlg.pack();
  1022.       dlg.show();
  1023.       System.out.println("back from show");
  1024.     }
  1025.     catch (Exception e) {System.out.println("BoardOptionsDialog " + e); e.printStackTrace(); }
  1026.   }
  1027.  
  1028.   public void otherAction(ActionEvent evt) {
  1029.     if (doNothing) //fake modal dialog on the loose
  1030.        return ;
  1031.     if (evt.getSource().equals(optionsButton))
  1032.        boardOptionsDialog();
  1033.     else if (evt.getSource().equals(sbLogon))
  1034.       logonButton();
  1035.     else if (evt.getSource().equals(chatText))  {
  1036.       sendMsg("Chat",myName + ":" + chatText.getText()) ;
  1037.       chatText.setText("");
  1038.     }
  1039.     else if (evt.getSource().equals(sbChoose))
  1040.       chooseButton();
  1041.   }
  1042.  
  1043.   void boardButtonAction(ActionEvent evt) {
  1044.     if (doNothing) //fake modal dialog on the loose
  1045.        return ;
  1046.     if (listuse == MOVELIST)
  1047.       gameButtons(evt);
  1048.     else
  1049.       navigationButtons(evt);
  1050.   }
  1051.  
  1052.   void getLibraryList() {
  1053.     listuse = LIBRARYLIST;
  1054.     sbChoose.setLabel(CVS.COPY_PASTE);
  1055.     if (loggedon) {
  1056.       if (libraryList.getItemCount()==0)
  1057.         sendMsg("LibraryList","") ;
  1058.       else
  1059.         setListButtons(ChessViewer.LIBRARYLIST);
  1060.     }
  1061.     else  {
  1062.       if (libraryList.getItemCount()==0) {
  1063.         libraryListContents.removeAllElements();
  1064.         for (Enumeration e = libraryHash.keys();e.hasMoreElements();) {
  1065.           String gameName = (String) e.nextElement() ;
  1066.           libraryList.addItem(gameName);
  1067.           libraryListContents.addElement("L");
  1068.         }
  1069.       }
  1070.       setListButtons(ChessViewer.LIBRARYLIST);
  1071.     }
  1072.   }
  1073.  
  1074.   void gameButtons(ActionEvent evt) {
  1075.     if (evt.getSource().equals(navBtn[0])) {
  1076.       navBtn[0].setEnabled(false);
  1077.       sendMsg("OfferAbort","") ;
  1078.       statusLine.setText(CVS.ABORT_OFFERED_TO + opponentName);
  1079.     }
  1080.     else
  1081.     if (evt.getSource().equals(navBtn[1])) {
  1082.       navBtn[1].setEnabled(false);
  1083.       if (game.claimDraw()) {
  1084.         sendMsg("AcceptDraw"," 1/2-1/2 " + game.getReason() )   ;
  1085.         gameOver("1/2-1/2");
  1086.       }
  1087.       else {
  1088.         sendMsg("OfferDraw","") ;
  1089.         statusLine.setText(CVS.DRAW_OFFERED_TO +opponentName);
  1090.       }
  1091.     }
  1092.     else
  1093.     if (evt.getSource().equals(navBtn[2])) {
  1094.       statusLine.setText(CVS.GAME_OVER);
  1095.       String result = "1-0 ";
  1096.       if (yourColor == ChessRules.White)
  1097.         result = "0-1 ";
  1098.       game.setComment(movecount,color,result);
  1099.       displayPos();
  1100.       gameOver(result);
  1101.       sendMsg("Resigned",result + myName + CVS.RESIGNED) ;
  1102.     }
  1103.     else
  1104.     if (evt.getSource().equals(navBtn[3])) {
  1105.       statusLine.setText(CVS.GAME_SUSPENDED);
  1106.       gameOver();
  1107.       hasListeners = false;
  1108.       sendMsg("Suspend","") ;
  1109.     }
  1110.   }
  1111.  
  1112.   public void navigationButtons(ActionEvent evt) {
  1113.     for (int i=0; i< 8;i++) {
  1114.       if (evt.getSource().equals(navBtn[i])) {
  1115.         movecount = moveSubscript[i] ;
  1116.         if (color==0)
  1117.           color = 1;
  1118.         else
  1119.           if (movecount != 0)  //initial position is Move(0,1)
  1120.             color = 0;
  1121.           break;
  1122.       }
  1123.     }
  1124.     gridControl1.setSubfocus(movecount-1,color + 1);
  1125.     //displayPos();
  1126.     if (listuse == PLAYERLIST || listuse == LIBRARYLIST) {
  1127.       listuse = KIBITZ;
  1128.       listPanel.setSelectedTab(MOVELIST_LABEL);
  1129.     }
  1130.   }
  1131.  
  1132.   public void setNames() {
  1133.     //System.out.println("PlayerB="+game.getPlayerB()+" PlayerW="+game.getPlayerW()+" myName="+myName);
  1134.     if (game.getPlayerB().equals(myName)) {
  1135.       if (blackOnTop)
  1136.         switchSides();
  1137.       else {
  1138.         bottomName.setText(game.getPlayerB());
  1139.         topName.setText(game.getPlayerW());
  1140.         bottomTime.setText(formatTime(playerTime[1]));
  1141.         topTime.setText(formatTime(playerTime[0]));
  1142.       }
  1143.     }
  1144.     else {
  1145.       if (!blackOnTop)
  1146.         switchSides();
  1147.       else {
  1148.         bottomName.setText(game.getPlayerW());
  1149.         topName.setText(game.getPlayerB());
  1150.         bottomTime.setText(formatTime(playerTime[0]));
  1151.         topTime.setText(formatTime(playerTime[1]));
  1152.       }
  1153.     }
  1154.   }
  1155.  
  1156.   void newGame(String white,String black) {
  1157.     game.init();
  1158.     game.setPlayerW(white);
  1159.     game.setPlayerB(black);
  1160.     setNames();
  1161.     movecount = 0;
  1162.     color = ChessRules.Black;
  1163.     count =  0;
  1164.     setListButtons(MOVELIST);
  1165.     moveToken = true;
  1166.     if (opponentName != null)    {
  1167.       hasListeners = true;
  1168.       gameTime.setEnabled(false);
  1169.       moveTime.setEnabled(false);
  1170.     }
  1171.     else                                       {
  1172.       //System.out.println("NG chessboard enabled");
  1173.       theboard.setEnabled(true);
  1174.     }
  1175.     displayPos();
  1176.     gameTime.setText(String.valueOf(gameTimeValue));
  1177.     moveTime.setText(String.valueOf(lMoveTime/1000));
  1178.  
  1179.     try {
  1180.     if (clock != null)
  1181.       clock.stop();
  1182.     clock = new Thread(this);
  1183.     clock.start();
  1184.     }
  1185.     catch (Exception e) {
  1186.       e.printStackTrace();
  1187.     }
  1188.   }
  1189.  
  1190.   void displayPos()  {
  1191.     if (count > 0 && movecount == count && game.getMoveNumber(movecount,color) == 0)
  1192.       color = 0; //don't step off the end
  1193.     game.setMove(movecount,color);
  1194.     //System.out.println("CV displayPos "+ movecount + "," + color);
  1195.     subroutine = "setPosition";
  1196.     theboard.setPosition(game.getPieceValues(movecount,color),
  1197.                          game.getPieceColors(movecount,color));
  1198.     subroutine = "DisplayPosition";
  1199.     if (listuse == MOVELIST){
  1200.       if (yourColor == color)
  1201.         statusLine.setText(CVS.WAITING_ON_YOUR);
  1202.       else
  1203.         statusLine.setText(CVS.YOUR_MOVE);
  1204.     }
  1205.     else
  1206.       if (color == ChessRules.Black)
  1207.         statusLine.setText(CVS.WHITE_TO_MOVE);
  1208.       else
  1209.         if (color == ChessRules.White)
  1210.           statusLine.setText(CVS.BLACK_TO_MOVE);
  1211.         else
  1212.           statusLine.setText("Color="+String.valueOf(color)+"?");
  1213.     setGameButtons();
  1214.   }
  1215.  
  1216.   //the browser is no longer displaying the applet. Let's be nice
  1217.   //and end our chessclock thread if it is running
  1218.   public void stop() {
  1219.     System.out.println("ChessViewer.stop called");
  1220.     if (clock != null) {
  1221.       if (yourColor == 0)
  1222.          opponentsTimeWhenStopped = playerTime[1];
  1223.       else
  1224.          opponentsTimeWhenStopped = playerTime[0];
  1225.       timerWasStopped = true;
  1226.       timeStopped =  System.currentTimeMillis();
  1227.       clock.stop();
  1228.     }
  1229.     clock = null;
  1230.   }
  1231.  
  1232.   //The browser is displaying the applet again. re-start the
  1233.   //chessclock if it was running when the applet was last stopped.
  1234.   public void start() {
  1235.     System.out.println("ChessViewer.start called");
  1236.  
  1237.     long opponentsTimeUsed;
  1238.     long timeAway;
  1239.     if (timerWasStopped) {
  1240.       try {
  1241.         int oppColor = 0;
  1242.         if (yourColor == 0)
  1243.           oppColor = 1;
  1244.         opponentsTimeUsed = opponentsTimeWhenStopped - playerTime[oppColor];
  1245.         timeAway = System.currentTimeMillis() - timeStopped;
  1246.         if (opponentsTimeUsed == 0) {
  1247.           if (color == yourColor)
  1248.             playerTime[oppColor] = playerTime[oppColor] - timeAway;
  1249.           else
  1250.             playerTime[yourColor] = playerTime[yourColor] - timeAway;
  1251.         }
  1252.         else
  1253.           playerTime[yourColor] =  playerTime[yourColor] - timeAway - lMoveTime + opponentsTimeUsed;
  1254.         clock = new Thread(this);
  1255.         clock.start();
  1256.       }
  1257.       catch (Exception e) {
  1258.         e.printStackTrace();
  1259.       }
  1260.     }
  1261.     timerWasStopped = false;
  1262.   }
  1263.  
  1264.   //run gets called whenever a thread gets started
  1265.   public void run() {
  1266.     try{
  1267.       if (threadFlag)  {
  1268.         threadFlag = false;
  1269.         theboard.setImageURL((URL) pieceGif.elementAt(0));
  1270.         validate();
  1271.         repaint();
  1272.         return;
  1273.       }
  1274.       //System.out.println("ChessViewer.run  clock started");
  1275.       clock.setPriority(Thread.MIN_PRIORITY);
  1276.       long time = System.currentTimeMillis();
  1277.       long nexttime;
  1278.       int OnMove = ChessRules.White;
  1279.       if (color == ChessRules.White)
  1280.         OnMove = ChessRules.Black;
  1281.       boolean enableSuspend = true;
  1282.       if (OnMove == yourColor)
  1283.         enableSuspend = false;
  1284.       navBtn[3].setEnabled(enableSuspend);
  1285.       synchronized (clock) {
  1286.         while (true) {
  1287.           try  {
  1288.             clock.wait(1000);
  1289.           }
  1290.           catch (InterruptedException e) {}
  1291.           if (!(OnMove == yourColor ^ enableSuspend))   {
  1292.             enableSuspend = !enableSuspend;
  1293.             navBtn[3].setEnabled(enableSuspend);
  1294.           }
  1295.           nexttime =  System.currentTimeMillis();
  1296.           playerTime[OnMove] = playerTime[OnMove] + time - nexttime ;
  1297.           time = nexttime;
  1298.           if (playerTime[OnMove] < 0) {
  1299.             String rslt = CVS.BLACK_LOST_ON_TIME;
  1300.             if (OnMove == ChessRules.White)
  1301.               rslt = CVS.WHITE_LOST_ON_TIME;
  1302.             if (OnMove == yourColor) {
  1303.               sendMsg("Resigned",rslt);
  1304.               //statusLine.setText(rslt);  status given when msg comes back from server
  1305.               gameOver(rslt);
  1306.             }
  1307.           }
  1308.           if (OnMove == 1 && blackOnTop || OnMove == 0 && !blackOnTop)
  1309.             topTime.setText(formatTime(playerTime[OnMove]));
  1310.           else
  1311.             bottomTime.setText(formatTime(playerTime[OnMove]));
  1312.           if (color == ChessRules.White)
  1313.             OnMove = ChessRules.Black;
  1314.           else
  1315.             OnMove = ChessRules.White;
  1316.         }
  1317.       }
  1318.     }
  1319.     catch (MalformedURLException e) {
  1320.       System.out.println("Malformed URL " + getDocumentBase().toString() + (URL) pieceGif.elementAt(0));
  1321.     }
  1322.     catch (ThreadDeath e) {
  1323.       System.out.println("ChessViewer.run died");
  1324.       throw e;
  1325.     }
  1326.   }
  1327.  
  1328.   String formatTime(long milliseconds) {
  1329.     String time;
  1330.     if (milliseconds < 0 )
  1331.       milliseconds = 0;
  1332.     long seconds = milliseconds / 1000;
  1333.     long minutes =  seconds / 60;
  1334.     long hours = minutes / 60;
  1335.     seconds = seconds - (60  * minutes);
  1336.     minutes = minutes - (60 * hours);
  1337.     String sec;
  1338.     String min;
  1339.     if (seconds < 10)
  1340.       sec = "0" + seconds;
  1341.     else
  1342.       sec = String.valueOf(seconds);
  1343.     if (minutes < 10)
  1344.       min = "0" + minutes;
  1345.     else
  1346.       min = String.valueOf(minutes);
  1347.     //if (hours != 0 || minutes > 9)
  1348.       time = String.valueOf(hours) + ":" + min;
  1349.     //else
  1350.     //  time = min + ":" + sec;
  1351.     if (hours != 0 )
  1352.       time = String.valueOf(hours) + ":" + min + ":" + sec;
  1353.     else
  1354.       time = min + ":" + sec;
  1355.     return time;
  1356.   }
  1357.  
  1358.   void fillList(String msg) {
  1359.     //System.out.println("CV processing List");
  1360.     int index = 0;
  1361.     int oldindex = 0;
  1362.     int matchchar = '?';
  1363.     String newname;
  1364.  
  1365.     List c = playerList;
  1366.     Vector v = listContents;
  1367.     if (listuse == LIBRARYLIST) {
  1368.       c = libraryList;
  1369.       v = libraryListContents;
  1370.     }
  1371.     c.removeAll();
  1372.     v.removeAllElements();
  1373.     if (msg != null) {
  1374.       while (index != -1)  {
  1375.         index = msg.indexOf(matchchar,oldindex);
  1376.         if (index != -1) {
  1377.           v.addElement(msg.substring(oldindex,oldindex+1));
  1378.           newname = msg.substring(oldindex+1,index);
  1379.           oldindex = index +1;
  1380.       c.addItem(newname);
  1381.         }
  1382.       }
  1383.     }
  1384.     else
  1385.       c.setVisible(true);
  1386.   }
  1387.  
  1388.   //always add to the end of the array (count is the size of the array)
  1389.   //don't assume the new move comes after the last move
  1390.   //in kibitz mode the board position can be altered to somewhere in the middle
  1391.   void addMove(String movemsg) {
  1392.     //System.out.println("ChessViewer.addMove " + movemsg);
  1393.     int timeIndex = movemsg.indexOf(' ');
  1394.     String time = movemsg.substring(0,timeIndex);
  1395.     long timeremaining = 0;
  1396.     try {
  1397.       timeremaining = Long.parseLong(time);
  1398.     }
  1399.     catch (NumberFormatException e) {
  1400.       System.out.println (time + " is not a number");
  1401.     }
  1402.     int varindex = movemsg.indexOf('@');
  1403.     if (opponentName == null)
  1404.       movecount = count;
  1405.     int prevsub = movecount;
  1406.     if (varindex > timeIndex){
  1407.       timeIndex = movemsg.indexOf(' ',varindex+1);
  1408.       try {
  1409.         prevsub = Integer.parseInt(movemsg.substring(varindex+1,timeIndex));
  1410.       }
  1411.       catch (NumberFormatException e) {
  1412.         System.out.println("could not read variation subscript in " + movemsg) ;
  1413.       }
  1414.     }
  1415.     String movetxt = movemsg.substring(timeIndex + 1);
  1416.     String sMovenum;
  1417.     int spaceindex = movetxt.indexOf('.');
  1418.     sMovenum = movetxt.substring(0,spaceindex);
  1419.     int movenum = Integer.parseInt(sMovenum);
  1420.     spaceindex++;
  1421.     int index = movetxt.indexOf('_');
  1422.     int temp = 0;
  1423.     if (index > 0)
  1424.       temp = movetxt.indexOf(' ',index);
  1425.     //System.out.println("found _ at " + index);
  1426.     //int clr = Chessboard.WhitePiece;
  1427.     int clrsub = ChessRules.White;
  1428.     String moveNotation ;
  1429.     if (index > 0) {      //new line in listbox needed
  1430.       if (prevsub == movecount)
  1431.         prevsub++;
  1432.       movecount++;
  1433.     }
  1434.     if (index > 0 && index > temp) {     //whites move
  1435.       playerTime[0] = timeremaining;
  1436.       if (blackOnTop)
  1437.         bottomTime.setText(formatTime(timeremaining));
  1438.       else
  1439.         topTime.setText(formatTime(timeremaining));
  1440.       //System.out.println("White move  " + movetxt+ index);
  1441.       clrsub = ChessRules.White;
  1442.       moveNotation = movetxt.substring(spaceindex+1,movetxt.lastIndexOf(' '));
  1443.     }
  1444.     else {
  1445.       playerTime[1] = timeremaining;
  1446.       if (blackOnTop)
  1447.         topTime.setText(formatTime(timeremaining));
  1448.       else
  1449.         bottomTime.setText(formatTime(timeremaining));
  1450.       clrsub = ChessRules.Black;
  1451.       moveNotation = movetxt.substring(movetxt.lastIndexOf(' '));
  1452.     }
  1453.     //System.out.println("move is " + Move[movecount][clrsub].Movetxt +
  1454.     //               "; movenum is " + String.valueOf(movenum) +
  1455.     //               "; color=" + String.valueOf(clrsub));
  1456.     game.addMove(movecount,clrsub,moveNotation,movenum,prevsub);
  1457.     gridControl1.setSubfocus(movecount-1,clrsub + 1);
  1458.     color = clrsub;
  1459.     if (clock != null)
  1460.       synchronized (clock) {
  1461.         clock.notify();   //time to punch the chess clock
  1462.       }
  1463.     count = movecount;
  1464.     //displayPos();
  1465.   }
  1466.  
  1467.   void switchSides() {
  1468.     blackOnTop = theboard.switchOrientation();
  1469.     if (blackOnTop) {
  1470.       bottomName.setText(game.getPlayerW());
  1471.       topName.setText(game.getPlayerB());
  1472.       topTime.setText(formatTime(playerTime[1]));
  1473.       bottomTime.setText(formatTime(playerTime[0]));
  1474.     }
  1475.     else {
  1476.       bottomName.setText(game.getPlayerB());
  1477.       topName.setText(game.getPlayerW());
  1478.       topTime.setText(formatTime(playerTime[0]));
  1479.       bottomTime.setText(formatTime(playerTime[1]));
  1480.     }
  1481.   }
  1482.  
  1483.   public void setListButtons(int use)  {
  1484.     listuse = use;
  1485.     switch (use) {
  1486.       case MOVELIST:
  1487.           sbChoose.setEnabled(false);
  1488.         listPanel.setSelectedTab(MOVELIST_LABEL);
  1489.         break;
  1490.       case PLAYERLIST:
  1491.           sbChoose.setEnabled(true);
  1492.         sbChoose.setLabel(CVS.COPY_PASTE);
  1493.         break;
  1494.       case LIBRARYLIST:
  1495.           sbChoose.setEnabled(true);
  1496.         sbChoose.setLabel(CVS.VIEW);
  1497.         System.out.println("show library list");
  1498.         break;
  1499.       case KIBITZ:
  1500.         sbChoose.setEnabled(true);
  1501.         sbChoose.setLabel(CVS.COPY_PASTE);
  1502.         navBtn[0].setLabel(CVS.BEGINNING_OF_GAME);
  1503.         navBtn[1].setLabel(CVS.BACK_ONE_MOVE);
  1504.         navBtn[3].setLabel(CVS.FORWARD_ONE_MOVE);
  1505.         navBtn[2].setLabel(CVS.END_OF_GAME);
  1506.         setGameButtons();
  1507.      }
  1508.   }
  1509.  
  1510.   void gameOver(String result) {
  1511.     game.setResult(result);
  1512.     System.out.println("setResult " + result);
  1513.     gameOver();
  1514.   }
  1515.  
  1516.   void gameOver() {
  1517.     setListButtons(ChessViewer.KIBITZ);
  1518.     gameTime.setEnabled(true);
  1519.     moveTime.setEnabled(true);
  1520.     opponentName = null;
  1521.     if (clock != null)
  1522.       clock.stop();
  1523.     timerWasStopped = false;
  1524.     clock = null;
  1525.     if (yourColor == ChessRules.Black)
  1526.       moveToken = false;
  1527.   }
  1528.  
  1529.   public void watch(String gameName) {
  1530.     int index =  gameName.lastIndexOf(':');
  1531.     if (index > 0)
  1532.       sendMsg("Watching",gameName.substring(0,index));
  1533.     else {
  1534.       infoText.setText("Cannot find game");
  1535.       System.out.println("Cannot find game " + gameName);
  1536.     }
  1537.   }
  1538.  
  1539.   void getGame(String name) {
  1540.     String gamePGN = (String) libraryHash.get(name) ;
  1541.     try {
  1542.       game.parsePGNFile (new StringReader(gamePGN));
  1543.       infoText.setText(game.getInfo());
  1544.     }
  1545.     catch (Exception e) {}
  1546.     setNames();
  1547.     fillMoveList();
  1548.     movecount = 1;
  1549.     color = 0;
  1550.     setListButtons(ChessViewer.KIBITZ) ;
  1551.     listPanel.setSelectedTab(MOVELIST_LABEL);
  1552.     setGameButtons();
  1553.     hasListeners = false;
  1554.     displayPos();
  1555.     //System.out.println("ML chessboard enabled");
  1556.     theboard.setEnabled(true);
  1557.     moveToken = true;
  1558.   }
  1559.  
  1560.   public void playerListEvent(AWTEvent evt) {
  1561.     if (doNothing) //fake modal dialog on the loose
  1562.       return ;
  1563.     String listContent = "?";
  1564.     //System.out.println("handling event for list c");
  1565.     int selectedIndex = playerList.getSelectedIndex();
  1566.     //System.out.println("listuse = " + listuse);
  1567.     //System.out.println("listuse = PLAYERLIST");
  1568.     if (selectedIndex >= 0)
  1569.       listContent = (String)listContents.elementAt(selectedIndex);
  1570.     if (listContent.equals("P")) {
  1571.       if (evt.getID() == Event.ACTION_EVENT)
  1572.         challenge(playerList.getSelectedItem());
  1573.       else
  1574.         if (evt.getID() == Event.LIST_SELECT){
  1575.           getInfo(playerList.getSelectedItem());
  1576.         }
  1577.         else
  1578.           if (evt.getID() == Event.LIST_DESELECT)
  1579.             sbChoose.setLabel(CVS.COPY_PASTE);
  1580.         }
  1581.         else
  1582.         if (listContent.equals("A")) {
  1583.           if (evt.getID() == Event.ACTION_EVENT)
  1584.             watch(playerList.getSelectedItem());
  1585.         else {
  1586.           sbChoose.setEnabled(true);
  1587.           sbChoose.setLabel(CVS.OBSERVE);
  1588.         }
  1589.     }
  1590.     else  {
  1591.       if (listContent.equals("G")) {
  1592.         if (evt.getID() == Event.ACTION_EVENT)
  1593.           sendMsg("Resume",String.valueOf(selectedIndex));
  1594.         else  {
  1595.           sbChoose.setEnabled(true);
  1596.           sbChoose.setLabel(CVS.RESUME);
  1597.         }
  1598.       }
  1599.     }
  1600.   }
  1601.  
  1602.   void libraryListEvent(AWTEvent evt) {
  1603.     //System.out.println("Gamelist handle");
  1604.     if (doNothing) //fake modal dialog on the loose
  1605.        return ;
  1606.     if (evt.getID() == Event.ACTION_EVENT)
  1607.       chooseGame();
  1608.     else {
  1609.       int [] selItems = libraryList.getSelectedIndexes();//returns null if multiple selections are not enabled
  1610.       if (selItems == null) {
  1611.         selItems = new int[1]  ;
  1612.         selItems[0] = libraryList.getSelectedIndex();
  1613.       }
  1614.       if (selItems.length == 0)
  1615.         sbChoose.setLabel(CVS.COPY_PASTE);
  1616.       else {
  1617.         if (selItems.length == 1)
  1618.           sbChoose.setLabel(CVS.VIEW);
  1619.         else
  1620.           sbChoose.setLabel(CVS.GET);
  1621.       }
  1622.     }
  1623.   }
  1624.  
  1625.   public static Frame getFrame(Component theComponent) {
  1626.     Component currParent = theComponent;
  1627.     Frame theFrame = null;
  1628.     while (currParent != null)  {
  1629.       if (currParent instanceof Frame){
  1630.         theFrame = (Frame) currParent;
  1631.         break;
  1632.       }
  1633.       currParent = currParent.getParent();
  1634.     }
  1635.     return theFrame;
  1636.   }
  1637.  
  1638.   void gridControl1_subfocusChanged(borland.jbcl.model.MatrixSubfocusEvent e) {
  1639.     if (doNothing) {//fake modal dialog on the loose
  1640.       //System.out.println("do nothing");
  1641.       return ;
  1642.     }
  1643.     if (listuse == MOVELIST || listuse == KIBITZ) {
  1644.       MatrixLocation  test = e.getLocation();
  1645.       if (test != null) {
  1646.         if (test.column < 2)
  1647.           color = 0;
  1648.         else
  1649.           color = 1;
  1650.         if (test.row >= 0)
  1651.              movecount = test.row+1;
  1652.         //System.out.println("Display cell " + test.row +", "+ test.column);
  1653.         displayPos();
  1654.       }
  1655.     }
  1656.  
  1657.   }
  1658.  
  1659.   void listPanel_subfocusChanging(borland.jbcl.model.VectorSubfocusEvent e) throws VetoException{
  1660.     System.out.println("tabset panel subfocus changing " + e.getLocation());
  1661.     if (listuse == MOVELIST)
  1662.     if (e.getLocation() != MOVELIST && opponentName != null)
  1663.       throw new VetoException() ;
  1664.     else
  1665.       return;
  1666.     if (e.getLocation() == PLAYERLIST) {
  1667.       listuse = PLAYERLIST;
  1668.       sendMsg("List","") ;
  1669.     }
  1670.     else if (e.getLocation() == LIBRARYLIST){
  1671.         listuse = LIBRARYLIST;
  1672.         if (libraryListContents.size() == 0)
  1673.           getLibraryList();
  1674.     }
  1675.     else
  1676.       listuse = KIBITZ;
  1677.    setListButtons(listuse);
  1678.  
  1679.   }
  1680. } //end of class ChessViewer
  1681.  
  1682. class ChessboardAdapt implements ActionListener
  1683. {
  1684.   ChessViewer adaptee;
  1685.   public void actionPerformed(ActionEvent e) {adaptee.moveInfo();}
  1686.   ChessboardAdapt(ChessViewer adaptee) {this.adaptee = adaptee;}
  1687. }
  1688.  
  1689. class OtherActionAdapter implements ActionListener
  1690. {
  1691.   ChessViewer adaptee;
  1692.   public void actionPerformed(ActionEvent e) {adaptee.otherAction(e);}
  1693.   OtherActionAdapter(ChessViewer adaptee) {this.adaptee = adaptee;}
  1694. }
  1695.  
  1696. class BoardButtonActionAdapter implements ActionListener
  1697. {
  1698.   ChessViewer adaptee;
  1699.   public void actionPerformed(ActionEvent e) {adaptee.boardButtonAction(e);}
  1700.   BoardButtonActionAdapter(ChessViewer adaptee) {this.adaptee = adaptee;}
  1701. }
  1702.  
  1703. class PlayerListAdapter implements ActionListener,ItemListener
  1704. {
  1705.   ChessViewer adaptee;
  1706.   PlayerListAdapter(ChessViewer adaptee) {this.adaptee = adaptee;}
  1707.   public void actionPerformed(ActionEvent e) {adaptee.playerListEvent(e);}
  1708.   public void itemStateChanged(ItemEvent e)  {adaptee.playerListEvent(e);}
  1709. }
  1710.  
  1711. class LibraryListAdapter implements ActionListener,ItemListener
  1712. {
  1713.   ChessViewer adaptee;
  1714.   LibraryListAdapter(ChessViewer adaptee) {this.adaptee = adaptee;}
  1715.    public void actionPerformed(ActionEvent e) {adaptee.libraryListEvent(e);}
  1716.    public void itemStateChanged(ItemEvent e)  {adaptee.libraryListEvent(e);}
  1717. }
  1718.  
  1719. class ChessViewer_gridControl1_SubfocusAdapter extends MatrixSubfocusAdapter
  1720. {
  1721.   ChessViewer adaptee;
  1722.   ChessViewer_gridControl1_SubfocusAdapter(ChessViewer adaptee) {
  1723.     this.adaptee = adaptee;
  1724.   }
  1725.   public void subfocusChanged(borland.jbcl.model.MatrixSubfocusEvent e) {
  1726.     adaptee.gridControl1_subfocusChanged(e);
  1727.   }
  1728. }
  1729.  
  1730. class ChessViewer_listPanel_SubfocusAdapter extends VectorSubfocusAdapter
  1731. {
  1732.   ChessViewer adaptee;
  1733.   ChessViewer_listPanel_SubfocusAdapter(ChessViewer adaptee) {
  1734.     this.adaptee = adaptee;
  1735.   }
  1736.  
  1737.   public void subfocusChanging(borland.jbcl.model.VectorSubfocusEvent e) throws VetoException {
  1738.     adaptee.listPanel_subfocusChanging(e);
  1739.   }
  1740. }
  1741.  
  1742. //simple class that does double duty as the
  1743. //grids columnheader viewmanager and model
  1744. class GC_ColumnHeaderManager implements VectorViewManager, VectorModel
  1745. {
  1746.   public GC_ColumnHeaderManager(ColumnView[] columns) {
  1747.     this.columns = columns;
  1748.   }
  1749.  
  1750.   public Object get(int index) {
  1751.     String caption = columns[index].getCaption();
  1752.     if (caption == null)
  1753.       caption =  String.valueOf(index);
  1754.     return caption;
  1755.   }
  1756.  
  1757.   public ItemPainter getPainter(int index, Object data, int state) { return painter; }
  1758.   public ItemEditor getEditor(int index, Object data, int state) { return null; }
  1759.   public int find(Object data) { return -1; }
  1760.   public int getCount() { return columns.length; }
  1761.   public void addModelListener(VectorModelListener listener) { modelListeners.add(listener); }
  1762.   public void removeModelListener(VectorModelListener listener) { modelListeners.remove(listener); }
  1763.  
  1764.   private borland.jbcl.util.EventMulticaster modelListeners = new borland.jbcl.util.EventMulticaster();
  1765.   private ColumnView[] columns;
  1766.   private ItemPainter painter = new TextItemPainter(Alignment.CENTER | Alignment.MIDDLE, new Insets(0,2,0,2));
  1767. }
  1768.