Subversion Repositories wimsdev

Rev

Rev 3653 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*
  2. *********************************************************************************
  3. * J.M. Evers 19/11/2009                                                         *
  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 whatoever                                                         *
  8. *********************************************************************************
  9.  
  10. <html>
  11.     <head>test vrije invulveld</head>
  12.     <body>
  13.         <script language="javascript" type="text/javascript">                                                                                      
  14.             function READTHIS(){                                                                                                                          
  15.                 var reply=document.applets[0].ReadApplet(1);
  16.                 alert("the applet will send to wims:\n"+reply);
  17.             }                                                                                                                                        
  18.         </script>                                                                                                                                  
  19.      <center>
  20.         <applet code="VrijeInvulVeld.class" archive="VrijeInvulVeld.jar" width="640" height="480">
  21.             <param name="xsize" value="300">
  22.             <param name="ysize" value="300">
  23.             <param name="bgcolor" value="255,255,255">
  24.             <param name="textcolor" value="250,0,0">
  25.             <param name="drawcolor" value="0,250,10">
  26.             <param name="penthickness" value="2">
  27.             <param name="penfontsize" value="18">
  28.             <param name="penfontfamily" value="Helvetica">
  29.             <param name="penfontstyle" value="bold">
  30.             <param name="language" value="nl">
  31.             <param name="text" value="yes"> <!-- if 0/no no text -->
  32.             <param name="line" value="yes"> <!-- if 0/no no lines -->
  33.             <param name="rect" value="0"> <!-- if 0/no no rec -->
  34.             <param name="ellipse" value="0"> <!-- if 0/no no ellipse -->
  35.             <param name="arrow" value="0"> <!-- if 0/no no arrows -->
  36.             <param name="grid" value="yes"> <!-- will produce a grid -->
  37.             <param name="textlines" value="10"> <!-- number of lines in the applet: strings are bound to these lines leave blank or remove parma-tag to revert to original behaviour of the drawing applet -->
  38.             <param name="textalign" value="vertical"> <!-- probability tree orientation -->
  39.         </applet>
  40.         <input type="button" name=".....TEST......" value=".....TEST....." onclick="javascript:READTHIS();">
  41.       </center>
  42.     </body>
  43. </html>
  44. */
  45.  
  46. import java.util.*;
  47. import java.awt.*;
  48. import java.applet.*;
  49.  
  50.  
  51.  
  52. /* The applet itself; contains a display, a control panel and a diagram */
  53.  
  54. public class VrijeInvulVeld extends Applet {
  55.     Diagram diagram;
  56.     DiagramControls controls;
  57.     DiagramDisplay display;
  58.     MessageArea message;
  59.     EventConsumer current_event_consumer;
  60.  
  61. // jm.evers a few defaults...i'm no good at this java :(
  62.     static int xsize=640;
  63.     static int ysize=480;
  64.     static int ygrid=50;// default disabled : less than 50 "lines" of text enables the "snap to line"
  65.     static Color bgcolor=new Color(250,250,250);
  66.     static Color textcolor=new Color(255,0,0);
  67.     static Color drawcolor=new Color(150,0,250);
  68.     static float thickness=2.0f;
  69.     static int penfontsize=16;
  70.     static String fontfamily="Helvetica";
  71.     static Font penfont= new Font(fontfamily, Font.BOLD, penfontsize);                                                                        
  72.     static Font messagefont= new Font(fontfamily, Font.BOLD,16);                                                                        
  73.     public String t_line="Line";
  74.     public String t_arrow="Arrow";
  75.     public String t_rectangle="Rectangle";
  76.     public String t_ellipse="Ellipse";
  77.     public String t_text="Text";
  78.     public String t_circle="Circle";
  79.     public String t_destroy="Delete";
  80.     public String t_move="Move";
  81.     static String t_press="Press return to finish the text";
  82.     static boolean textalign=false; // horizontal [snap to y: sort to y] . otherwise vertical [snap to x:sort to x]
  83.     static int textcounter=0;
  84.     static int linecounter=0;
  85.     static boolean original=false;
  86.     static boolean draw_line=true;
  87.     static boolean draw_text=true;
  88.     static boolean draw_arrow=true;
  89.     static boolean draw_ellipse=true;
  90.     static boolean draw_rect=true;
  91.  
  92. //
  93.     public void init() {
  94.         String param;
  95.         param = getParameter("language");
  96.         if(param != null) {
  97.             if(param.equalsIgnoreCase("nl")){
  98.                 t_line="lijn";
  99.                 t_arrow="pijl";
  100.                 t_rectangle="rechthoek";
  101.                 t_ellipse="ellips";
  102.                 t_text="tekst";
  103.                 t_circle="cirkel";
  104.                 t_destroy="wissen";
  105.                 t_move="verplaatsen";
  106.                 t_press="Druk op enter als de tekst klaar is";
  107.             }
  108.             if(param.equalsIgnoreCase("de")){
  109.                 t_line="Linie";
  110.                 t_arrow="Pfeil";
  111.                 t_rectangle="Rechteck";
  112.                 t_ellipse="Ellipse";
  113.                 t_text="Text";
  114.                 t_circle="Kreis";
  115.                 t_destroy="löschen";
  116.                 t_move="verlagern";
  117.                 t_press="Drücken Sie auf \"Eingabe\" am Ende des Textes";
  118.             }
  119.             if(param.equalsIgnoreCase("fr")){
  120.                 t_line="droite";
  121.                 t_arrow="flèche";
  122.                 t_rectangle="rectangle";
  123.                 t_ellipse="ellips";
  124.                 t_text="texte";
  125.                 t_circle="cercle ";
  126.                 t_destroy="effacer";
  127.                 t_move="déplacer";
  128.                 t_press="Press return to finish the text";
  129.             }
  130.         }
  131.         param = getParameter("line");
  132.         if(param != null){if(param.equalsIgnoreCase("no") || param.equals("0")){draw_line=false;}}
  133.         param = getParameter("rect");
  134.         if(param != null){if(param.equalsIgnoreCase("no") || param.equals("0")){draw_rect=false;}}
  135.         param = getParameter("arrow");
  136.         if(param != null){if(param.equalsIgnoreCase("no") || param.equals("0")){draw_arrow=false;}}
  137.         param = getParameter("text");
  138.         if(param != null){if(param.equalsIgnoreCase("no") || param.equals("0")){draw_text=false;}}
  139.         param = getParameter("ellipse");
  140.         if(param != null){if(param.equalsIgnoreCase("no") || param.equals("0")){draw_ellipse=false;}}
  141.         param = getParameter("penfontsize");
  142.         if(param != null) {penfontsize=Integer.parseInt(param,10); penfont= new Font("Helvetica", Font.BOLD, penfontsize);}
  143.         param = getParameter("penfontfamily");
  144.         if(param != null) {penfont= new Font(param, Font.BOLD, penfontsize);}
  145.         param = getParameter("penfontstyle");
  146.         if(param != null) {
  147.             if(param.equalsIgnoreCase("bold")){penfont= new Font(param, Font.BOLD , penfontsize);}
  148.             else if(param.equalsIgnoreCase("italic")){penfont= new Font(param, Font.ITALIC , penfontsize);}
  149.             else if(param.equalsIgnoreCase("plain")){penfont= new Font(param, Font.PLAIN , penfontsize);}
  150.         }
  151.         param = getParameter("penthickness");
  152.         if(param != null) {thickness=Float.parseFloat(param);}
  153.         param = getParameter("xsize");
  154.         if(param != null) {xsize=Integer.parseInt(param,10);}
  155.         param = getParameter("ysize");
  156.         if(param != null) {ysize=Integer.parseInt(param,10);}
  157.         param = getParameter("textlines");
  158.         if(param != null) {ygrid=Integer.parseInt(param,10);
  159.             if(ygrid>100){ygrid=100;System.out.println("100 lines max !");}
  160.             if(ygrid<0){ygrid=10;System.out.println("positive number textlines !");}
  161.         }
  162.         param = getParameter("textalign");
  163.         if(param == null || param.length()==0){original=true;}else{original=false;if(param.equalsIgnoreCase("vertical")){textalign=true;}else{textalign=false;}}
  164.         resize(xsize,ysize);
  165.         param=getParameter("bgcolor"); // Background color of inputfield "input"
  166.         if (param != null && param.length()>0){bgcolor=ReturnColor(param);}
  167.         param=getParameter("textcolor"); // Background color of inputfield "input"
  168.         if (param != null && param.length()>0){textcolor=ReturnColor(param);}
  169.         param=getParameter("drawcolor"); // Background color of inputfield "input"
  170.         if (param != null && param.length()>0){drawcolor=ReturnColor(param);}
  171.        
  172.         diagram = new Diagram();
  173.         diagram.editor = this;
  174.         // no idea how to tell this class that the names are passed on as params in init...
  175.         add(controls = new DiagramControls(this ,t_line,t_arrow,t_rectangle,t_ellipse,t_text,t_circle,t_destroy,t_move));
  176.         add(display = new DiagramDisplay(this ,thickness,textcolor,drawcolor,penfont));
  177.         current_event_consumer = controls;
  178.        
  179.     }
  180.  
  181. // jm.evers
  182.  
  183.     public Color ReturnColor(String RGB){
  184.         int R=0;int G=0;int B=0;
  185.         RGB=RGB.replace(':',',');RGB=RGB.replace(';',',');
  186.         StringTokenizer q = new StringTokenizer(RGB, ",");
  187.         String k;int rgb;Color kleur;
  188.         for( int a=0; a<3 ; a++){
  189.             k=q.nextToken();
  190.             rgb=Integer.parseInt(k, 10);
  191.             if(rgb<0){rgb=0;}
  192.             if(rgb>255){rgb=255;}
  193.             if(a == 0){R = rgb;}
  194.             else if(a == 1){G = rgb;}
  195.             else if(a == 2){B = rgb;}
  196.         }
  197.         kleur=new Color(R,G,B);
  198.         return kleur;
  199.     }
  200.    
  201.     public String ReadApplet(String arg){
  202.         String reply="";
  203.         if(arg.equals("1")){
  204.             String line_analysis="";
  205.             int[] text_x=new int[textcounter];
  206.             int[] text_y=new int[textcounter];
  207.             int[] line_x1=new int[linecounter];
  208.             int[] line_y1=new int[linecounter];
  209.             int[] line_x2=new int[linecounter];
  210.             int[] line_y2=new int[linecounter];
  211.             String[] tekst=new String[textcounter];
  212.             int real_text_length=0;String tmp="";
  213.             int real_line_length=0;int x1;int x2;int y1;int y2;
  214.             for(Enumeration e = diagram.elements(); e.hasMoreElements(); ){                                                                            
  215.                 DiagramItem item = (DiagramItem)e.nextElement();
  216.                 if(item.specify_line_x1() != -1){
  217.                     x1=item.specify_line_x1();
  218.                     y1=item.specify_line_y1();
  219.                     x2=item.specify_line_x2();
  220.                     y2=item.specify_line_y2();
  221.                     if(textalign){//alleen horizontale lijnen
  222.                         if( x1 != x2 && y1 == y2){// avoid line-dots to be send as lines/branches
  223.                             line_x1[real_line_length] = x1;
  224.                             line_y1[real_line_length] = y1;
  225.                             line_x2[real_line_length] = x2;
  226.                             line_y2[real_line_length] = y2;
  227.                             real_line_length++;
  228.                             System.out.println("een horizontale lijn "+real_line_length);
  229.                         }
  230.                     }
  231.                     else
  232.                     {
  233.                         if( y1 != y2 && x1 == x2 ){// avoid line-dots to be send as lines/branches
  234.                             line_x1[real_line_length] = x1;
  235.                             line_y1[real_line_length] = y1;
  236.                             line_x2[real_line_length] = x2;
  237.                             line_y2[real_line_length] = y2;
  238.                             real_line_length++;
  239.                             System.out.println("een vertikale lijn "+real_line_length);
  240.                         }
  241.                     }
  242.                 }
  243.                 if(item.specify_text() != null){
  244.                     tmp = item.specify_text();
  245.                     // remove the forgotten '_' and we can't use komma's in the reply...replace them by points ?
  246.                     tmp =replace(tmp,"_"," ");
  247.                     tekst[real_text_length] =replace(tmp,",",".");
  248.                     text_x[real_text_length] = item.specify_text_x();
  249.                     text_y[real_text_length] = item.specify_text_y();
  250.                     real_text_length++;
  251.                 }
  252.             }
  253.            
  254.             boolean nog_meer = true;int i=0;int s=0;int temp_x;int temp_y;String temp_txt;
  255.             String[] sameline = new String[real_text_length];
  256.             FontMetrics fm =getFontMetrics(penfont);                                                                                      
  257.             int hoogte = fm.getMaxAscent();
  258.             if(textalign){//horizonal probability tree
  259.                 while (nog_meer) {
  260.                     nog_meer = false;
  261.                     for ( i=0; i<real_text_length-1; i++ ){
  262.                         if ( text_y[i] < text_y[i+1] ){ sameline[i]="\n";}
  263.                         if ( text_y[i] > text_y[i+1] ){
  264.                             temp_y = text_y[i]; text_y[i] = text_y[i+1];  text_y[i+1] = temp_y;
  265.                             temp_x = text_x[i];  text_x[i] = text_x[i+1];  text_x[i+1] = temp_x;
  266.                             temp_txt = tekst[i];  tekst[i] = tekst[i+1];  tekst[i+1] = temp_txt;
  267.                             nog_meer = true;
  268.                             sameline[i]="\n";
  269.                         }
  270.                         if ( text_y[i] == text_y[i+1] ){
  271.                             sameline[i]=" ";
  272.                             if( text_x[i] > text_x[i+1] ){
  273.                                 temp_y = text_y[i]; text_y[i] = text_y[i+1];  text_y[i+1] = temp_y;
  274.                                 temp_x = text_x[i]; text_x[i] = text_x[i+1];  text_x[i+1] = temp_x;
  275.                                 temp_txt = tekst[i]; tekst[i] = tekst[i+1];  tekst[i+1] = temp_txt;
  276.                                 nog_meer = true;
  277.                             }
  278.                         }
  279.                     }
  280.                 }
  281.             }
  282.             else
  283.             {//vertical probability tree
  284.                 while (nog_meer) {
  285.                     nog_meer = false;
  286.                     for ( i=0; i<real_text_length-1; i++ ){
  287.                         if ( text_x[i] < text_x[i+1] ){ sameline[i]="\n";}
  288.                         if ( text_x[i] > text_x[i+1] ){
  289.                             temp_y = text_y[i]; text_y[i] = text_y[i+1];  text_y[i+1] = temp_y;
  290.                             temp_x = text_x[i];  text_x[i] = text_x[i+1];  text_x[i+1] = temp_x;
  291.                             temp_txt = tekst[i];  tekst[i] = tekst[i+1];  tekst[i+1] = temp_txt;
  292.                             nog_meer = true;
  293.                             sameline[i]="\n";
  294.                         }
  295.                         if ( text_x[i] == text_x[i+1] ){
  296.                             sameline[i]=" ";
  297.                             if( text_y[i] > text_y[i+1] ){
  298.                                 temp_y = text_y[i]; text_y[i] = text_y[i+1];  text_y[i+1] = temp_y;
  299.                                 temp_x = text_x[i]; text_x[i] = text_x[i+1];  text_x[i+1] = temp_x;
  300.                                 temp_txt = tekst[i];  tekst[i] = tekst[i+1];  tekst[i+1] = temp_txt;
  301.                                 nog_meer = true;
  302.                             }
  303.                         }
  304.                     }
  305.                 }
  306.            
  307.             }
  308.             int wacht=0;
  309.             if(textalign){
  310.                 for(i=0;i<real_line_length;i++){
  311.                     y1=line_y1[i];
  312.                     for(s=0;s<real_text_length;s++){
  313.                         if(text_y[s]==y1 ||( text_y[s]<y1 && text_y[s]>y1-hoogte)){
  314.                             wacht=s;
  315.                         }
  316.                     }
  317.                     if(wacht!=0){
  318.                         sameline[wacht]="\n line \n";
  319.                         wacht=0;
  320.                     }
  321.                 }
  322.             }
  323.             else
  324.             {
  325.                 for(i=0;i<real_line_length;i++){
  326.                     x1=line_x1[i];
  327.                     x2=line_x2[i];
  328.                     y1=line_y1[i];
  329.                     y2=line_y2[1];
  330.                     if(x1<x2+hoogte && x1>x2-hoogte){
  331.                     // dus een "bijna vertikale lijn
  332.                         for(s=0;s<real_text_length;s++){
  333.                             if(text_y[s]==y1 ||( text_y[s]<y1 && text_y[s]>y1-hoogte)){
  334.                                 wacht=s;
  335.                             }
  336.                         }
  337.                         if(wacht!=0){
  338.                             sameline[wacht]="\n vertikale line \n";
  339.                             wacht=0;
  340.                         }
  341.                     }
  342.                 }
  343.             }
  344.  
  345.             for(i=0;i<real_text_length;i++){
  346.                 if(sameline[i] == null){sameline[i]="\n";}
  347.                 reply=reply+tekst[i]+sameline[i];
  348.             }
  349.         }
  350.         else
  351.         {
  352.             //alldata...no special sorting of the text
  353.             for(Enumeration e = diagram.elements(); e.hasMoreElements(); ){                                                                            
  354.                 DiagramItem item = (DiagramItem)e.nextElement();
  355.                 reply=reply+item.describe()+"\n";
  356.             }
  357.         }
  358.  
  359.         return reply;
  360.     }
  361.    
  362.     // replace compatible with java 1.4  [B. Perrin-Riou]
  363.     public static String replace(String source, String pattern, String replace){
  364.         if (source!=null){
  365.             final int len = pattern.length();
  366.             StringBuffer sb = new StringBuffer();
  367.             int found = -1;
  368.             int start = 0;
  369.             while( (found = source.indexOf(pattern, start) ) != -1){
  370.                 sb.append(source.substring(start, found));
  371.                 sb.append(replace);
  372.                 start = found + len;
  373.             }
  374.             sb.append(source.substring(start));
  375.             return sb.toString();
  376.         }
  377.         else return "";
  378.     }
  379.  
  380.     public void start() {
  381.     }
  382.  
  383.     public void stop() {
  384.     }
  385.  
  386.     public void destroy() {
  387.     }
  388.  
  389.     public static void main(String argv[]) {
  390.         /* This more-or-less replicates what happens when we  are run as an applet. */
  391.         Frame f = new Frame();
  392.         VrijeInvulVeld d = new VrijeInvulVeld();
  393.         d.init();
  394.         d.start();
  395.         f.add("Center", d);
  396.         f.show();
  397.     }
  398. }
  399. /* end applet */
  400.  
  401.  
  402.  
  403. /* The diagram */
  404.  
  405. class Diagram extends Vector {
  406.     VrijeInvulVeld editor;
  407.     DiagramItem nearby(int x, int y){
  408.         DiagramItem bestitem = null;
  409.         double bestdist = 6;
  410.         for(Enumeration e = elements(); e.hasMoreElements(); ) {
  411.             DiagramItem item = (DiagramItem)e.nextElement();
  412.             double dist = item.distance(x, y);
  413.             if(dist < bestdist) {
  414.                 bestitem = item;
  415.                 bestdist = dist;
  416.             }
  417.         }
  418.         return bestitem;
  419.     }
  420. }
  421.  
  422.  
  423. /* The drawing area */
  424.  
  425. class DiagramDisplay extends Canvas {
  426.     VrijeInvulVeld editor;
  427.     DiagramDisplay(VrijeInvulVeld ed , float thickness,Color textcolor,Color drawcolor, Font penfont){
  428.         editor = ed;
  429.         setBackground(VrijeInvulVeld.bgcolor);
  430.         resize(VrijeInvulVeld.xsize,VrijeInvulVeld.ysize);
  431.     }
  432.  
  433.  
  434.     public void paint(Graphics g) {
  435.         Graphics2D g2 = (Graphics2D) g;                                                                                                                    
  436.         g2.setFont(VrijeInvulVeld.penfont);    
  437.         g2.setStroke( new BasicStroke(VrijeInvulVeld.thickness));
  438.         g2.setColor(VrijeInvulVeld.drawcolor);
  439.         for(Enumeration e = editor.diagram.elements(); e.hasMoreElements(); ) {
  440.             ((DiagramItem)e.nextElement()).draw(g2);
  441.         }
  442.     }
  443.    
  444.  
  445.     public boolean mouseDown(Event e, int x, int y){
  446.         if(editor.current_event_consumer.down(x, y)){
  447.             repaint();
  448.             return true;
  449.         }
  450.         else
  451.         {
  452.             return false;
  453.         }
  454.     }
  455.  
  456.     public boolean mouseUp(Event e, int x, int y){
  457.         if(editor.current_event_consumer.up(x, y)){
  458.             repaint();
  459.             return true;
  460.         }
  461.         else
  462.         {
  463.             return false;
  464.         }
  465.     }
  466.  
  467.     public boolean mouseDrag(Event e, int x, int y){
  468.         if(editor.current_event_consumer.drag(x, y)){
  469.             repaint();
  470.             return true;
  471.         }
  472.         else
  473.         {
  474.             return false;
  475.         }
  476.     }
  477.  
  478.     public boolean keyDown(Event e, int key){
  479.         if(editor.current_event_consumer.key(key)){
  480.             repaint();
  481.             return true;
  482.         }
  483.         else
  484.         {
  485.             return false;
  486.         }
  487.     }
  488. }
  489.  
  490. /* The control panel and the diagram items do things in response to input */
  491.  
  492. interface EventConsumer {
  493.     public boolean down(int x, int y);
  494.     public boolean up(int x, int y);
  495.     public boolean drag(int x, int y);
  496.     public boolean key(int key);
  497.     public void yield();
  498. }
  499.  
  500. /* The control panel */
  501.  
  502. class DiagramControls extends Panel implements EventConsumer {
  503.     VrijeInvulVeld editor;
  504.     CheckboxGroup buttons;
  505.     Checkbox line, arrow, rect, ellipse, text, destroy, move;
  506.     final int CREATE = 0, DESTROY = 1, MOVE = 2;
  507.    
  508.  
  509.     DiagramControls( VrijeInvulVeld ed ,String t_line,String t_arrow,String t_rectangle,String t_ellipse,String t_text,String t_circle,String t_destroy,String t_move) {
  510.         editor = ed;
  511.         setBackground(Color.white);
  512.         GridBagLayout gridbag = new GridBagLayout();
  513.         GridBagConstraints c = new GridBagConstraints();
  514.         Component button;
  515.         setLayout(gridbag);
  516.         buttons = new CheckboxGroup();
  517.         c.gridy = 0;
  518.         c.gridx = 0;
  519.         c.fill = GridBagConstraints.HORIZONTAL;
  520.         c.weightx = 1;
  521.         c.anchor = GridBagConstraints.CENTER;
  522.         if(VrijeInvulVeld.draw_text){
  523.             button = new DiagramControl(this, CREATE, (new Text()).getClass(), t_text ,  true);
  524.             gridbag.setConstraints(button, c);add(button);c.gridx++;
  525.         }
  526.         if(VrijeInvulVeld.draw_line){
  527.             button = new DiagramControl(this, CREATE, (new Line()).getClass(), t_line ,  false);
  528.             gridbag.setConstraints(button, c);add(button);c.gridx++;
  529.         }
  530.         if(VrijeInvulVeld.draw_arrow){
  531.             button = new DiagramControl(this, CREATE, (new Arrow()).getClass(), t_arrow ,  false);
  532.             gridbag.setConstraints(button, c);add(button);c.gridx++;
  533.         }
  534.         if(VrijeInvulVeld.draw_rect){
  535.             button = new DiagramControl(this, CREATE, (new Rect()).getClass(), t_rectangle, false);
  536.             gridbag.setConstraints(button, c);add(button);c.gridx++;
  537.         }
  538.         if(VrijeInvulVeld.draw_ellipse){
  539.             button = new DiagramControl(this, CREATE, (new Ellipse()).getClass(), t_ellipse , false);
  540.             gridbag.setConstraints(button, c);add(button);c.gridx++;
  541.         }
  542.         button = new DiagramControl(this, MOVE, (new Object()).getClass(), t_move ,    false);
  543.         gridbag.setConstraints(button, c);
  544.         add(button);
  545.         c.gridx++;
  546.         button = new DiagramControl(this, DESTROY, (new Object()).getClass(), t_destroy  , false);
  547.         gridbag.setConstraints(button, c);
  548.         add(button);
  549.  
  550.     }
  551.     public boolean down(int x, int y) {
  552.         DiagramControl current_button = (DiagramControl)buttons.getCurrent();
  553.         DiagramItem target;
  554.         Diagram diagram = editor.diagram;
  555.         editor.showStatus("");
  556.         switch(current_button.mode) {
  557.             case CREATE:
  558.             try {
  559.                 Class class_ = current_button.class_;
  560.                 target = (DiagramItem)class_.newInstance();
  561.                 target.diagram = diagram;
  562.                 target.create();
  563.                 editor.current_event_consumer = target;
  564.                 diagram.addElement(target);
  565.                 target.down(x, y);
  566.             }
  567.             catch (InstantiationException ex) {}
  568.             catch (IllegalAccessException ex) {}
  569.             return true;
  570.            
  571.             case DESTROY:
  572.             target = diagram.nearby(x, y);
  573.             if(target != null) {diagram.removeElement(target);target.destroy();}
  574.             return true;
  575.            
  576.             case MOVE:
  577.             target = diagram.nearby(x, y);
  578.             if(target != null) {target.move();editor.current_event_consumer = target;target.down(x, y);}
  579.             return false;
  580.            
  581.             default:
  582.             return false;
  583.         }
  584.     }
  585.  
  586.     public boolean up(int x, int y) {
  587.         return false;
  588.     }
  589.  
  590.     public boolean drag(int x, int y) {
  591.         return false;
  592.     }
  593.  
  594.     public boolean key(int key) {
  595.         return false;
  596.     }
  597.  
  598.     public boolean keyDown(Event e, int key) {
  599.         /* For some reason we get the canvas key presses.  Pass them on XXX */
  600.         return editor.display.keyDown(e, key);
  601.     }
  602.  
  603.     public void yield() {}
  604. }
  605.  
  606. /* The buttons in the control panel */
  607.  
  608. class DiagramControl extends Checkbox {
  609.     int mode;
  610.     Class class_;
  611.     DiagramControl(DiagramControls parent, int _mode, Class _class, String label, boolean state) {
  612.         super(label, parent.buttons, state);
  613.         mode = _mode;
  614.         class_ = _class;
  615.     }
  616. }
  617.  
  618.  
  619. /* The diagram items.
  620.  * The methods implemented here are suitable for shapes defined by two
  621.  * points (ends of a line, corners of an ellipse's bounding box).  Other
  622.  * shapes should override.  Maybe I should use a subclass for this, but
  623.  * some of the methods may be useful for other shapes (text could use
  624.  * these methods for moving but not creating; it would be nice to store the
  625.  * state just by switching the methods).
  626.  */
  627.  
  628. abstract class DiagramItem implements EventConsumer {
  629.     Diagram diagram;
  630.     int state;
  631.     final int NONE=0, CREATE=1, MOVE=2;
  632.     int x, y, w, h;
  633.     int movex, movey;
  634.     DiagramItem() {
  635.         x = y = w = h = 0;
  636.     }
  637.  
  638.     DiagramItem(StringTokenizer tok) throws Exception {
  639.         if(tok.countTokens() != 4)
  640.         throw new IllegalArgumentException();
  641.         x = (new Integer(tok.nextToken())).intValue();
  642.         y = (new Integer(tok.nextToken())).intValue();
  643.         w = (new Integer(tok.nextToken())).intValue();
  644.         h = (new Integer(tok.nextToken())).intValue();
  645.     }
  646.  
  647.     abstract void draw(Graphics g);
  648.     abstract String describe();
  649.     abstract String specify_text();
  650.     abstract int specify_text_x();
  651.     abstract int specify_text_y();
  652.     abstract int specify_line_x1();
  653.     abstract int specify_line_y1();
  654.     abstract int specify_line_x2();
  655.     abstract int specify_line_y2();
  656.  
  657.     void create() {
  658.         state = CREATE;
  659.     }
  660.  
  661.     public void yield() {
  662.         diagram.editor.current_event_consumer = diagram.editor.controls;
  663.         state = NONE;
  664.     }
  665.  
  666.     void destroy() {}
  667.  
  668.     void move() {
  669.         state = MOVE;
  670.     }
  671.  
  672.     public boolean down(int _x, int _y) {
  673.         switch(state){
  674.             case CREATE:
  675.             x = _x; y = _y;
  676.             return true;
  677.            
  678.             case MOVE:
  679.             movex = _x; movey = _y;
  680.             return true;
  681.         }
  682.         return false;
  683.     }
  684.  
  685.     public boolean up(int _x, int _y) {
  686.         switch(state){
  687.             case CREATE:
  688.             w = _x - x; h = _y - y;
  689.             yield();
  690.             return true;
  691.            
  692.             case MOVE:
  693.             x += (_x - movex);
  694.             y += (_y - movey);
  695.             yield();
  696.             return true;
  697.         }
  698.         return false;
  699.     }
  700.  
  701.     public boolean drag(int _x, int _y) {
  702.         switch(state){
  703.             case CREATE:
  704.             w = _x - x; h = _y - y;
  705.             return true;
  706.        
  707.             case MOVE:
  708.             x += (_x - movex);
  709.             y += (_y - movey);
  710.             movex = _x;
  711.             movey = _y;
  712.             return true;
  713.         }
  714.         return false;
  715.     }
  716.  
  717.     public boolean key(int key) {
  718.         return false;
  719.     }
  720.  
  721.     abstract double distance(int x, int y);
  722. }
  723.  
  724. class Ellipse extends DiagramItem {
  725.     Ellipse(){super();}
  726.     Ellipse(StringTokenizer tok) throws Exception {super(tok);}
  727.     String describe() {return "ellipse," + x + "," + y + "," + w + "," + h;}
  728.     String specify_text() {return null; }
  729.     int specify_text_x() {return -1; }
  730.     int specify_text_y() {return -1; }
  731.     int specify_line_x1(){return -1;}
  732.     int specify_line_y1(){return -1;}
  733.     int specify_line_x2(){return -1;}
  734.     int specify_line_y2(){return -1;}
  735.     void draw(Graphics g) {
  736.         g.drawOval(x, y, w, h);
  737.     }
  738.     double distance(int _x, int _y) {
  739.         /* Do this better! */
  740.         float ww = w < 1 ? 1 : w, hh = h < 1 ? 1 : h;
  741.         float yscale = ww/hh;
  742.         float xx = _x - (x + ww / 2);
  743.         float yy = (_y - (y + hh / 2)) * yscale;
  744.         double r = Math.sqrt(xx * xx + yy * yy);
  745.         return Math.abs(r - ww / 2);
  746.     }
  747. }
  748.  
  749. /* The class name Rectangle is already taken :-( */
  750.  
  751. class Rect extends DiagramItem {
  752.     Rect(){super();}
  753.     Rect(StringTokenizer tok) throws Exception { super(tok);}
  754.  
  755.     String describe() {return "rectangle," + x + "," + y + "," + (x+w) + "," + (y+h);}
  756.     String specify_text() {return null; }
  757.     int specify_text_x() {return -1; }
  758.     int specify_text_y() {return -1; }
  759.     int specify_line_x1(){return -1;}
  760.     int specify_line_y1(){return -1;}
  761.     int specify_line_x2(){return -1;}
  762.     int specify_line_y2(){return -1;}
  763.  
  764.     void draw(Graphics g) {
  765.         g.drawLine(x  , y  , x+w, y  );
  766.         g.drawLine(x+w, y  , x+w, y+h);
  767.         g.drawLine(x+w, y+h, x  , y+h);
  768.         g.drawLine(x  , y+h, x  , y  );
  769.     }
  770.  
  771.     double distance(int _x, int _y) {
  772.         double dtop, dbottom, dleft, dright, dist;
  773.         if(_x < x){
  774.             dtop = Misc.distance(_x, _y, x, y);
  775.         }
  776.         else
  777.         {
  778.             if(_x > x+w){
  779.                 dtop = Misc.distance(_x, _y, x+w, y);
  780.             }
  781.             else
  782.             {
  783.                 dtop = Math.abs(_y - y);
  784.             }
  785.         }    
  786.    
  787.         if(_x < x){
  788.             dbottom = Misc.distance(_x, _y, x, y+h);
  789.         }
  790.         else
  791.         {
  792.             if(_x > x+w){
  793.                 dbottom = Misc.distance(_x, _y, x+w, y+h);
  794.             }
  795.             else
  796.             {
  797.                 dbottom = Math.abs(_y - (y+h));
  798.             }
  799.         }
  800.        
  801.         if(_y < y)
  802.             dleft = Misc.distance(_x, _y, x, y);
  803.         else if(_y > y+h)
  804.             dleft = Misc.distance(_x, _y, x, y+h);
  805.         else
  806.             dleft = Math.abs(_x - x);
  807.    
  808.         if(_y < y)
  809.             dright = Misc.distance(_x, _y, x+w, y);
  810.         else if(_y > y+h)
  811.             dright = Misc.distance(_x, _y, x+w, y+h);
  812.         else
  813.             dright = Math.abs(_x - (x+w));
  814.  
  815.         dist = dtop;
  816.         if(dbottom < dist){dist = dbottom;}
  817.         if(dleft < dist){dist = dleft;}
  818.         if(dright < dist){dist = dright;}
  819.        
  820.         return dist;
  821.     }
  822. }
  823.  
  824. class Line extends DiagramItem {
  825.     Line() {super();}
  826.     Line(StringTokenizer tok) throws Exception {super(tok);}
  827.     void draw(Graphics g) {
  828.         Graphics2D g2 = (Graphics2D) g;
  829.         if(!VrijeInvulVeld.original){
  830.             int dy=(int) VrijeInvulVeld.ysize / VrijeInvulVeld.ygrid;
  831.             int dx=(int) VrijeInvulVeld.xsize / VrijeInvulVeld.ygrid;
  832.             if(state != 2){
  833.                 y=dy*((int) Math.round(y/dy));
  834.                 h=dy*((int) Math.round(h/dy));
  835.             }
  836.             if(state == 1 || state == 2){
  837.                 g2.setColor(VrijeInvulVeld.textcolor);
  838.                 g2.setStroke( new BasicStroke(1.0f));
  839.                 if(VrijeInvulVeld.textalign){
  840.                     for(int p=0;p<VrijeInvulVeld.ysize;p=p+dy){
  841.                         g2.drawLine(0,p,VrijeInvulVeld.xsize,p);
  842.                     }
  843.                 }
  844.                 else
  845.                 {
  846.                     for(int p=0;p<VrijeInvulVeld.xsize;p=p+dx){
  847.                         g2.drawLine(p,0,p,VrijeInvulVeld.ysize);
  848.                     }      
  849.                 }
  850.             }
  851.         }
  852.         g2.setColor(VrijeInvulVeld.drawcolor);
  853.         g2.setStroke( new BasicStroke(VrijeInvulVeld.thickness));
  854.         g2.drawLine(x, y, x+w, y+h);
  855.         VrijeInvulVeld.linecounter++;
  856.     }
  857.     String describe() {return "line," + x + "," + y + "," + (x+w) + "," + (y+h);}
  858.     String specify_text() {return null; }
  859.     int specify_text_x(){return -1; }
  860.     int specify_text_y(){return -1; }
  861.     int specify_line_x1(){return x;}
  862.     int specify_line_y1(){return y;}
  863.     int specify_line_x2(){return (x+w);}
  864.     int specify_line_y2(){return (y+h);}
  865.  
  866.     double distance(int _x, int _y) {
  867.         if(w == 0 && h == 0)
  868.         return Misc.distance(x, y, _x, _y);
  869.         /* Set origin to end of line */
  870.         _x -= x;
  871.         _y -= y;
  872.         /* Find line length and unit vector along line */
  873.         double len = Math.sqrt(w*w + h*h);
  874.         double u = w / len;
  875.         double v = h / len;
  876.         /* Find nearest point on line using dot product */
  877.         double r = _x * u + _y * v;
  878.         if(r < 0)
  879.             return Misc.distance(0, 0, _x, _y);
  880.         if(r > len)
  881.             return Misc.distance(w, h, _x, _y);
  882.             return Misc.distance(r * u, r * v, _x, _y);
  883.     }
  884. }
  885.  
  886. class Arrow extends Line {
  887.     Arrow(){super();}
  888.     Arrow(StringTokenizer tok) throws Exception { super(tok);}
  889.     void draw(Graphics g) {
  890.         /* Draw a line */
  891.         Graphics2D g2 = (Graphics2D) g;
  892.         if(!VrijeInvulVeld.original){
  893.             int dy=(int) VrijeInvulVeld.ysize / VrijeInvulVeld.ygrid;
  894.             int dx=(int) VrijeInvulVeld.xsize / VrijeInvulVeld.ygrid;
  895.             if( state != 2){
  896.                 y=dy*((int) Math.round(y/dy));
  897.                 h=dy*((int) Math.round(h/dy));
  898.             }
  899.             if(state == 1 || state == 2){
  900.                 g2.setColor(VrijeInvulVeld.textcolor);
  901.                 g2.setStroke( new BasicStroke(1.0f));
  902.                 if(VrijeInvulVeld.textalign){
  903.                     for(int p=0;p<VrijeInvulVeld.ysize;p=p+dy){
  904.                         g2.drawLine(0,p,VrijeInvulVeld.xsize,p);
  905.                     }
  906.                 }
  907.                 else
  908.                 {
  909.                     for(int p=0;p<VrijeInvulVeld.xsize;p=p+dx){
  910.                         g2.drawLine(p,0,p,VrijeInvulVeld.ysize);
  911.                     }      
  912.                 }
  913.             }
  914.         }
  915.            
  916.         VrijeInvulVeld.linecounter++;
  917.         g2.setColor(VrijeInvulVeld.drawcolor);
  918.         g2.setStroke( new BasicStroke(VrijeInvulVeld.thickness));
  919.         g2.drawLine(x, y, x+w, y+h);
  920.         if(w == 0 && h == 0){return;}
  921.        
  922.         /* Find unit vector along line */
  923.         double len = Math.sqrt(w*w + h*h);
  924.         double u = w / len;
  925.         double v = h / len;
  926.  
  927.         /* Draw arrow head */
  928.         double _x = x + w - 5 * u;
  929.         double _y = y + h - 5 * v;
  930.         g2.drawLine(x+w, y+h, (int)(_x - 5 * v + 0.5), (int)(_y + 5 * u + 0.5));
  931.         g2.drawLine(x+w, y+h, (int)(_x + 5 * v + 0.5), (int)(_y - 5 * u + 0.5));
  932.     }
  933.        
  934.     String describe() {return "arrow," + x + "," + y + "," + (x+w) + "," +(y+h);}
  935.     String specify_text() {return null; }
  936.     int specify_text_x() {return -1; }
  937.     int specify_text_y() {return -1; }
  938.     int specify_line_x1(){return x;}
  939.     int specify_line_y1(){return y;}
  940.     int specify_line_x2(){return (x+w);}
  941.     int specify_line_y2(){return (y+h);}
  942.  
  943. }
  944.  
  945. class Text extends DiagramItem {
  946.     String text;
  947.     StringBuffer buffer;
  948.     Text() {
  949.         x = y = 0;
  950.         buffer = new StringBuffer();
  951.         text = buffer.toString().concat("_");
  952.     }
  953.  
  954.     Text(StringTokenizer tok) throws Exception {
  955.         if(tok.countTokens() < 1){throw new IllegalArgumentException();}
  956.             x = (new Integer(tok.nextToken())).intValue();
  957.             y = (new Integer(tok.nextToken())).intValue();
  958.             text = tok.nextToken("\n\r").trim();
  959.  
  960.     }
  961.  
  962.     void create() {
  963.         super.create();
  964.         diagram.editor.controls.disable();
  965.         //diagram.editor.showStatus("Press return to finish string");
  966.         diagram.editor.showStatus(VrijeInvulVeld.t_press);
  967.         VrijeInvulVeld.textcounter++;
  968.     }
  969.  
  970.     public void yield() {
  971.         super.yield();
  972.         diagram.editor.controls.enable();
  973.         text = buffer.toString();
  974.     }
  975.  
  976.     String describe() {
  977.         return "text," + x + "," + y + "," + text;
  978.     }
  979.     String specify_text() {return text; }
  980.     int specify_text_x() {return x; }
  981.     int specify_text_y() {return y; }
  982.     int specify_line_x1(){return -1;}
  983.     int specify_line_y1(){return -1;}
  984.     int specify_line_x2(){return -1;}
  985.     int specify_line_y2(){return -1;}
  986.    
  987.  
  988.     void draw(Graphics g) {
  989.     //jm.evers
  990.         if(!VrijeInvulVeld.original){
  991.             Graphics2D g2 = (Graphics2D) g;
  992.             int dy=(int) VrijeInvulVeld.ysize / VrijeInvulVeld.ygrid;
  993.             int dx=(int) VrijeInvulVeld.xsize / VrijeInvulVeld.ygrid;
  994.             if(state == 1 || state == 2){//show a temp grid lines
  995.                 g2.setColor(VrijeInvulVeld.drawcolor);
  996.                 g2.setStroke( new BasicStroke(1.0f));
  997.                 if(VrijeInvulVeld.textalign){for(int p=0;p<VrijeInvulVeld.ysize;p=p+dy){g2.drawLine(0,p,VrijeInvulVeld.xsize,p);}}
  998.                 else{for(int p=0;p<VrijeInvulVeld.xsize;p=p+dx){g2.drawLine(p,0,p,VrijeInvulVeld.ysize);}}
  999.                 g2.setFont(VrijeInvulVeld.penfont);    
  1000.             }
  1001.             else
  1002.             {
  1003.                 g2.setFont(VrijeInvulVeld.penfont);    
  1004.             }
  1005.             if(state != 2){ // not while dragging
  1006.                 if(VrijeInvulVeld.ygrid<50 && VrijeInvulVeld.ygrid>1){
  1007.                     if(VrijeInvulVeld.textalign){// then snap to the nearest vertical line...
  1008.                         y=dy*((int) (Math.round(y/dy)));
  1009.                         if(y<dy){y=dy;}
  1010.                         if(y>VrijeInvulVeld.ysize-dy){y=VrijeInvulVeld.ysize-dy;}
  1011.                     }
  1012.                     else
  1013.                     {//snap to the nearest horizontal line...
  1014.                         x=dx*((int) (Math.round(x/dx)));
  1015.                         if(x<dx){x=dx;}
  1016.                         if(x>VrijeInvulVeld.xsize-dx){x=VrijeInvulVeld.xsize-dx;}
  1017.                     }
  1018.                 }
  1019.             }
  1020.             g2.setColor(VrijeInvulVeld.textcolor);
  1021.             g2.setStroke( new BasicStroke(VrijeInvulVeld.thickness));
  1022.             g2.drawString(text, x, y);
  1023.             g2.setColor(VrijeInvulVeld.drawcolor);
  1024.         }
  1025.         else
  1026.         {
  1027.             g.drawString(text, x, y);
  1028.         }
  1029.     }
  1030.     double distance(int _x, int _y) {
  1031.         FontMetrics fm = diagram.editor.display.getGraphics().getFontMetrics();
  1032.         int m = y - (fm.getAscent() / 2);
  1033.         if(_x < x){return Misc.distance(x, m, _x, _y);}
  1034.         int r = x + fm.stringWidth(text);
  1035.         if(_x > r){return Misc.distance(r, m, _x, _y);}
  1036.         return Math.abs(_y - m);
  1037.     }
  1038.  
  1039.     public boolean down(int _x, int _y) {
  1040.         switch(state) {
  1041.             case CREATE:
  1042.             x = _x; y = _y;
  1043.             return true;
  1044.            
  1045.             case MOVE:
  1046.             return super.down(_x, _y);
  1047.         }
  1048.         return false;
  1049.     }
  1050.  
  1051.     public boolean up(int _x, int _y) {
  1052.         switch(state) {
  1053.             case CREATE:
  1054.             x = _x; y = _y;
  1055.             return true;
  1056.            
  1057.             case MOVE:
  1058.             return super.up(_x, _y);    
  1059.         }
  1060.         return false;
  1061.     }
  1062.  
  1063.     public boolean drag(int _x, int _y) {
  1064.         switch(state) {
  1065.             case CREATE:
  1066.             x = _x; y = _y;
  1067.             return true;
  1068.            
  1069.             case MOVE:
  1070.             return super.drag(_x, _y);
  1071.         }
  1072.         return false;
  1073.     }
  1074.  
  1075.     public boolean key(int key) {
  1076.         char c[] = new char[1];
  1077.         switch(state) {
  1078.             case CREATE:
  1079.             switch(key) {
  1080.                 case 10:/* LF */
  1081.  
  1082.                 case 13:/* CR */
  1083.                 yield();
  1084.                 if(text.equals("")){
  1085.                     diagram.removeElement(this);
  1086.                     destroy();
  1087.                     diagram.editor.showStatus("String was empty");
  1088.                 }
  1089.                 else
  1090.                     diagram.editor.showStatus("");
  1091.                     return true;
  1092.                
  1093.                 case 8:/* BS */
  1094.                 case 127:/* DEL */
  1095.                 int l = buffer.length();
  1096.             if(l > 0)
  1097.                 buffer.setLength(l - 1);
  1098.                 break;
  1099.    
  1100.                 default:
  1101.                 buffer.append((char)key);
  1102.                 break;
  1103.             }
  1104.             text = buffer.toString().concat("_");
  1105.             return true;
  1106.         }
  1107.         return false;
  1108.     }
  1109. }
  1110.  
  1111. /* An area for displaying messages */
  1112.  
  1113. class MessageArea extends Canvas {
  1114.     String text = "";
  1115.     void setText(String s) {
  1116.         text = s;
  1117.         repaint();
  1118.     }
  1119.  
  1120.     public void paint(Graphics g) {
  1121.         setBackground(VrijeInvulVeld.bgcolor);
  1122.         //g.setFont(VrijeInvulVeld.messagefont);    
  1123.         g.drawString(text,5,20);
  1124.     }
  1125. }
  1126.  
  1127.  
  1128. /* Handy functions */
  1129.  
  1130. class Misc {
  1131.     static double distance(double x1, double y1, double x2, double y2) {
  1132.         return Math.sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
  1133.     }
  1134. }
  1135.