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