Subversion Repositories wimsdev

Rev

Rev 4807 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*
  2. *********************************************************************************
  3. * J.M. Evers 2010                                                               *
  4. * This is all amateur scriblings... So no copyrights.                           *
  5. * This source code file, and compiled classes derived from it,                  *
  6. * can be used and distributed without restriction, including for commercial use *
  7. * No warrenty.                                                  *
  8. *********************************************************************************
  9. version 0.41
  10. 11/2012
  11. Corrected html-table output
  12.  
  13.  
  14. version 0.4
  15. 10/12/2010
  16. Added param pointsize to differ size of points from linewidth
  17. Removed −&times from html reply (problems with representation after sending to wims)
  18. now just ascii + - : x
  19.  
  20. version 0.3
  21. Added decimals [point object]
  22.  
  23. version 0.2
  24.  
  25. Added correct French button text [B. Perrin-Riou]
  26. Added left hand +,-,x,: sign next to the lines [when language=fr ]
  27.  
  28. version 0.1
  29.  
  30. Applet for simple adding, subtracting,dividing and multiplying by pupils.
  31. The result can be checked by WIMS.
  32.  
  33. Output:
  34. document.getElementById('InvulGrid').ReadApplet("0") : itemlist [one item per horizontal line]
  35. document.getElementById('InvulGrid').ReadApplet("1") : javascript confirmbox
  36. document.getElementById('InvulGrid').ReadApplet("2") : html table
  37. document.getElementById('InvulGrid').ReadApplet("3") : latex array/table
  38.  
  39. Example [same as test.html]
  40. <html>
  41.  <body>
  42.      <script type="text/javascript">
  43.         function ReadThis(){
  44.  
  45.             var wims_reply = document.getElementById('InvulGrid').ReadApplet("0");
  46.             alert("this can send to wims for correction:\n"+wims_reply);
  47.            
  48.             var js_alert_show= document.getElementById('InvulGrid').ReadApplet("1");
  49.             alert("this can be the confirmbox for the pupil:\n"+js_alert_show);
  50.            
  51.             var html_show= document.getElementById('InvulGrid').ReadApplet("2");
  52.             document.getElementById('html_reply').innerHTML="this is a html-table representation<br>"+html_show;
  53.            
  54.             var latex_show= document.getElementById('InvulGrid').ReadApplet("3");
  55.             alert("this is an latex array of the answer:\n Usable via !insmath\n"+latex_show);
  56.         }
  57.     </script>.
  58.     <table>
  59.     <tr>
  60.     <th>
  61.     <applet id="InvulGrid" codebase="dist" archive="InvulGrid.jar"  code="InvulGrid.class"  width="400" height="400">
  62.         <param name="fontsize" value="50"><!-- optional: actual fontsize will be determined according xlines/ylines -- xsize/ysize -->
  63.         <param name="pencolor" value="0,0,255,150"><!-- optional: typing color -->
  64.         <param name="bgcolor" value="255,255,255"><!-- optional: canvas bgcolor;default white ; R,G,B,alpha -->
  65.         <param name="markcolor" value="10,255,10,60"><!-- optional:  active field color -->
  66.         <param name="linecolor" value="200,10,60,150"><!-- optional:  user drawn lines in applet  -->
  67.         <param name="linewidth" value="6"><!-- linewidth of user drawn lines -->
  68.         <param name="pointsize" value="3"><!-- size of drawn decimal points -->
  69.        
  70.         <param name="xlines" value="12"><!-- default 10 ; number of vertical lines : determines fontsize -->
  71.         <param name="ylines" value="12"><!-- default 10 ; number of horizontal lines  -->
  72.         <param name="showgrid" value="1"><!-- show xlines and ylines as grid in gridcolor -->
  73.         <param name="gridcolor" value="0,0,255,40"><!-- color of grid  -->
  74.         <param name="reverse" value="yes"><!-- default false ; editing from right to left  -->
  75.        
  76.         <param name="language" value="en"><!-- default en ; nl , fr -->
  77.         <!-- optional: is an itemlist, spaces matter .-->
  78.         <!-- Optional horizontal lines: ---|x|-|+|:  -->
  79.         <!-- bug in java plugin's stringtokenizer: first token blancspace is stripped off... -->
  80.         <!-- in applet viewer this works fine -->
  81.         <!-- to produce an space before the first number, add a "," like-->
  82.         <!-- spaces matter  !! -->
  83.         <param name="exercise" value=",   13456789,     567890,      12345,      45678,    2345678,---|-">
  84.        
  85.         <!-- use first row of grid for user scribbling: this will not be send to wims -->
  86.         <param name="scribling_pencolor" value="255,200,0,170"><!-- optional -->
  87.         <!-- if param buttons is empty or not set : only a 'clear all; button will be shown -->
  88.         <param name="buttons" value="+"><!-- user draws lines with +,-,x,&divide; symbols ; do not use too many!  -->
  89.     </applet>
  90.     <br>
  91.     <input type="button" name="InvulGrid" value="Read " onclick="javascript:ReadThis(0);">
  92.     </th>
  93.     <th>
  94.         <div id="html_reply"></div>
  95.     </th>
  96.     </tr>
  97.     <table>
  98.     </body>
  99. </html>
  100. */
  101.  
  102. import java.applet.Applet;
  103. import java.awt.image.BufferedImage;
  104. import java.awt.*;
  105. import java.awt.event.*;
  106. import java.util.*;
  107. import java.awt.Color;
  108. import javax.swing.*;
  109. //import java.io.*; not needed, we use javascript to communicate with WIMS
  110.  
  111. public class InvulGrid extends JApplet implements  ActionListener,KeyListener,MouseListener, MouseMotionListener, MouseWheelListener {
  112.     Font font;
  113.     int fontsize,xsize,ysize,xlines,ylines,xstep,ystep,linewidth,pointsize;
  114.     Color scribling_pencolor,bgcolor,pencolor,linecolor,markcolor,gridcolor,deletecolor,marked_color,exercisecolor,scribling_rowcolor;
  115.     String[][] charArray;
  116.     boolean[][] Marked;
  117.     boolean[][] Editable;
  118.     boolean[] EditableObject;
  119.     int xindex = 0;
  120.     int yindex = 0;
  121.     int objcnt=0;
  122.     Graphics2D backg;
  123.     BufferedImage bg;
  124.     Vector objects = new Vector();
  125.     Vector decimalpoints = new Vector();
  126.     int pointcnt = 0;
  127.     boolean showgrid;
  128.     public String line_plus="line + ";
  129.     public String line_times="line x";
  130.     public String line_min="line -";
  131.     public String line_div="line :";
  132.     public String delete_line="delete line";
  133.     public String clear_all="clear all";
  134.     Container cp;
  135.     int editablecnt = 0;
  136.     int fontheight=10;
  137.     boolean check_segments = false;
  138.     boolean reverse = false;
  139.     boolean left_to_right = false;
  140.     int scribling = 2;
  141.     // true: --- +  false: + ---
  142.     boolean right = true;
  143.     int fontwidth = 10;
  144.     // reverse :if no 'conclusion line' is drawn, we write form left to right
  145.     // if a line is drawn, we write from right to left...
  146.  
  147.     // slow repainting can occur via update() : using bufferedimage of grid to avoid flickering.
  148.      
  149.     public void init(){
  150.         scribling_pencolor = colorParam("scribling_pencolor", new Color(255,0,0));
  151.         if( (getBool("scribling_row",true)) == true){scribling = 2;}else{scribling = 1;}
  152.         getLanguage("language");
  153.         getButtons();  
  154.         Dimension appletSize = getSize();
  155.         xsize = appletSize.width;
  156.         ysize = appletSize.height;
  157.         xlines = getInt("xlines",10);
  158.         ylines = getInt("ylines",10);
  159.         xstep = (int) xsize/xlines;
  160.         ystep = (int) ysize/(ylines+1);
  161.         bg = new BufferedImage(xsize,ysize, BufferedImage.TYPE_INT_ARGB);
  162.         backg = (Graphics2D) bg.getGraphics();
  163.         // fitfont kan ylines bepalen !! volgorde is belangrijk
  164.         fontsize = getInt("fontsize",28);
  165.         font = FitFont( backg ,"TimesRoman" , fontsize);
  166.         charArray = new String[xlines+1][ylines+1];
  167.         Marked = new boolean[xlines+1][ylines+1];
  168.         Editable = new boolean[xlines+1][ylines+1];
  169.         EditableObject = new boolean[xlines*ylines];
  170.        
  171.         for(int x = 0; x < xlines+1; x++){
  172.             for(int y = 0; y < ylines+1 ; y++){
  173.                 charArray[x][y]="";
  174.                 Marked[x][y]=false;
  175.                 Editable[x][y]=true;
  176.             }
  177.         }
  178.         for(int y = 0 ; y <xlines*ylines;y++){
  179.             EditableObject[y] = true;
  180.         }
  181.         showgrid = getBool("showgrid",true);
  182.         left_to_right = getBool("reverse",false);
  183.         scribling_rowcolor = colorParam("scribling_rowcolor",new Color(0,255,0,50));
  184.         bgcolor = colorParam("bgcolor",Color.white);
  185.         pencolor = colorParam("pencolor",Color.black);
  186.         linecolor = colorParam("linecolor",Color.red);
  187.         markcolor = colorParam("markcolor",Color.green);
  188.         gridcolor = colorParam("gridcolor",Color.blue);
  189.         exercisecolor = colorParam("exercisecolor",Color.black);
  190.         linewidth = getInt("linewidth",2);
  191.         pointsize = getInt("pointsize",5);
  192.         deletecolor = new Color(255,0,0,120);
  193.         marked_color = markcolor;
  194.         addKeyListener(this);
  195.         addMouseListener(this);
  196.         addMouseMotionListener(this);
  197.         addMouseWheelListener(this);
  198.         getSegments();
  199.         ReadStringParam();
  200.         prepaint();
  201.         requestFocus();
  202.     }
  203.  
  204.     public String ReadApplet(String t){
  205.         String[] reply = new String[ylines+1];
  206.         String[] horline = new String[ylines+1];
  207.         StringBuffer tmp;
  208.         int cnt = 0;
  209.         int userline;
  210.         int maxlength=0;
  211.         String op;// operator +,-,/,*
  212.         boolean not_empty = false;
  213.         boolean found_line = false;
  214.         int pnt = -1;
  215.         for( int y = scribling ; y <= ylines ; y++ ){// y = 1 all including scribling row ; y=2 excluding scribling row
  216.             tmp = new StringBuffer();
  217.             found_line = false;
  218.             op = "";
  219.             pnt = -1;
  220.             for(int i = 0 ; i < objcnt ; i++){
  221.                 if (objects.elementAt(i) instanceof GridLine){
  222.                     if( ((GridLine)objects.elementAt(i)).isSegment()  == true ){
  223.                         userline = (int)(((GridLine)objects.elementAt(i)).getY1()/ystep) - 1;
  224.                         if( y == userline ){
  225.                             found_line = true;
  226.                             op = ((GridLine)objects.elementAt(i)).getText();
  227.                             i = objcnt; //exit
  228.                         }
  229.                     }
  230.                 }
  231.             }
  232.             pnt = findPoint(y);
  233.             for( int x = 0 ; x <= xlines ; x++ ){
  234.                 if(x == pnt){
  235.                     tmp.append(".");
  236.                 }
  237.                 tmp.append(charArray[x][y]);
  238.             }
  239.             if(tmp.length() != 0){
  240.                 if( tmp.length() > maxlength ){maxlength = tmp.length();}
  241.                 not_empty = true;
  242.                 reply[cnt] = replace(tmp.toString(), " " , "");
  243.                 //System.out.println("added "+reply[cnt] + " by y =  "+y);
  244.                 if(found_line == true){horline[cnt] = op;}
  245.                 cnt++;
  246.             }
  247.        
  248.         }
  249.         if(not_empty == false){return "error:empty answer";}
  250.  
  251.         if( t.equals("3") ){
  252.             return makeLatex(reply,horline);
  253.         }
  254.         else
  255.         {
  256.             if( t.equals("2") ){
  257.                 return makeHtml(reply,horline);
  258.             }
  259.             else
  260.             {
  261.                 if( t.equals("1") ){
  262.                     return makeJs(reply,horline,maxlength);
  263.                 }
  264.                 else
  265.                 {
  266.                     if( t.equals("0") ){
  267.                         return Array2String(reply,",");
  268.                     }
  269.                     else
  270.                     {
  271.                         return "error : usage is \n ReadApplet(0) ... wims itemlist\n ReadApplet(3) ... latex representation\n ReadApplet(2) ... html representation\n ReadApplet(1) ... javascript confirmbox";
  272.                     }  
  273.                 }
  274.             }
  275.         }    
  276.     }
  277.    
  278.     public String Array2String(String[] s, String sep) {
  279.         StringBuilder result = new StringBuilder();
  280.         if (s.length > 0) {
  281.             result.append(s[0]);
  282.             for (int i=1; i < s.length; i++) {
  283.                 if(s[i] != null){
  284.                     result.append(sep);
  285.                     result.append(s[i]);
  286.                 }
  287.             }
  288.         }
  289.         return result.toString();
  290.     }
  291.  
  292.     public String makeLatex(String[] reply , String[] horline){
  293.         String latex="";
  294.         String op="";
  295.         String space="";
  296.         boolean fraction = false;
  297.         int w = 0;int thisline=0;
  298.         while ( fraction == false && w <= ylines ){
  299.             if(reply[w] != null){
  300.                 if(reply[w].indexOf("\\") != -1){
  301.                     fraction = true;
  302.                     thisline = w;
  303.                 }
  304.             }
  305.             w++;
  306.         }
  307.        
  308.         if(fraction == true ){
  309.             int start = (reply[thisline]).indexOf("/");
  310.             int end = (reply[thisline]).indexOf("\\");
  311.             w = end - start - 1;
  312.             if(w<0){w = reply[thisline].length();}
  313.             reply[thisline] = replace(reply[thisline],"\\"," & \\diagdown & ");
  314.             reply[thisline] = replace(reply[thisline],"/"," & \\diagup & ");
  315.             reply[thisline] = reply[thisline] + " \\\\ ";
  316.             latex="\\begin{array}{cclcc}"+reply[thisline];
  317.             thisline++;
  318.         }
  319.         else
  320.         {
  321.             latex="\\begin{array}{rr}";
  322.             thisline = 0;
  323.         }
  324.        
  325.         for( int y = thisline ; y < reply.length ; y++ ){
  326.             if( reply[y] != null){
  327.                 if(horline[y] != null){
  328.                     if((horline[y]).equals("\u00D7")){
  329.                         op =" \\times ";
  330.                     }
  331.                     else
  332.                     {    
  333.                         if((horline[y]).equals("\u00F7")){
  334.                             op =" \\div ";
  335.                         }
  336.                         else
  337.                         {
  338.                             op = horline[y];    
  339.                         }
  340.                     }
  341.                     if(fraction == false){
  342.                         if(right){
  343.                             latex = latex + " \\underline{" +reply[y]+ "} & "+horline[y] +" \\\\ ";
  344.                         }
  345.                         else // french
  346.                         {
  347.                             latex = latex + horline[y] +" & \\underline{" +reply[y]+ " } \\\\ ";
  348.                         }
  349.                     }
  350.                     else
  351.                     {
  352.                         if( w > reply[y].length()){
  353.                             for(int z=0; z < w - reply[y].length();z++){
  354.                                 space = space + " \\: ";
  355.                             }
  356.                         }
  357.                         latex = latex + "&  & \\underline{" +space+ reply[y]+"} &  & \\\\ ";
  358.                     }
  359.                 }
  360.                 else
  361.                 {
  362.                     if(fraction == false){
  363.                         if(right){
  364.                             latex  = latex + " "+ reply[y] + " & "+ " \\\\ ";
  365.                         }
  366.                         else // french
  367.                         {
  368.                             latex  = latex + " & "+ reply[y] + " \\\\ ";
  369.                         }
  370.                     }
  371.                     else
  372.                     {
  373.                         if( w > reply[y].length()){
  374.                             for(int z=0; z < w - reply[y].length();z++){
  375.                                 space = space + " \\: ";
  376.                             }
  377.                         }
  378.                         latex  = latex + "&  & "+ space+ reply[y] +" &  &  \\\\ ";
  379.                     }
  380.                 }
  381.             }
  382.         }
  383.         latex = latex + " \\end{array}";
  384.         return latex;
  385.     }
  386.  
  387.     public String makeHtml(String[] reply , String[] horline){
  388.         String table = "<table class=\"schaersvoorde_form\"><tr><td style=\"text-align:right\"><table class=\"schaersvoorde_form\">";
  389.         String tmp="";
  390.         for( int y = 0 ; y < reply.length ; y++ ){
  391.             if(reply[y] != null){
  392.                 if(right){
  393.                     table=table+"<tr><td style=\"text-align:right\">"+reply[y]+"</td><td>&nbsp;&nbsp;&nbsp;&nbsp;</td></tr>";
  394.                 }
  395.                 else // french
  396.                 {
  397.                     table=table+"<tr><td style=\"text-align:center;\">&nbsp;&nbsp;&nbsp;&nbsp;</td><td style=\"text-align:right\">"+reply[y]+"</td></tr>";
  398.                 }
  399.                 if(horline[y] != null){
  400.                     if(horline[y].equals("\u00D7")) tmp = "x";
  401.                     else
  402.                     if(horline[y].equals("\u00F7")) tmp = ":";
  403.                     else tmp = horline[y];
  404.                    
  405.                     if(right){
  406.                         table=table+"</table></td></tr><tr><td><table class=\"schaersvoorde_form\"><tr><th style=\"width:100%\"><hr style=\"height:2px;color:black;width:100%\"/></th><th>"+tmp+"</th></tr></table></td></tr><td><table class=\"schaersvoorde_form\">";
  407.                     }
  408.                     else // french
  409.                     {
  410.                         table=table+"</table></td><tr><td><table class=\"schaersvoorde_form\"><tr><th>"+tmp+"</th><th style=\"width:100%\"><hr style=\"height:2px;color:black;width:100%\"/></th></tr></table></td></tr><td><table class=\"schaersvoorde_form\">";
  411.                     }
  412.                 }
  413.             }
  414.         }
  415.         table = table+"</table></td></tr></table>";
  416.         return table;
  417.     }
  418.    
  419.     public String makeJs(String[] reply, String[] horline , int maxlength){
  420.         String js="";String space = "";String line = "";String op = "";
  421.         for(int i = 0 ; i < maxlength ; i++){
  422.             line = line + "-";
  423.         }
  424.         for( int y = 0 ; y < reply.length ; y++ ){
  425.             if(reply[y] != null){
  426.                 if(horline[y] != null){
  427.                     space = "";
  428.                     for(int i = 0 ; i < (maxlength - reply[y].length()) ; i++){
  429.                         space = space + " ";
  430.                     }
  431.                     if(right){
  432.                         js = js + space+reply[y] + "\n" + line + " " + horline[y] + "\n";
  433.                     }
  434.                     else // french
  435.                     {
  436.                         js = js + space+reply[y] + "\n" + horline[y] +"  "+ line + "\n";
  437.                     }
  438.                 }
  439.                 else // trying to align at the rightside of the alertbox ... somehow this will not work properly
  440.                 {
  441.                     space = "";
  442.                     for(int i = 0 ; i < (maxlength - reply[y].length()) ; i++){
  443.                         space = space + " ";
  444.                     }
  445.                     js  = js + space + reply[y] + "\n";
  446.                 }
  447.             }
  448.         }
  449.         return js;
  450.     }
  451.    
  452.     public void getSegments(){
  453.         String param = getParameter("segment1");
  454.         if(param != null && param.length() > 3){
  455.        
  456.             int i = 1;
  457.             StringTokenizer s;
  458.             int m=0,x1=0,x2=0,y1=0,y2=0;
  459.             String colorparam;Color segmentcolor;
  460.             check_segments = true;
  461.             while( param != null && param.length() >3 ){
  462.                 s = new StringTokenizer(param, ",");
  463.                 m = s.countTokens();
  464.                 if(m != 4){System.out.println("Expecting 2 points for a linesegment");return;}
  465.                 for(int p = 0 ; p < 4 ; p++){
  466.                     if( p == 0 ){ x1 =  Integer.parseInt(s.nextToken());}
  467.                     else
  468.                     if( p == 1 ){ y1 =  Integer.parseInt(s.nextToken());}
  469.                     else
  470.                     if( p == 2 ){ x2 =  Integer.parseInt(s.nextToken());}
  471.                     else
  472.                     if( p == 3 ){ y2 =  Integer.parseInt(s.nextToken());}
  473.                 }
  474.                 colorparam = "color"+i;
  475.                 EditableObject[editablecnt] = false;editablecnt++;
  476.                 segmentcolor =  colorParam(colorparam,linecolor);
  477.                 drawLine(x1*xstep,(y1+2)*ystep,x2*xstep,(y2+2)*ystep,segmentcolor,"",false,false);
  478.                 i++;
  479.                 param = getParameter("segment"+i);
  480.             }
  481.         }
  482.     }
  483.  
  484.  
  485.     public void ReadStringParam(){
  486.         String exo = getParameter("exercise");
  487.         if(exo != null && exo.length()>0){
  488.             StringTokenizer lines = new StringTokenizer(exo, ",");
  489.             int m=lines.countTokens();
  490.             boolean found_fraction = false;
  491.             boolean found_decimal_point = false;
  492.             if( m < ylines ){
  493.                 String lastword="";
  494.                 String word="";String tmp="";int xi=0;
  495.                 for( int i = 0 ; i < m ; i++){
  496.                     word = lines.nextToken();
  497.                     if(word.indexOf("/") != -1){ found_fraction = true;}
  498.                     if(word.indexOf("---|") != -1){// a special line and should be LAST !!
  499.                         // the last word was: charArray[xindex - 1][yindex - 1]
  500.                         char[] wordArray = lastword.toCharArray();
  501.                         boolean found = false;int start = 0;int end = wordArray.length;
  502.                         for(int s = 0; s < end;s++){
  503.                             if(wordArray[s] != ' ' && !found){start = s;found = true;}
  504.                         }
  505.                         if(right && found_decimal_point){
  506.                             end = end - 1;
  507.                         }
  508.                         else
  509.                         {
  510.                             if(!right && found_decimal_point && start >0 ){start = start - 1; end = end - 1;}
  511.                         }
  512.                         if(word.indexOf("---|+") != -1){ // ---- +
  513.                             drawLine(start*xstep,(i+2)*ystep,end*xstep,(i+2)*ystep,linecolor,"+",false,true);
  514.                             EditableObject[editablecnt] = false;editablecnt++;
  515.                         }
  516.                         else
  517.                         {
  518.                             if(word.indexOf("---|-") != -1){ // ---- -
  519.                                 drawLine(start*xstep,(i+2)*ystep,end*xstep,(i+2)*ystep,linecolor,"-",false,true);
  520.                                 EditableObject[editablecnt] = false;editablecnt++;
  521.                             }
  522.                             else
  523.                             {
  524.                                 if(word.indexOf("---|x") != -1){ // ---- x
  525.                                     drawLine(start*xstep,(i+2)*ystep,end*xstep,(i+2)*ystep,linecolor,"\u00D7",false,true);
  526.                                     EditableObject[editablecnt] = false;editablecnt++;
  527.                                 }
  528.                                 else
  529.                                 {
  530.                                     if(word.indexOf("---|:") != -1){ // ---- division
  531.                                         drawLine(start*xstep,(i+2)*ystep,end*xstep,(i+2)*ystep,linecolor,"\u00F7",false,true);
  532.                                         EditableObject[editablecnt] = false;editablecnt++;
  533.                                     }
  534.                                     else
  535.                                     {
  536.                                         System.out.println("unknown command : "+word);
  537.                                     }
  538.                                 }
  539.                             }
  540.                         }    
  541.                     }
  542.                     else
  543.                     {
  544.                         xi=0;
  545.                         for( int p = 0 ; p < word.length(); p++){
  546.                             if( p <= xlines ){
  547.                                 tmp = Character.toString(word.charAt(p));
  548.                                 if(tmp.equals(".")){
  549.                                     drawPoint(xi,i+2,pointsize,false);
  550.                                     found_decimal_point = true;
  551.                                 }
  552.                                 else
  553.                                 {
  554.                                     charArray[xi][i+2] = tmp;
  555.                                     //we do not use yindex=1 : space is used for controls...
  556.                                     lastword = word;
  557.                                     if(found_fraction == true){
  558.                                         Editable[xi][i+2] = false;
  559.                                     }
  560.                                     else
  561.                                     {
  562.                                         for(int c = 0 ; c<xlines;c++){ // disable editing of line y=i+2
  563.                                             Editable[c][i+2] = false;
  564.                                         }
  565.                                     }
  566.                                     xi++;
  567.                                 }
  568.                             }
  569.                             else
  570.                             {
  571.                                 System.out.println("ERROR : word "+word+" too large for "+xlines+" gridlines...\nin param \"execise\"");
  572.                                 return;
  573.                             }
  574.                         }
  575.                     }
  576.                 }
  577.                 for(int x = 0 ; x<xlines ; x++){
  578.                     Editable[x][1] = true;
  579.                     charArray[x][1]="";
  580.                 }
  581.             }
  582.             else
  583.             {
  584.                 System.out.println("ERROR : to many spaces in param \"exercise\"");
  585.                 return;
  586.             }
  587.         }
  588.     }
  589.  
  590.  
  591.     public void getLanguage(String s){
  592.         s = getParameter("language");
  593.         if(s != null && s.length()  == 2){
  594.             if( s.equalsIgnoreCase("nl")){
  595.                 line_plus="lijn + ";
  596.                 line_times="lijn x";
  597.                 line_min="lijn -";
  598.                 delete_line="verwijder lijn";
  599.                 clear_all="alles wissen";
  600.                 line_div="line :";
  601.                 right=true;
  602.                 return;
  603.             }
  604.             else
  605.             {
  606.                 if( s.equalsIgnoreCase("fr")){
  607.                     line_plus="droite + ";
  608.                     line_times="droite x";
  609.                     delete_line="effacer droite";
  610.                     clear_all="effacer";
  611.                     line_min="droite -";
  612.                     line_div="droite :";
  613.                     right=false;
  614.                     return;
  615.                 }
  616.             }
  617.         }
  618.     }
  619.    
  620.    
  621.     public Font FitFont(Graphics g , String fontname , int fontsize){
  622.         String maxstring="";
  623.         for(int p = 0 ; p<xlines+4;p++){
  624.             maxstring=maxstring+"5";
  625.         }
  626.         font  = new Font(fontname,Font.BOLD,fontsize);
  627.         FontMetrics fm = g.getFontMetrics(font);
  628.         if(fm.stringWidth(maxstring) > xsize){
  629.             boolean does_not_fit = true;
  630.             while(fontsize > 4 && does_not_fit){
  631.                 fontsize = fontsize - 1;
  632.                 font = new Font(fontname,Font.BOLD,fontsize);
  633.                 fm = g.getFontMetrics(font);
  634.                 if(fm.stringWidth(maxstring) < xsize){
  635.                     does_not_fit = false;
  636.                 }
  637.             }
  638.             System.out.println("xsize ("+xsize+") of applet too small...I've adjusted fontsize to "+fontsize);
  639.             font  = new Font(fontname,Font.BOLD,fontsize);
  640.             fm = g.getFontMetrics(font);
  641.         }
  642.         fontheight =(int) (0.6*fm.getHeight());
  643.         if( fontheight > ystep ){ // fonts will overlap !! decrease ygrid...
  644.             System.out.println("I will decrease number of horizontal lines: fonts will overlap...\nuse more xlines to overcome this.");
  645.             ystep =  fontheight;
  646.             ylines = (int) (ysize / fontheight);
  647.             if(ylines < 2){ylines = 2;}
  648.         }
  649.         fontwidth = fm.stringWidth("+");
  650.         return font;
  651.     }
  652.    
  653.     public int getInt(String s, int i){
  654.         String s1 = getParameter(s);
  655.         if( s1 != null && s1.length()!=0){
  656.             try{
  657.                 i = Integer.parseInt(s1);
  658.             }
  659.             catch(Exception exception){System.out.println(" can not parse parameter "+s);}
  660.         }
  661.         return i;
  662.     }
  663.  
  664.     public boolean getBool(String s, boolean flag){
  665.         String s1 = getParameter(s);
  666.         if(s1 != null){
  667.             if(s1.equals("1") || s1.equalsIgnoreCase("yes") || s1.equalsIgnoreCase("true"))
  668.                 return true;
  669.             if(s1.equals("0") || s1.equalsIgnoreCase("no") || s1.equalsIgnoreCase("false"))
  670.                 return false;
  671.         }
  672.         return flag;
  673.     }
  674.  
  675.     public Color colorParam(String s, Color color){
  676.         String s1 = getParameter(s);
  677.         if(s1 != null && s1.length() != 0){
  678.             s1 = replace(s1,":", ",");
  679.             s1 = replace(s1,";", ",");
  680.             if( s1.indexOf(',') > 0 ){
  681.                 StringTokenizer stringtokenizer = new StringTokenizer(s1, ",");
  682.                 int i = stringtokenizer.countTokens();
  683.                 if(i < 3 || i > 4){ return color;}
  684.                 int ai[] = new int[i + 1];
  685.                 for(int j = 0; j < i; j++){
  686.                     ai[j] = Integer.parseInt(stringtokenizer.nextToken());
  687.                     if(ai[j] > 255 || ai[j] < 0){ ai[j] = 0;}
  688.                 }
  689.                 if(i == 3){
  690.                     color = new Color(ai[0], ai[1], ai[2]);
  691.                 }
  692.                 else
  693.                 {
  694.                     color = new Color(ai[0], ai[1], ai[2], ai[3]);
  695.                 }
  696.             }
  697.             else
  698.             {
  699.                 try{ color = Color.decode( s1 );}catch(Exception e){System.out.println("could not parse "+s);}
  700.                 return color;
  701.             }
  702.         }
  703.         return color;
  704.     }
  705.  
  706.     public void prepaint(){ // all "static" components are painted "once"
  707.         backg.setColor(bgcolor);
  708.         backg.fillRect(0,0,xsize,ysize);
  709.         if(showgrid){
  710.             backg.setColor(gridcolor);
  711.             backg.setStroke( new BasicStroke(1));
  712.             for(int x=0; x<xsize;x=x+xstep){
  713.                     backg.drawLine(x,ystep,x,ysize);
  714.             }
  715.             for(int y=ystep;y<ysize;y=y+ystep){
  716.                 backg.drawLine(0,y,xsize,y);                   
  717.             }
  718.         }
  719.         reverse=false;
  720.         backg.setFont(font);
  721.         for( int i = 0 ; i < objcnt; i++){
  722.             if (objects.elementAt(i) instanceof GridLine){
  723.                 backg.setStroke( new BasicStroke(linewidth));
  724.                 backg.setColor(((GridLine)objects.elementAt(i)).getColor());
  725.                 backg.drawLine(
  726.                     ((GridLine)objects.elementAt(i)).getX1(),
  727.                     ((GridLine)objects.elementAt(i)).getY1(),
  728.                     ((GridLine)objects.elementAt(i)).getX2(),
  729.                     ((GridLine)objects.elementAt(i)).getY2()
  730.                 );
  731.                 if(right){
  732.                     backg.drawString(
  733.                         ((GridLine)objects.elementAt(i)).getText(),
  734.                         ((GridLine)objects.elementAt(i)).getX2()+linewidth,
  735.                         ((GridLine)objects.elementAt(i)).getY2()
  736.                         //((GridLine)objects.elementAt(i)).getY2()+(fontheight-linewidth)/2
  737.                     );
  738.                 }
  739.                 else
  740.                 {
  741.                     backg.drawString(
  742.                         ((GridLine)objects.elementAt(i)).getText(),
  743.                         ((GridLine)objects.elementAt(i)).getX1()-linewidth-fontwidth,
  744.                         ((GridLine)objects.elementAt(i)).getY2()
  745.                         //((GridLine)objects.elementAt(i)).getY2()+(fontheight-linewidth)/2
  746.                     );
  747.                 }
  748.                 if(i == objcnt - 1){
  749.                     reverse= ((GridLine)objects.elementAt(i)).isSegment();
  750.                 }
  751.             }
  752.         }
  753.         for( int i = 0 ;i < pointcnt ; i++){
  754.             if (decimalpoints.elementAt(i) instanceof DecimalPoint){
  755.                 int l = ((DecimalPoint)decimalpoints.elementAt(i)).getD();
  756.                 backg.setStroke( new BasicStroke(l));
  757.                 backg.setColor(pencolor);
  758.                 backg.fillOval(
  759.                     xstep*(((DecimalPoint)decimalpoints.elementAt(i)).getX()) - pointsize,
  760.                     ystep*(1+((DecimalPoint)decimalpoints.elementAt(i)).getY()) - pointsize,
  761.                     l,
  762.                     l
  763.                 );
  764.             }
  765.         }
  766.         backg.setColor(scribling_rowcolor);
  767.         for(int x = 0 ; x <= xlines ; x++){
  768.             backg.fillRect(x*xstep,ystep,xstep,ystep); //scribling row
  769.         }
  770.  
  771.         backg.setColor(exercisecolor);
  772.         for(int x=0;x <= xlines ;x++){
  773.             for(int y=0;y <= ylines  ;y++){
  774.                 if(!Editable[x][y]){
  775.                     backg.drawString(charArray[x][y],x*xstep,(y+1)*ystep);
  776.                 }
  777.             }
  778.         }
  779.     }
  780.    
  781.     public void update(Graphics g){
  782.         prepaint();
  783.         paintComponent(g);
  784.     }
  785.    
  786.     public void paint(Graphics g){
  787.         update(g);
  788.     }
  789.  
  790.     public void paintComponent(Graphics g){
  791.         Graphics2D g2 = (Graphics2D) g;
  792.         g2.drawImage(bg,0,0,this);
  793.         g2.setFont(font);
  794.         reverse=false;
  795.         for( int i = 0 ; i < objcnt; i++){
  796.             if (objects.elementAt(i) instanceof GridLine){
  797.                 if( ((GridLine)objects.elementAt(i)).getEdit() ){
  798.                     backg.setStroke( new BasicStroke(linewidth));
  799.                     backg.setColor(((GridLine)objects.elementAt(i)).getColor());
  800.                     backg.drawLine(
  801.                         ((GridLine)objects.elementAt(i)).getX1(),
  802.                         ((GridLine)objects.elementAt(i)).getY1(),
  803.                         ((GridLine)objects.elementAt(i)).getX2(),
  804.                         ((GridLine)objects.elementAt(i)).getY2()
  805.                     );
  806.                     if(right){
  807.                         backg.drawString(
  808.                             ((GridLine)objects.elementAt(i)).getText(),
  809.                             ((GridLine)objects.elementAt(i)).getX2()+linewidth, // ---- +
  810.                             ((GridLine)objects.elementAt(i)).getY2()
  811.                             //((GridLine)objects.elementAt(i)).getY2()+(fontheight-linewidth)/2
  812.                         );
  813.                     }
  814.                     else //french
  815.                     {
  816.                         backg.drawString(
  817.                             ((GridLine)objects.elementAt(i)).getText(),
  818.                             ((GridLine)objects.elementAt(i)).getX1()-linewidth-fontwidth, // + ----
  819.                             ((GridLine)objects.elementAt(i)).getY2()+(fontheight-linewidth)/2
  820.                         );
  821.                    
  822.                     }
  823.                 }
  824.                 if(i == objcnt - 1){
  825.                     reverse= ((GridLine)objects.elementAt(i)).isSegment();
  826.                 }
  827.             }
  828.         }
  829.         for( int i = 0 ; i < pointcnt; i++){
  830.             if (decimalpoints.elementAt(i) instanceof DecimalPoint){
  831.                 int l = ((DecimalPoint)decimalpoints.elementAt(i)).getD();
  832.                 backg.setStroke( new BasicStroke(l));
  833.                 backg.setColor(pencolor);
  834.                 backg.fillOval(
  835.                     xstep*(((DecimalPoint)decimalpoints.elementAt(i)).getX()) - pointsize,
  836.                     ystep*(1+((DecimalPoint)decimalpoints.elementAt(i)).getY()) - pointsize,
  837.                     l,
  838.                     l
  839.                 );
  840.             }
  841.         }
  842.         for(int y=1;y <= ylines  ;y++){ // start from scribling row
  843.             for(int x=0;x <= xlines ;x++){
  844.                 if(Marked[x][y]){
  845.                     g2.setColor(marked_color);
  846.                     g2.fillRect(x*xstep,y*ystep,xstep,ystep);
  847.                     Marked[x][y]=false;
  848.                 }
  849.                 if(Editable[x][y]){
  850.                     if( y == 1){ // scribling row
  851.                         g2.setColor(scribling_pencolor);
  852.                     }
  853.                     else
  854.                     {
  855.                         g2.setColor(pencolor);
  856.                     }
  857.                     g2.drawString(charArray[x][y],x*xstep,(y+1)*ystep);
  858.                 }
  859.             }
  860.         }
  861.        
  862.     }
  863.    
  864.     public synchronized void mousePressed(MouseEvent evt){
  865.         int x = evt.getX();int y = evt.getY();
  866.         boolean xfound=false,yfound=false;
  867.         for(int p=0 ; p < xsize ; p = p + xstep){
  868.             if(x > p && x < p + xstep ){
  869.                 xindex = (int) x/xstep;
  870.                 xfound=true;
  871.             }
  872.         }
  873.         for(int p=ystep ; p < ysize ; p = p + ystep){
  874.             if(y > p && y < p + ystep ){
  875.                 yindex = (int) y/ystep ;
  876.                 yfound=true;
  877.             }
  878.         }
  879.         if(xfound && yfound){
  880.             Marked[xindex][yindex] = true;
  881.             repaint();
  882.         }
  883.     }
  884.     public void mouseWheelMoved(MouseWheelEvent evt){
  885.         int d = evt.getWheelRotation();
  886.         if(d < 0){
  887.             yindex--;
  888.             if(yindex < 1){yindex =  1;}
  889.             Marked[xindex][yindex] = true;
  890.         }
  891.         else
  892.         {
  893.             yindex++;
  894.             if(yindex > ylines ){yindex = ylines ;}
  895.             Marked[xindex][yindex] = true;
  896.         }
  897.         repaint();
  898.     }
  899.  
  900.     public synchronized void mouseDragged(MouseEvent evt){
  901.         int x =(int) (evt.getX())/xstep;
  902.         int y =(int) (evt.getY())/ystep;
  903.         if(x>=0 && y>=1 && x<=xlines && y<=ylines){
  904.             if(Editable[x][y]){ // only delete if editable
  905.                 Marked[x][y] = true;
  906.                 charArray[x][y]="";
  907.                 deleteDecimalPoint(x,y);
  908.                 marked_color=deletecolor;
  909.                 xindex = x;
  910.                 yindex = y;
  911.                 repaint();
  912.             }
  913.         }
  914.     }
  915.    
  916.     public synchronized void mouseReleased(MouseEvent evt){}
  917.     public void mouseEntered(MouseEvent evt){requestFocus();}
  918.     public void mouseExited(MouseEvent evt){}
  919.     public void mouseMoved(MouseEvent evt){requestFocus();}
  920.     public void mouseClicked(MouseEvent evt){
  921.         int x =(int) (evt.getX())/xstep;
  922.         int y =(int) (evt.getY())/ystep;
  923.         if(x>=0 && y>=0 && x<=xlines && y<=ylines){
  924.             if(Editable[x][y]){
  925.                 xindex = x;yindex = y;
  926.                 Marked[xindex][yindex] = true;
  927.                 repaint();
  928.             }
  929.         }
  930.     }
  931.     public int[] ForbiddenKeys={16,17,18,19,20,27,112,113,114,115,116,117,118,119,120,145,154,155};
  932.  
  933.     public void keyPressed(KeyEvent e){
  934.         int key = e.getKeyCode();
  935.         //System.out.println("key="+key);
  936.         for(int i = 0 ; i < 18 ; i++){
  937.             if(key == ForbiddenKeys[i]){return;}
  938.         }
  939.         ProcessKey( key, Character.toString(e.getKeyChar()) );
  940.         repaint();
  941.     }
  942.    
  943.     public void keyTyped(KeyEvent e ) {}
  944.     public void keyReleased(KeyEvent e){}
  945.  
  946.     public void ProcessKey(int key,String c){
  947.             if(key == 46 || key == 44){if(Editable[xindex][yindex] == true){if(reverse){drawPoint(xindex+1,yindex,pointsize,true);}else{drawPoint(xindex,yindex,pointsize,true);}Marked[xindex][yindex] = true;}}
  948.             else
  949.             if(key == 32){ // space
  950.                 xindex++;;
  951.                 if( xindex > xlines - 1){
  952.                     xindex = 0;
  953.                     yindex++;
  954.                     if(yindex > ylines ){yindex = ylines;}     
  955.                 }
  956.                 Marked[xindex][yindex] = true;
  957.             }
  958.             else
  959.             if(key == 10){ // enter -> newline : starts under the first char of previous line
  960.                 int[] word = findLastWordLength();
  961.                 yindex++;
  962.                 if(reverse && left_to_right == false ){xindex = word[2];}else{xindex = word[1];}
  963.                 if(yindex > ylines  ){yindex = ylines;}
  964.                 Marked[xindex][yindex] = true;
  965.             }
  966.             else
  967.             if(key == 37){ // leftarrow
  968.                 xindex--;
  969.                 if(xindex < 0){xindex = xlines;
  970.                     yindex--;
  971.                     if(yindex < 1){yindex = 1;}// not smaller than 1 : control button space...
  972.                 }
  973.                 Marked[xindex][yindex] = true;
  974.             }
  975.             else
  976.             if(key == 39){ // rightarrow
  977.                 xindex++;
  978.                 if( xindex > xlines - 1){
  979.                     xindex = 0;
  980.                     yindex++;
  981.                     if(yindex > ylines ){yindex = ylines;}     
  982.                 }
  983.                 Marked[xindex][yindex] = true;
  984.             }
  985.             else
  986.             if( key == 36){// home;
  987.                 yindex = 1;
  988.                 xindex = 1;
  989.                 Marked[xindex][yindex] = true;
  990.             }
  991.             else           
  992.             if( key == 35){// end;
  993.                 yindex = ylines ;
  994.                 Marked[xindex][yindex] = true;
  995.             }
  996.             else           
  997.             if( key == 38 || key == 33){// arrow up
  998.                 yindex--;
  999.                 if(yindex < 1){yindex = 1;}
  1000.                 Marked[xindex][yindex] = true;
  1001.             }
  1002.             else
  1003.             if( key == 40 || key == 34 ){// arrow down
  1004.                 yindex++;
  1005.                 if(yindex > ylines ){yindex = ylines ;}
  1006.                 Marked[xindex][yindex] = true;
  1007.             }      
  1008.             else
  1009.             if( (key == 8 ) && Editable[xindex][yindex]){//backspace
  1010.                 charArray[xindex][yindex] = "";
  1011.                 deleteDecimalPoint(xindex,yindex);
  1012.                 xindex--;
  1013.                 if(xindex < 0){
  1014.                     xindex = xlines - 1;
  1015.                     yindex--;
  1016.                     if(yindex < 1){ yindex = 1;}
  1017.                 }
  1018.                 Marked[xindex][yindex] = true;
  1019.             }
  1020.             else
  1021.             if( ( key == 127 )  && Editable[xindex][yindex]){// delete
  1022.                 charArray[xindex][yindex] = "";
  1023.                 Marked[xindex][yindex] = true;
  1024.                 deleteDecimalPoint(xindex,yindex);
  1025.             }
  1026.             else
  1027.             {
  1028.                 if(Editable[xindex][yindex]){
  1029.                     charArray[xindex][yindex] = c;
  1030.                     if(reverse && left_to_right == false ){
  1031.                         if(xindex < xlines ){
  1032.                             xindex = xindex - 1;
  1033.                             if (xindex<0 ){
  1034.                                 int[] pos = findLastWordLength();
  1035.                                 xindex = pos[2];
  1036.                                 yindex++;
  1037.                                 if( yindex > ylines ){ yindex = ylines;}
  1038.                             }
  1039.                         }
  1040.                     }
  1041.                     else
  1042.                     {
  1043.                         if(xindex < xlines ){
  1044.                             xindex = xindex + 1;
  1045.                             if (xindex>=xlines ){
  1046.                                 int[] pos = findLastWordLength();
  1047.                                 xindex = pos[1];
  1048.                                 yindex++;
  1049.                                 if( yindex > ylines ){ yindex = ylines;}
  1050.                             }
  1051.                         }
  1052.                     }  
  1053.                     Marked[xindex][yindex] = true;
  1054.                 }
  1055.                
  1056.             }
  1057.             marked_color = markcolor;
  1058.     }
  1059.  
  1060.     public void Clear(){
  1061.         for(int x = 0; x < xlines+1; x++){
  1062.             for(int y = 0; y < ylines+1 ; y++){
  1063.                 if(Editable[x][y]){ // only clear if editable
  1064.                     charArray[x][y]="";
  1065.                     Marked[x][y]=false;
  1066.                 }
  1067.             }
  1068.         }
  1069.         repaint();
  1070.     }
  1071.  
  1072.     public int[] findLastWordLength(){
  1073.         int[] word = new int[4];
  1074.         int cnt;int thisline=0;int max=0;
  1075.         for(int y = 0 ; y < ylines ; y++){
  1076.             cnt=0;
  1077.             for(int x=0 ; x < xlines ; x++){
  1078.                 if(charArray[x][y] != ""){cnt++;}
  1079.             }
  1080.             if(cnt>0){
  1081.                 thisline = y;
  1082.                 if( cnt > max ){ max = cnt;}
  1083.             }
  1084.         }
  1085.         int begin=0;
  1086.         int end=xlines;
  1087.         for(int x = 0 ; x<xlines;x++){ // from left to word
  1088.             if(charArray[x][thisline] != "" ){begin = x;x=xlines;}
  1089.         }
  1090.         for(int x = xlines - 1  ; x >= 0;x--){//from right to word
  1091.             if(charArray[x][thisline] != "" ){ end = x; x=-1;}
  1092.         }
  1093.         word[0] = thisline;
  1094.         word[1] = begin;
  1095.         word[2] = end;
  1096.         word[3] = max;
  1097.         return word;
  1098.     }
  1099.  
  1100.  
  1101.     public  String replace(String source, String pattern, String replace){
  1102.         if ( source!=null && pattern.length()!=0 ){
  1103.             final int len = pattern.length();
  1104.             StringBuffer sb = new StringBuffer();
  1105.             int found = -1;
  1106.             int start = 0;
  1107.             while( (found = source.indexOf(pattern, start) ) != -1) {
  1108.                 sb.append(source.substring(start, found));
  1109.                 sb.append(replace);
  1110.                 start = found + len;
  1111.             }
  1112.             sb.append(source.substring(start));
  1113.             return sb.toString();
  1114.         }
  1115.         else return "";
  1116.     }
  1117.  
  1118.     public void deleteAllLines(){
  1119.         int s = objcnt - 1;
  1120.         for( int i = s ; i >=0; i--){
  1121.             if(EditableObject[i]){
  1122.                 objects.removeElementAt(i);
  1123.                 objcnt--;
  1124.             }
  1125.         }
  1126.         repaint();
  1127.     }
  1128.  
  1129.     public void deleteLine(){
  1130.         if(objcnt <= 0){objcnt = 0; return;}
  1131.         if( (EditableObject[objcnt - 1]) == true){
  1132.             try{
  1133.                 objcnt--;
  1134.                 objects.removeElementAt(objcnt);
  1135.                 repaint();
  1136.             }
  1137.             catch(Exception e){System.out.println("can not remove line ... objcnt = "+objcnt+"\nerror : "+e);}
  1138.         }
  1139.     }
  1140.  
  1141.     public void deleteAllPoints(){
  1142.         int m = pointcnt - 1;
  1143.         for( int i = m ; i >=0; i--){
  1144.             if( (((DecimalPoint)decimalpoints.elementAt(i)).getEditable()) == true ){
  1145.                 decimalpoints.removeElementAt(i);
  1146.                 pointcnt--;
  1147.             }
  1148.         }
  1149.         repaint();
  1150.     }
  1151.    
  1152.     public int findPoint(int y){ // find the x- location of a decimal point at line y : only 1 point allowed...
  1153.         for(int i = 0 ; i<pointcnt;i++){
  1154.             if( (DecimalPoint)decimalpoints.elementAt(i) != null ){
  1155.                 if( (((DecimalPoint)decimalpoints.elementAt(i)).getY()) == y ){
  1156.                     return (int) (((DecimalPoint)decimalpoints.elementAt(i)).getX());
  1157.                 }
  1158.             }
  1159.         }
  1160.         return -1;
  1161.     }
  1162.    
  1163.     public void deleteDecimalPoint(int x,int y){
  1164.         for( int i = 0 ; i < pointcnt; i++){
  1165.             if(
  1166.                 (((DecimalPoint)decimalpoints.elementAt(i)).getX()) == x
  1167.                 &&
  1168.                 (((DecimalPoint)decimalpoints.elementAt(i)).getY()) == y
  1169.                 &&
  1170.                 (((DecimalPoint)decimalpoints.elementAt(i)).getEditable()) == true
  1171.             ){
  1172.                 try{
  1173.                     decimalpoints.removeElementAt(i);
  1174.                     pointcnt--;
  1175.                     repaint();
  1176.                     return;
  1177.                 }catch(Exception e){System.out.println("poincnt "+pointcnt+"\terror="+e);}
  1178.             }
  1179.         }
  1180.     }
  1181.    
  1182.     public void destroy() {}
  1183.    
  1184.     public void start(){}
  1185.  
  1186.     public void drawPoint(int x, int y, int pointsize,boolean can_be_edited){
  1187.         try{
  1188.             decimalpoints.add(new DecimalPoint(x,y,pointsize,can_be_edited));
  1189.             pointcnt++;
  1190.         }
  1191.         catch(Exception e){System.out.println(e);}
  1192.     }
  1193.    
  1194.     public void drawLine(int x1,int y1,int x2,int y2,Color c,String s, boolean edit , boolean is_segment){
  1195.         try{
  1196.             objects.add(new GridLine(x1,y1,x2,y2,c,s,edit,is_segment));
  1197.             objcnt++;
  1198.         }
  1199.         catch(Exception e){System.out.println(e);}
  1200.     }
  1201.    
  1202.     public void actionPerformed(ActionEvent e){
  1203.         String command = e.getActionCommand();
  1204.         if(command.equals(clear_all)){
  1205.             Clear();
  1206.             deleteAllLines();
  1207.             deleteAllPoints();
  1208.         }
  1209.         else
  1210.         {
  1211.             if(command.equals(line_plus)){
  1212.                 int[] word = findLastWordLength();
  1213.                 if(word[0] > 1){
  1214.                     drawLine(word[1]*xstep,(word[0]+1)*ystep,(word[2]+1)*xstep,(word[0]+1)*ystep,linecolor,"+",true,true);//+
  1215.                 }
  1216.             }
  1217.             else
  1218.             {
  1219.                 if(command.equals(line_min)){
  1220.                     int[] word = findLastWordLength();
  1221.                     if(word[0] > 1){
  1222.                         drawLine(word[1]*xstep,(word[0]+1)*ystep,(word[2]+1)*xstep,(word[0]+1)*ystep,linecolor,"-",true,true);//+
  1223.                     }
  1224.                 }
  1225.                 else
  1226.                 {
  1227.                     if(command.equals(line_div)){
  1228.                         int[] word = findLastWordLength();
  1229.                         if(word[0] > 1){
  1230.                             drawLine(word[1]*xstep,(word[0]+1)*ystep,(word[2]+1)*xstep,(word[0]+1)*ystep,linecolor,"\u00F7",true,true);//+
  1231.                         }
  1232.                     }
  1233.                     else
  1234.                     {
  1235.                         if(command.equals(line_times)){
  1236.                             int[] word = findLastWordLength();
  1237.                             if(word[0] > 1){
  1238.                                 drawLine(word[1]*xstep,(word[0]+1)*ystep,(word[2]+1)*xstep,(word[0]+1)*ystep,linecolor,"\u00D7",true,true);
  1239.                             }
  1240.                         }
  1241.                         else
  1242.                         {
  1243.                             if(command.equals(delete_line)){
  1244.                                 deleteLine();
  1245.                             }
  1246.                         }
  1247.                     }
  1248.                 }
  1249.             }
  1250.         }
  1251.         repaint();
  1252.     }
  1253.    
  1254.     public void getButtons(){
  1255.         String param = getParameter("buttons");
  1256.         Panel panel;
  1257.         if( param != null && param.length()>0){
  1258.             panel = InvulGridPanel(param);
  1259.         }
  1260.         else
  1261.         {
  1262.             panel = InvulGridPanel("none");
  1263.         }
  1264.         cp = getContentPane();
  1265.         cp.add(panel);
  1266.     }
  1267.  
  1268.     public Panel InvulGridPanel(String param){
  1269.         Panel panel = new Panel();
  1270.         setLayout(new FlowLayout());
  1271.         Button s;
  1272.         if(!param.equals("none")){
  1273.             StringTokenizer label = new StringTokenizer(param, ",");
  1274.             int m = label.countTokens();String operator="";
  1275.             String txt="";
  1276.             for(int i = 0; i < m ;i++){
  1277.                 operator = label.nextToken();
  1278.                 if(operator.equals("+")) txt = line_plus;
  1279.                 else
  1280.                 if(operator.equals("-")) txt = line_min;
  1281.                 else
  1282.                 if(operator.equals(":")) txt = line_div;
  1283.                 else
  1284.                 if(operator.equals("x")) txt = line_times;
  1285.                 s = new Button(txt);
  1286.                 s.addActionListener(this);
  1287.                 add(s);
  1288.             }
  1289.             s = new Button(delete_line);
  1290.             s.addActionListener(this);
  1291.             add(s);
  1292.         }
  1293.         s = new Button(clear_all);
  1294.         s.addActionListener(this);
  1295.         add(s);
  1296.         return panel;
  1297.     }
  1298.  
  1299.     public static void main(String[] args) {
  1300.         run(new InvulGrid(), 300, 300);
  1301.   }
  1302.  
  1303.     public static void run(JApplet applet, int width, int height) {
  1304.         JFrame frame = new JFrame();
  1305.         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  1306.         frame.getContentPane().add(applet);
  1307.         applet.init();
  1308.         applet.start();
  1309.         frame.setVisible(true);
  1310.     }
  1311.  
  1312.  
  1313. }
  1314.  
  1315.  
  1316. class DecimalPoint {
  1317.     int x,y;
  1318.     int linewidth;
  1319.     boolean editable;
  1320.    
  1321.     public DecimalPoint(int x,int y, int linewidth,boolean editable){
  1322.         this.x = x;
  1323.         this.y = y;
  1324.         this.linewidth = linewidth;
  1325.         this.editable = editable;
  1326.     }
  1327.    
  1328.     public int getX(){return x;}
  1329.     public int getY(){return y;}
  1330.     public int getD(){return linewidth;}
  1331.     public boolean getEditable(){return editable;}
  1332. }
  1333.  
  1334. class GridLine {
  1335.     int x1,y1,x2,y2;
  1336.     Color color;
  1337.     String txt;
  1338.     boolean edit;
  1339.     boolean segment;
  1340.  
  1341.     public GridLine(int x1, int y1 , int x2 , int y2, Color color, String txt,boolean edit, boolean segment){
  1342.         this.x1 = x1;
  1343.         this.y1 = y1;
  1344.         this.x2 = x2;
  1345.         this.y2 = y2;
  1346.         this.color = color;
  1347.         this.txt = txt;
  1348.         this.edit = edit;
  1349.         this.segment = segment;
  1350.    }
  1351.    public int getX1() { return x1; }
  1352.    public int getY1() { return y1; }
  1353.    public int getX2() { return x2; }
  1354.    public int getY2() { return y2; }
  1355.    public Color getColor(){ return color;}
  1356.    public String getText() { return txt;}
  1357.    public boolean getEdit() { return edit;}
  1358.    public boolean isSegment() { return segment;}
  1359. }
  1360.  
  1361.