Subversion Repositories wimsdev

Rev

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