Back to index

wims  3.65+svn20090927
VrijeInvulVeld.java
Go to the documentation of this file.
00001 /*
00002 <html>
00003     <head>test vrije invulveld</head>
00004     <body>
00005        <script language="javascript" type="text/javascript">                                                                                      
00006            function READTHIS(){                                                                                                                           
00007               var reply=document.applets[0].ReadApplet(1);
00008                alert("the applet will send to wims:\n"+reply);
00009            }                                                                                                                                         
00010        </script>                                                                                                                                  
00011      <center>
00012        <applet code="VrijeInvulVeld.class" archive="VrijeInvulVeld.jar" width="640" height="480">
00013            <param name="xsize" value="300">
00014            <param name="ysize" value="300">
00015            <param name="bgcolor" value="255,255,255">
00016            <param name="textcolor" value="250,0,0">
00017            <param name="drawcolor" value="0,250,10">
00018            <param name="penthickness" value="2">
00019            <param name="penfontsize" value="18">
00020            <param name="penfontfamily" value="Helvetica">
00021            <param name="penfontstyle" value="bold">
00022            <param name="language" value="nl">
00023            <param name="text" value="yes"> <!-- if 0/no no text -->
00024            <param name="line" value="yes"> <!-- if 0/no no lines -->
00025            <param name="rect" value="0"> <!-- if 0/no no rec -->
00026            <param name="ellipse" value="0"> <!-- if 0/no no ellipse -->
00027            <param name="arrow" value="0"> <!-- if 0/no no arrows -->
00028            <param name="grid" value="yes"> <!-- will produce a grid -->
00029            <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 -->
00030            <param name="textalign" value="vertical"> <!-- probability tree orientation --> 
00031        </applet>
00032        <input type="button" name=".....TEST......" value=".....TEST....." onclick="javascript:READTHIS();">
00033       </center>
00034     </body>
00035 </html>
00036 */
00037 
00038 import java.util.*;
00039 import java.awt.*;
00040 import java.applet.*;
00041 
00042 
00043 
00044 /* The applet itself; contains a display, a control panel and a diagram */
00045 
00046 public class VrijeInvulVeld extends Applet {
00047     Diagram diagram;
00048     DiagramControls controls;
00049     DiagramDisplay display;
00050     MessageArea message;
00051     EventConsumer current_event_consumer;
00052 
00053 // jm.evers a few defaults...i'm no good at this java :(
00054     static int xsize=640;
00055     static int ysize=480;
00056     static int ygrid=50;// default disabled : less than 50 "lines" of text enables the "snap to line"
00057     static Color bgcolor=new Color(250,250,250);
00058     static Color textcolor=new Color(255,0,0);
00059     static Color drawcolor=new Color(150,0,250);
00060     static float thickness=2.0f;
00061     static int penfontsize=16;
00062     static String fontfamily="Helvetica";
00063     static Font penfont= new Font(fontfamily, Font.BOLD, penfontsize);                                                                         
00064     static Font messagefont= new Font(fontfamily, Font.BOLD,16);                                                                         
00065     public String t_line="Line";
00066     public String t_arrow="Arrow";
00067     public String t_rectangle="Rectangle";
00068     public String t_ellipse="Ellipse";
00069     public String t_text="Text";
00070     public String t_circle="Circle";
00071     public String t_destroy="Delete";
00072     public String t_move="Move";
00073     static String t_press="Press return to finish the text";
00074     static boolean textalign=false; // horizontal [snap to y: sort to y] . otherwise vertical [snap to x:sort to x]
00075     static int textcounter=0;
00076     static int linecounter=0;
00077     static boolean original=false;
00078     static boolean draw_line=true;
00079     static boolean draw_text=true;
00080     static boolean draw_arrow=true;
00081     static boolean draw_ellipse=true;
00082     static boolean draw_rect=true;
00083 
00084 //
00085     public void init() {
00086        String param;
00087        param = getParameter("language");
00088        if(param != null) {
00089            if(param.equalsIgnoreCase("nl")){
00090               t_line="lijn";
00091               t_arrow="pijl";
00092               t_rectangle="rechthoek";
00093               t_ellipse="ellips";
00094               t_text="tekst";
00095               t_circle="cirkel";
00096               t_destroy="wissen";
00097               t_move="verplaatsen";
00098               t_press="Druk op enter als de tekst klaar is";
00099            }
00100            if(param.equalsIgnoreCase("de")){
00101               t_line="Linie";
00102               t_arrow="Pfeil";
00103               t_rectangle="Rechteck";
00104               t_ellipse="Ellipse";
00105               t_text="Text";
00106               t_circle="Kreis";
00107               t_destroy="löschen";
00108               t_move="verlagern";
00109               t_press="Drücken Sie auf \"Eingabe\" am Ende des Textes";
00110            }
00111            if(param.equalsIgnoreCase("fr")){
00112               t_line="droite";
00113               t_arrow="flèche";
00114               t_rectangle="rectangle";
00115               t_ellipse="ellips";
00116               t_text="texte";
00117               t_circle="cercle ";
00118               t_destroy="effacer";
00119               t_move="déplacer";
00120               t_press="Press return to finish the text";
00121            }
00122        }
00123        param = getParameter("line");
00124        if(param != null){if(param.equalsIgnoreCase("no") || param.equals("0")){draw_line=false;}}
00125        param = getParameter("rect");
00126        if(param != null){if(param.equalsIgnoreCase("no") || param.equals("0")){draw_rect=false;}}
00127        param = getParameter("arrow");
00128        if(param != null){if(param.equalsIgnoreCase("no") || param.equals("0")){draw_arrow=false;}}
00129        param = getParameter("text");
00130        if(param != null){if(param.equalsIgnoreCase("no") || param.equals("0")){draw_text=false;}}
00131        param = getParameter("ellipse");
00132        if(param != null){if(param.equalsIgnoreCase("no") || param.equals("0")){draw_ellipse=false;}}
00133        param = getParameter("penfontsize");
00134        if(param != null) {penfontsize=Integer.parseInt(param,10); penfont= new Font("Helvetica", Font.BOLD, penfontsize);}
00135        param = getParameter("penfontfamily");
00136        if(param != null) {penfont= new Font(param, Font.BOLD, penfontsize);}
00137        param = getParameter("penfontstyle");
00138        if(param != null) {
00139            if(param.equalsIgnoreCase("bold")){penfont= new Font(param, Font.BOLD , penfontsize);}
00140            else if(param.equalsIgnoreCase("italic")){penfont= new Font(param, Font.ITALIC , penfontsize);}
00141            else if(param.equalsIgnoreCase("plain")){penfont= new Font(param, Font.PLAIN , penfontsize);}
00142        }
00143        param = getParameter("penthickness");
00144        if(param != null) {thickness=Float.parseFloat(param);}
00145        param = getParameter("xsize");
00146        if(param != null) {xsize=Integer.parseInt(param,10);}
00147        param = getParameter("ysize");
00148        if(param != null) {ysize=Integer.parseInt(param,10);}
00149        param = getParameter("textlines");
00150        if(param != null) {ygrid=Integer.parseInt(param,10);
00151            if(ygrid>100){ygrid=100;System.out.println("100 lines max !");}
00152            if(ygrid<0){ygrid=10;System.out.println("positive number textlines !");}
00153        }
00154        param = getParameter("textalign");
00155        if(param == null || param.length()==0){original=true;}else{original=false;if(param.equalsIgnoreCase("vertical")){textalign=true;}else{textalign=false;}}
00156        resize(xsize,ysize);
00157        param=getParameter("bgcolor"); // Background color of inputfield "input"
00158        if (param != null && param.length()>0){bgcolor=ReturnColor(param);}
00159        param=getParameter("textcolor"); // Background color of inputfield "input"
00160        if (param != null && param.length()>0){textcolor=ReturnColor(param);}
00161        param=getParameter("drawcolor"); // Background color of inputfield "input"
00162        if (param != null && param.length()>0){drawcolor=ReturnColor(param);}
00163        
00164        diagram = new Diagram();
00165        diagram.editor = this;
00166        // no idea how to tell this class that the names are passed on as params in init...
00167        add(controls = new DiagramControls(this ,t_line,t_arrow,t_rectangle,t_ellipse,t_text,t_circle,t_destroy,t_move));
00168        add(display = new DiagramDisplay(this ,thickness,textcolor,drawcolor,penfont));
00169        current_event_consumer = controls;
00170        
00171     }
00172 
00173 // jm.evers
00174 
00175     public Color ReturnColor(String RGB){
00176        int R=0;int G=0;int B=0;
00177        RGB=RGB.replace(':',',');RGB=RGB.replace(';',',');
00178        StringTokenizer q = new StringTokenizer(RGB, ",");
00179        String k;int rgb;Color kleur;
00180        for( int a=0; a<3 ; a++){
00181            k=q.nextToken();
00182            rgb=Integer.parseInt(k, 10);
00183            if(rgb<0){rgb=0;}
00184            if(rgb>255){rgb=255;}
00185            if(a == 0){R = rgb;}
00186            else if(a == 1){G = rgb;}
00187            else if(a == 2){B = rgb;}
00188        }
00189        kleur=new Color(R,G,B);
00190        return kleur;
00191     }
00192     
00193     public String ReadApplet(String arg){
00194        String reply="";
00195        if(arg.equals("1")){
00196            String line_analysis="";
00197            int[] text_x=new int[textcounter];
00198            int[] text_y=new int[textcounter];
00199            int[] line_x1=new int[linecounter];
00200            int[] line_y1=new int[linecounter];
00201            int[] line_x2=new int[linecounter];
00202            int[] line_y2=new int[linecounter];
00203            String[] tekst=new String[textcounter];
00204            int real_text_length=0;String tmp="";
00205            int real_line_length=0;int x1;int x2;int y1;int y2;
00206            for(Enumeration e = diagram.elements(); e.hasMoreElements(); ){                                                                            
00207               DiagramItem item = (DiagramItem)e.nextElement();
00208               if(item.specify_line_x1() != -1){
00209                   x1=item.specify_line_x1();
00210                   y1=item.specify_line_y1();
00211                   x2=item.specify_line_x2();
00212                   y2=item.specify_line_y2();
00213                   if(textalign){//alleen horizontale lijnen
00214                      if( x1 != x2 && y1 == y2){// avoid line-dots to be send as lines/branches
00215                          line_x1[real_line_length] = x1;
00216                          line_y1[real_line_length] = y1;
00217                          line_x2[real_line_length] = x2;
00218                          line_y2[real_line_length] = y2;
00219                          real_line_length++;
00220                          System.out.println("een horizontale lijn "+real_line_length);
00221                      }
00222                   }
00223                   else
00224                   {
00225                      if( y1 != y2 && x1 == x2 ){// avoid line-dots to be send as lines/branches
00226                          line_x1[real_line_length] = x1;
00227                          line_y1[real_line_length] = y1;
00228                          line_x2[real_line_length] = x2;
00229                          line_y2[real_line_length] = y2;
00230                          real_line_length++;
00231                          System.out.println("een vertikale lijn "+real_line_length);
00232                      }
00233                   }
00234               }
00235               if(item.specify_text() != null){
00236                   tmp = item.specify_text();
00237                   // remove the forgotten '_' and we can't use komma's in the reply...replace them by points ?
00238                   tmp =replace(tmp,"_"," ");
00239                   tekst[real_text_length] =replace(tmp,",",".");
00240                   text_x[real_text_length] = item.specify_text_x();
00241                   text_y[real_text_length] = item.specify_text_y();
00242                   real_text_length++;
00243               }
00244            }
00245            
00246            boolean nog_meer = true;int i=0;int s=0;int temp_x;int temp_y;String temp_txt;
00247            String[] sameline = new String[real_text_length];
00248            FontMetrics fm =getFontMetrics(penfont);                                                                                       
00249             int hoogte = fm.getMaxAscent();
00250            if(textalign){//horizonal probability tree
00251               while (nog_meer) {
00252                   nog_meer = false;
00253                   for ( i=0; i<real_text_length-1; i++ ){
00254                      if ( text_y[i] < text_y[i+1] ){ sameline[i]="\n";}
00255                      if ( text_y[i] > text_y[i+1] ){
00256                          temp_y = text_y[i]; text_y[i] = text_y[i+1];  text_y[i+1] = temp_y;
00257                          temp_x = text_x[i];  text_x[i] = text_x[i+1];  text_x[i+1] = temp_x;
00258                          temp_txt = tekst[i];  tekst[i] = tekst[i+1];  tekst[i+1] = temp_txt;
00259                          nog_meer = true;
00260                          sameline[i]="\n";
00261                      }
00262                      if ( text_y[i] == text_y[i+1] ){
00263                          sameline[i]=" ";
00264                          if( text_x[i] > text_x[i+1] ){
00265                             temp_y = text_y[i]; text_y[i] = text_y[i+1];  text_y[i+1] = temp_y;
00266                              temp_x = text_x[i]; text_x[i] = text_x[i+1];  text_x[i+1] = temp_x;
00267                              temp_txt = tekst[i]; tekst[i] = tekst[i+1];  tekst[i+1] = temp_txt;
00268                             nog_meer = true;
00269                          }
00270                      }
00271                   }
00272               }
00273            }
00274            else
00275            {//vertical probability tree
00276               while (nog_meer) {
00277                   nog_meer = false;
00278                   for ( i=0; i<real_text_length-1; i++ ){
00279                      if ( text_x[i] < text_x[i+1] ){ sameline[i]="\n";}
00280                      if ( text_x[i] > text_x[i+1] ){
00281                          temp_y = text_y[i]; text_y[i] = text_y[i+1];  text_y[i+1] = temp_y;
00282                          temp_x = text_x[i];  text_x[i] = text_x[i+1];  text_x[i+1] = temp_x;
00283                          temp_txt = tekst[i];  tekst[i] = tekst[i+1];  tekst[i+1] = temp_txt;
00284                          nog_meer = true;
00285                          sameline[i]="\n";
00286                      }
00287                      if ( text_x[i] == text_x[i+1] ){
00288                          sameline[i]=" ";
00289                          if( text_y[i] > text_y[i+1] ){
00290                             temp_y = text_y[i]; text_y[i] = text_y[i+1];  text_y[i+1] = temp_y;
00291                              temp_x = text_x[i]; text_x[i] = text_x[i+1];  text_x[i+1] = temp_x;
00292                              temp_txt = tekst[i];  tekst[i] = tekst[i+1];  tekst[i+1] = temp_txt;
00293                             nog_meer = true;
00294                          }
00295                      }
00296                   }
00297               }
00298            
00299            }
00300            int wacht=0;
00301            if(textalign){
00302               for(i=0;i<real_line_length;i++){
00303                   y1=line_y1[i];
00304                   for(s=0;s<real_text_length;s++){
00305                      if(text_y[s]==y1 ||( text_y[s]<y1 && text_y[s]>y1-hoogte)){
00306                          wacht=s;
00307                      }
00308                   }
00309                   if(wacht!=0){
00310                      sameline[wacht]="\n line \n";
00311                      wacht=0;
00312                   }
00313               }
00314            }
00315            else
00316            {
00317               for(i=0;i<real_line_length;i++){
00318                   x1=line_x1[i];
00319                   x2=line_x2[i];
00320                   y1=line_y1[i];
00321                   y2=line_y2[1];
00322                   if(x1<x2+hoogte && x1>x2-hoogte){
00323                   // dus een "bijna vertikale lijn
00324                      for(s=0;s<real_text_length;s++){
00325                          if(text_y[s]==y1 ||( text_y[s]<y1 && text_y[s]>y1-hoogte)){
00326                             wacht=s;
00327                          }
00328                      }
00329                      if(wacht!=0){
00330                          sameline[wacht]="\n vertikale line \n";
00331                          wacht=0;
00332                      }
00333                   }
00334               }
00335            }
00336 
00337            for(i=0;i<real_text_length;i++){
00338               if(sameline[i] == null){sameline[i]="\n";}
00339               reply=reply+tekst[i]+sameline[i];
00340            }
00341        }
00342        else
00343        {
00344            //alldata...no special sorting of the text
00345            for(Enumeration e = diagram.elements(); e.hasMoreElements(); ){                                                                            
00346               DiagramItem item = (DiagramItem)e.nextElement();
00347               reply=reply+item.describe()+"\n";
00348            }
00349         }
00350 
00351        return reply;
00352     }
00353     
00354     // replace compatible with java 1.4  [B. Perrin-Riou]
00355     public static String replace(String source, String pattern, String replace){
00356        if (source!=null){
00357            final int len = pattern.length();
00358            StringBuffer sb = new StringBuffer();
00359            int found = -1;
00360            int start = 0;
00361            while( (found = source.indexOf(pattern, start) ) != -1){
00362               sb.append(source.substring(start, found));
00363               sb.append(replace);
00364               start = found + len;
00365            }
00366            sb.append(source.substring(start));
00367            return sb.toString();
00368        }
00369         else return "";
00370     }
00371 
00372     public void start() {
00373     }
00374 
00375     public void stop() {
00376     }
00377 
00378     public void destroy() {
00379     }
00380 
00381     public static void main(String argv[]) {
00382        /* This more-or-less replicates what happens when we  are run as an applet. */
00383        Frame f = new Frame();
00384        VrijeInvulVeld d = new VrijeInvulVeld();
00385        d.init();
00386        d.start();
00387        f.add("Center", d);
00388        f.show();
00389     }
00390 }
00391 /* end applet */
00392 
00393 
00394 
00395 /* The diagram */
00396 
00397 class Diagram extends Vector {
00398     VrijeInvulVeld editor;
00399     DiagramItem nearby(int x, int y){
00400        DiagramItem bestitem = null;
00401        double bestdist = 6;
00402        for(Enumeration e = elements(); e.hasMoreElements(); ) {
00403            DiagramItem item = (DiagramItem)e.nextElement();
00404            double dist = item.distance(x, y);
00405            if(dist < bestdist) {
00406               bestitem = item;
00407               bestdist = dist;
00408            }
00409        }
00410        return bestitem;
00411     }
00412 }
00413 
00414 
00415 /* The drawing area */
00416 
00417 class DiagramDisplay extends Canvas {
00418     VrijeInvulVeld editor;
00419     DiagramDisplay(VrijeInvulVeld ed , float thickness,Color textcolor,Color drawcolor, Font penfont){
00420        editor = ed;
00421        setBackground(VrijeInvulVeld.bgcolor);
00422        resize(VrijeInvulVeld.xsize,VrijeInvulVeld.ysize);
00423     }
00424 
00425 
00426     public void paint(Graphics g) {
00427        Graphics2D g2 = (Graphics2D) g;                                                                                                                    
00428        g2.setFont(VrijeInvulVeld.penfont);    
00429        g2.setStroke( new BasicStroke(VrijeInvulVeld.thickness)); 
00430        g2.setColor(VrijeInvulVeld.drawcolor);
00431        for(Enumeration e = editor.diagram.elements(); e.hasMoreElements(); ) {
00432            ((DiagramItem)e.nextElement()).draw(g2);
00433        }
00434     }
00435     
00436 
00437     public boolean mouseDown(Event e, int x, int y){
00438        if(editor.current_event_consumer.down(x, y)){
00439            repaint();
00440            return true;
00441        } 
00442        else 
00443        {
00444            return false;
00445        }
00446     }
00447 
00448     public boolean mouseUp(Event e, int x, int y){
00449        if(editor.current_event_consumer.up(x, y)){
00450            repaint();
00451            return true;
00452        } 
00453        else 
00454        {
00455            return false;
00456        }
00457     }
00458 
00459     public boolean mouseDrag(Event e, int x, int y){
00460        if(editor.current_event_consumer.drag(x, y)){
00461            repaint();
00462            return true;
00463        } 
00464        else
00465        {
00466            return false;
00467        }
00468     }
00469 
00470     public boolean keyDown(Event e, int key){
00471        if(editor.current_event_consumer.key(key)){
00472            repaint();
00473            return true;
00474        } 
00475        else 
00476        {
00477            return false;
00478        }
00479     }
00480 }
00481 
00482 /* The control panel and the diagram items do things in response to input */
00483 
00484 interface EventConsumer {
00485     public boolean down(int x, int y);
00486     public boolean up(int x, int y);
00487     public boolean drag(int x, int y);
00488     public boolean key(int key);
00489     public void yield();
00490 }
00491 
00492 /* The control panel */
00493 
00494 class DiagramControls extends Panel implements EventConsumer {
00495     VrijeInvulVeld editor;
00496     CheckboxGroup buttons;
00497     Checkbox line, arrow, rect, ellipse, text, destroy, move;
00498     final int CREATE = 0, DESTROY = 1, MOVE = 2;
00499     
00500 
00501     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) {
00502        editor = ed;
00503        setBackground(Color.white);
00504        GridBagLayout gridbag = new GridBagLayout();
00505        GridBagConstraints c = new GridBagConstraints();
00506        Component button;
00507        setLayout(gridbag);
00508        buttons = new CheckboxGroup();
00509        c.gridy = 0;
00510        c.gridx = 0;
00511        c.fill = GridBagConstraints.HORIZONTAL;
00512        c.weightx = 1;
00513        c.anchor = GridBagConstraints.CENTER;
00514        if(VrijeInvulVeld.draw_text){
00515            button = new DiagramControl(this, CREATE, (new Text()).getClass(), t_text ,  true);
00516            gridbag.setConstraints(button, c);add(button);c.gridx++;
00517        }
00518        if(VrijeInvulVeld.draw_line){
00519            button = new DiagramControl(this, CREATE, (new Line()).getClass(), t_line ,  false);
00520            gridbag.setConstraints(button, c);add(button);c.gridx++;
00521        }
00522        if(VrijeInvulVeld.draw_arrow){
00523            button = new DiagramControl(this, CREATE, (new Arrow()).getClass(), t_arrow ,  false);
00524            gridbag.setConstraints(button, c);add(button);c.gridx++;
00525        }
00526        if(VrijeInvulVeld.draw_rect){
00527            button = new DiagramControl(this, CREATE, (new Rect()).getClass(), t_rectangle, false);
00528            gridbag.setConstraints(button, c);add(button);c.gridx++;
00529        }
00530        if(VrijeInvulVeld.draw_ellipse){
00531            button = new DiagramControl(this, CREATE, (new Ellipse()).getClass(), t_ellipse , false);
00532            gridbag.setConstraints(button, c);add(button);c.gridx++;
00533        }
00534        button = new DiagramControl(this, MOVE, (new Object()).getClass(), t_move ,    false);
00535        gridbag.setConstraints(button, c);
00536        add(button);
00537        c.gridx++;
00538        button = new DiagramControl(this, DESTROY, (new Object()).getClass(), t_destroy  , false);
00539        gridbag.setConstraints(button, c);
00540        add(button);
00541 
00542     }
00543     public boolean down(int x, int y) {
00544        DiagramControl current_button = (DiagramControl)buttons.getCurrent();
00545        DiagramItem target;
00546        Diagram diagram = editor.diagram;
00547        editor.showStatus("");
00548        switch(current_button.mode) {
00549            case CREATE:
00550            try {
00551               Class class_ = current_button.class_;
00552               target = (DiagramItem)class_.newInstance();
00553               target.diagram = diagram;
00554               target.create();
00555               editor.current_event_consumer = target;
00556               diagram.addElement(target);
00557               target.down(x, y);
00558            }
00559            catch (InstantiationException ex) {}
00560            catch (IllegalAccessException ex) {}
00561            return true;
00562            
00563            case DESTROY:
00564            target = diagram.nearby(x, y);
00565            if(target != null) {diagram.removeElement(target);target.destroy();}
00566            return true;
00567            
00568            case MOVE:
00569            target = diagram.nearby(x, y);
00570            if(target != null) {target.move();editor.current_event_consumer = target;target.down(x, y);}
00571            return false;
00572            
00573            default:
00574            return false;
00575        }
00576     }
00577 
00578     public boolean up(int x, int y) {
00579        return false;
00580     }
00581 
00582     public boolean drag(int x, int y) {
00583        return false;
00584     }
00585 
00586     public boolean key(int key) {
00587        return false;
00588     }
00589 
00590     public boolean keyDown(Event e, int key) {
00591        /* For some reason we get the canvas key presses.  Pass them on XXX */
00592        return editor.display.keyDown(e, key);
00593     }
00594 
00595     public void yield() {}
00596 }
00597 
00598 /* The buttons in the control panel */
00599 
00600 class DiagramControl extends Checkbox {
00601     int mode;
00602     Class class_;
00603     DiagramControl(DiagramControls parent, int _mode, Class _class, String label, boolean state) {
00604        super(label, parent.buttons, state);
00605        mode = _mode;
00606        class_ = _class;
00607     }
00608 }
00609 
00610 
00611 /* The diagram items.
00612  * The methods implemented here are suitable for shapes defined by two
00613  * points (ends of a line, corners of an ellipse's bounding box).  Other
00614  * shapes should override.  Maybe I should use a subclass for this, but
00615  * some of the methods may be useful for other shapes (text could use
00616  * these methods for moving but not creating; it would be nice to store the 
00617  * state just by switching the methods).
00618  */
00619 
00620 abstract class DiagramItem implements EventConsumer {
00621     Diagram diagram;
00622     int state;
00623     final int NONE=0, CREATE=1, MOVE=2;
00624     int x, y, w, h;
00625     int movex, movey;
00626     DiagramItem() {
00627        x = y = w = h = 0;
00628     }
00629 
00630     DiagramItem(StringTokenizer tok) throws Exception {
00631        if(tok.countTokens() != 4)
00632        throw new IllegalArgumentException();
00633        x = (new Integer(tok.nextToken())).intValue();
00634        y = (new Integer(tok.nextToken())).intValue();
00635        w = (new Integer(tok.nextToken())).intValue();
00636        h = (new Integer(tok.nextToken())).intValue();
00637     }
00638 
00639     abstract void draw(Graphics g);
00640     abstract String describe();
00641     abstract String specify_text();
00642     abstract int specify_text_x();
00643     abstract int specify_text_y();
00644     abstract int specify_line_x1();
00645     abstract int specify_line_y1();
00646     abstract int specify_line_x2();
00647     abstract int specify_line_y2();
00648 
00649     void create() {
00650        state = CREATE;
00651     }
00652 
00653     public void yield() {
00654        diagram.editor.current_event_consumer = diagram.editor.controls;
00655        state = NONE;
00656     }
00657 
00658     void destroy() {}
00659 
00660     void move() {
00661        state = MOVE;
00662     }
00663 
00664     public boolean down(int _x, int _y) {
00665        switch(state){
00666            case CREATE:
00667            x = _x; y = _y;
00668            return true;
00669            
00670            case MOVE:
00671            movex = _x; movey = _y;
00672            return true;
00673        }
00674        return false;
00675     }
00676 
00677     public boolean up(int _x, int _y) {
00678        switch(state){
00679            case CREATE:
00680            w = _x - x; h = _y - y;
00681            yield();
00682            return true;
00683            
00684            case MOVE:
00685            x += (_x - movex);
00686            y += (_y - movey);
00687            yield();
00688            return true;
00689        }
00690        return false;
00691     }
00692 
00693     public boolean drag(int _x, int _y) {
00694        switch(state){
00695            case CREATE:
00696            w = _x - x; h = _y - y;
00697            return true;
00698        
00699            case MOVE:
00700            x += (_x - movex);
00701            y += (_y - movey);
00702            movex = _x;
00703            movey = _y;
00704            return true;
00705        }
00706        return false;
00707     }
00708 
00709     public boolean key(int key) {
00710        return false;
00711     }
00712 
00713     abstract double distance(int x, int y);
00714 }
00715 
00716 class Ellipse extends DiagramItem {
00717     Ellipse(){super();}
00718     Ellipse(StringTokenizer tok) throws Exception {super(tok);}
00719     String describe() {return "ellipse," + x + "," + y + "," + w + "," + h;}
00720     String specify_text() {return null; }
00721     int specify_text_x() {return -1; }
00722     int specify_text_y() {return -1; }
00723     int specify_line_x1(){return -1;}
00724     int specify_line_y1(){return -1;}
00725     int specify_line_x2(){return -1;}
00726     int specify_line_y2(){return -1;}
00727     void draw(Graphics g) {
00728        g.drawOval(x, y, w, h);
00729     }
00730     double distance(int _x, int _y) {
00731        /* Do this better! */
00732        float ww = w < 1 ? 1 : w, hh = h < 1 ? 1 : h;
00733        float yscale = ww/hh;
00734        float xx = _x - (x + ww / 2);
00735        float yy = (_y - (y + hh / 2)) * yscale;
00736        double r = Math.sqrt(xx * xx + yy * yy);
00737        return Math.abs(r - ww / 2);
00738     }
00739 }
00740 
00741 /* The class name Rectangle is already taken :-( */
00742 
00743 class Rect extends DiagramItem {
00744     Rect(){super();}
00745     Rect(StringTokenizer tok) throws Exception { super(tok);}
00746 
00747     String describe() {return "rectangle," + x + "," + y + "," + (x+w) + "," + (y+h);}
00748     String specify_text() {return null; }
00749     int specify_text_x() {return -1; }
00750     int specify_text_y() {return -1; }
00751     int specify_line_x1(){return -1;}
00752     int specify_line_y1(){return -1;}
00753     int specify_line_x2(){return -1;}
00754     int specify_line_y2(){return -1;}
00755 
00756     void draw(Graphics g) {
00757        g.drawLine(x  , y  , x+w, y  );
00758        g.drawLine(x+w, y  , x+w, y+h);
00759        g.drawLine(x+w, y+h, x  , y+h);
00760        g.drawLine(x  , y+h, x  , y  );
00761     }
00762 
00763     double distance(int _x, int _y) {
00764        double dtop, dbottom, dleft, dright, dist;
00765        if(_x < x){
00766            dtop = Misc.distance(_x, _y, x, y);
00767        }
00768        else 
00769        {
00770            if(_x > x+w){
00771               dtop = Misc.distance(_x, _y, x+w, y);
00772            }
00773            else
00774            {
00775               dtop = Math.abs(_y - y);
00776            }
00777        }    
00778     
00779        if(_x < x){
00780            dbottom = Misc.distance(_x, _y, x, y+h);
00781        }
00782        else
00783        {
00784            if(_x > x+w){
00785               dbottom = Misc.distance(_x, _y, x+w, y+h);
00786            }
00787            else
00788            {
00789               dbottom = Math.abs(_y - (y+h));
00790            }
00791        }
00792        
00793        if(_y < y)
00794            dleft = Misc.distance(_x, _y, x, y);
00795        else if(_y > y+h)
00796            dleft = Misc.distance(_x, _y, x, y+h);
00797        else
00798            dleft = Math.abs(_x - x);
00799     
00800        if(_y < y)
00801            dright = Misc.distance(_x, _y, x+w, y);
00802        else if(_y > y+h)
00803            dright = Misc.distance(_x, _y, x+w, y+h);
00804        else
00805            dright = Math.abs(_x - (x+w));
00806 
00807        dist = dtop;
00808        if(dbottom < dist){dist = dbottom;}
00809        if(dleft < dist){dist = dleft;}
00810        if(dright < dist){dist = dright;}
00811        
00812        return dist;
00813     }
00814 }
00815 
00816 class Line extends DiagramItem {
00817     Line() {super();}
00818     Line(StringTokenizer tok) throws Exception {super(tok);}
00819     void draw(Graphics g) {
00820        Graphics2D g2 = (Graphics2D) g;
00821        if(!VrijeInvulVeld.original){
00822            int dy=(int) VrijeInvulVeld.ysize / VrijeInvulVeld.ygrid;
00823            int dx=(int) VrijeInvulVeld.xsize / VrijeInvulVeld.ygrid;
00824            if(state != 2){
00825               y=dy*((int) Math.round(y/dy));
00826               h=dy*((int) Math.round(h/dy));
00827            }
00828            if(state == 1 || state == 2){
00829               g2.setColor(VrijeInvulVeld.textcolor);
00830               g2.setStroke( new BasicStroke(1.0f));
00831               if(VrijeInvulVeld.textalign){
00832                   for(int p=0;p<VrijeInvulVeld.ysize;p=p+dy){
00833                      g2.drawLine(0,p,VrijeInvulVeld.xsize,p);
00834                   }
00835               }
00836               else
00837               {
00838                   for(int p=0;p<VrijeInvulVeld.xsize;p=p+dx){
00839                      g2.drawLine(p,0,p,VrijeInvulVeld.ysize);
00840                   }      
00841               }
00842            }
00843        }
00844        g2.setColor(VrijeInvulVeld.drawcolor);
00845        g2.setStroke( new BasicStroke(VrijeInvulVeld.thickness));
00846        g2.drawLine(x, y, x+w, y+h);
00847        VrijeInvulVeld.linecounter++;
00848     }
00849     String describe() {return "line," + x + "," + y + "," + (x+w) + "," + (y+h);}
00850     String specify_text() {return null; }
00851     int specify_text_x(){return -1; }
00852     int specify_text_y(){return -1; }
00853     int specify_line_x1(){return x;}
00854     int specify_line_y1(){return y;}
00855     int specify_line_x2(){return (x+w);}
00856     int specify_line_y2(){return (y+h);}
00857 
00858     double distance(int _x, int _y) {
00859        if(w == 0 && h == 0)
00860        return Misc.distance(x, y, _x, _y);
00861        /* Set origin to end of line */
00862        _x -= x;
00863        _y -= y;
00864        /* Find line length and unit vector along line */
00865        double len = Math.sqrt(w*w + h*h);
00866        double u = w / len;
00867        double v = h / len;
00868        /* Find nearest point on line using dot product */
00869        double r = _x * u + _y * v;
00870        if(r < 0)
00871            return Misc.distance(0, 0, _x, _y);
00872        if(r > len)
00873            return Misc.distance(w, h, _x, _y);
00874            return Misc.distance(r * u, r * v, _x, _y);
00875     }
00876 }
00877 
00878 class Arrow extends Line {
00879     Arrow(){super();}
00880     Arrow(StringTokenizer tok) throws Exception { super(tok);}
00881     void draw(Graphics g) {
00882        /* Draw a line */
00883        Graphics2D g2 = (Graphics2D) g;
00884        if(!VrijeInvulVeld.original){
00885            int dy=(int) VrijeInvulVeld.ysize / VrijeInvulVeld.ygrid;
00886            int dx=(int) VrijeInvulVeld.xsize / VrijeInvulVeld.ygrid;
00887            if( state != 2){
00888               y=dy*((int) Math.round(y/dy));
00889               h=dy*((int) Math.round(h/dy));
00890            }
00891            if(state == 1 || state == 2){
00892               g2.setColor(VrijeInvulVeld.textcolor);
00893               g2.setStroke( new BasicStroke(1.0f));
00894               if(VrijeInvulVeld.textalign){
00895                   for(int p=0;p<VrijeInvulVeld.ysize;p=p+dy){
00896                      g2.drawLine(0,p,VrijeInvulVeld.xsize,p);
00897                   }
00898               }
00899               else
00900               {
00901                   for(int p=0;p<VrijeInvulVeld.xsize;p=p+dx){
00902                      g2.drawLine(p,0,p,VrijeInvulVeld.ysize);
00903                   }      
00904               }
00905            }
00906        }
00907            
00908        VrijeInvulVeld.linecounter++;
00909        g2.setColor(VrijeInvulVeld.drawcolor);
00910        g2.setStroke( new BasicStroke(VrijeInvulVeld.thickness));
00911        g2.drawLine(x, y, x+w, y+h);
00912        if(w == 0 && h == 0){return;}
00913        
00914        /* Find unit vector along line */
00915        double len = Math.sqrt(w*w + h*h);
00916        double u = w / len;
00917        double v = h / len;
00918 
00919        /* Draw arrow head */
00920        double _x = x + w - 5 * u;
00921        double _y = y + h - 5 * v;
00922        g2.drawLine(x+w, y+h, (int)(_x - 5 * v + 0.5), (int)(_y + 5 * u + 0.5));
00923        g2.drawLine(x+w, y+h, (int)(_x + 5 * v + 0.5), (int)(_y - 5 * u + 0.5));
00924     }
00925         
00926     String describe() {return "arrow," + x + "," + y + "," + (x+w) + "," +(y+h);}
00927     String specify_text() {return null; }
00928     int specify_text_x() {return -1; }
00929     int specify_text_y() {return -1; }
00930     int specify_line_x1(){return x;}
00931     int specify_line_y1(){return y;}
00932     int specify_line_x2(){return (x+w);}
00933     int specify_line_y2(){return (y+h);}
00934 
00935 }
00936 
00937 class Text extends DiagramItem {
00938     String text;
00939     StringBuffer buffer;
00940     Text() {
00941        x = y = 0;
00942        buffer = new StringBuffer();
00943        text = buffer.toString().concat("_");
00944     }
00945 
00946     Text(StringTokenizer tok) throws Exception {
00947        if(tok.countTokens() < 1){throw new IllegalArgumentException();}
00948            x = (new Integer(tok.nextToken())).intValue();
00949            y = (new Integer(tok.nextToken())).intValue();
00950            text = tok.nextToken("\n\r").trim();
00951 
00952     }
00953 
00954     void create() {
00955        super.create();
00956        diagram.editor.controls.disable();
00957        //diagram.editor.showStatus("Press return to finish string");
00958        diagram.editor.showStatus(VrijeInvulVeld.t_press);
00959        VrijeInvulVeld.textcounter++;
00960     }
00961 
00962     public void yield() {
00963        super.yield();
00964        diagram.editor.controls.enable();
00965        text = buffer.toString();
00966     }
00967 
00968     String describe() {
00969        return "text," + x + "," + y + "," + text;
00970     }
00971     String specify_text() {return text; }
00972     int specify_text_x() {return x; }
00973     int specify_text_y() {return y; }
00974     int specify_line_x1(){return -1;}
00975     int specify_line_y1(){return -1;}
00976     int specify_line_x2(){return -1;}
00977     int specify_line_y2(){return -1;}
00978     
00979 
00980     void draw(Graphics g) {
00981     //jm.evers
00982        if(!VrijeInvulVeld.original){
00983            Graphics2D g2 = (Graphics2D) g;
00984            int dy=(int) VrijeInvulVeld.ysize / VrijeInvulVeld.ygrid;
00985            int dx=(int) VrijeInvulVeld.xsize / VrijeInvulVeld.ygrid;
00986            if(state == 1 || state == 2){//show a temp grid lines
00987               g2.setColor(VrijeInvulVeld.drawcolor);
00988               g2.setStroke( new BasicStroke(1.0f));
00989               if(VrijeInvulVeld.textalign){for(int p=0;p<VrijeInvulVeld.ysize;p=p+dy){g2.drawLine(0,p,VrijeInvulVeld.xsize,p);}}
00990               else{for(int p=0;p<VrijeInvulVeld.xsize;p=p+dx){g2.drawLine(p,0,p,VrijeInvulVeld.ysize);}}
00991               g2.setFont(VrijeInvulVeld.penfont);     
00992            }
00993            else
00994            {
00995               g2.setFont(VrijeInvulVeld.penfont);    
00996            }
00997            if(state != 2){ // not while dragging
00998               if(VrijeInvulVeld.ygrid<50 && VrijeInvulVeld.ygrid>1){
00999                   if(VrijeInvulVeld.textalign){// then snap to the nearest vertical line...
01000                      y=dy*((int) (Math.round(y/dy)));
01001                      if(y<dy){y=dy;}
01002                      if(y>VrijeInvulVeld.ysize-dy){y=VrijeInvulVeld.ysize-dy;}
01003                   }
01004                   else
01005                   {//snap to the nearest horizontal line...
01006                      x=dx*((int) (Math.round(x/dx)));
01007                      if(x<dx){x=dx;}
01008                      if(x>VrijeInvulVeld.xsize-dx){x=VrijeInvulVeld.xsize-dx;}
01009                   }
01010               }
01011            }
01012            g2.setColor(VrijeInvulVeld.textcolor);
01013            g2.setStroke( new BasicStroke(VrijeInvulVeld.thickness));
01014            g2.drawString(text, x, y);
01015            g2.setColor(VrijeInvulVeld.drawcolor);
01016        }
01017        else
01018        {
01019            g.drawString(text, x, y);
01020        }
01021     }
01022     double distance(int _x, int _y) {
01023        FontMetrics fm = diagram.editor.display.getGraphics().getFontMetrics();
01024        int m = y - (fm.getAscent() / 2);
01025        if(_x < x){return Misc.distance(x, m, _x, _y);}
01026        int r = x + fm.stringWidth(text);
01027        if(_x > r){return Misc.distance(r, m, _x, _y);}
01028        return Math.abs(_y - m);
01029     }
01030 
01031     public boolean down(int _x, int _y) {
01032        switch(state) {
01033            case CREATE:
01034            x = _x; y = _y;
01035            return true;
01036            
01037            case MOVE:
01038            return super.down(_x, _y);
01039        }
01040        return false;
01041     }
01042 
01043     public boolean up(int _x, int _y) {
01044        switch(state) {
01045            case CREATE:
01046            x = _x; y = _y;
01047            return true;
01048            
01049            case MOVE:
01050            return super.up(_x, _y);    
01051        }
01052        return false;
01053     }
01054 
01055     public boolean drag(int _x, int _y) {
01056        switch(state) {
01057            case CREATE:
01058            x = _x; y = _y;
01059            return true;
01060            
01061            case MOVE:
01062            return super.drag(_x, _y);
01063        }
01064        return false;
01065     }
01066 
01067     public boolean key(int key) {
01068        char c[] = new char[1];
01069        switch(state) {
01070            case CREATE:
01071            switch(key) {
01072               case 10:/* LF */
01073 
01074               case 13:/* CR */
01075               yield();
01076               if(text.equals("")){
01077                   diagram.removeElement(this);
01078                   destroy();
01079                   diagram.editor.showStatus("String was empty");
01080               }
01081               else
01082                   diagram.editor.showStatus("");
01083                   return true;
01084               
01085               case 8:/* BS */
01086               case 127:/* DEL */
01087               int l = buffer.length();
01088            if(l > 0)
01089               buffer.setLength(l - 1);
01090               break;
01091     
01092               default:
01093               buffer.append((char)key);
01094               break;
01095            }
01096            text = buffer.toString().concat("_");
01097            return true;
01098        }
01099        return false;
01100     }
01101 }
01102 
01103 /* An area for displaying messages */
01104 
01105 class MessageArea extends Canvas {
01106     String text = "";
01107     void setText(String s) {
01108        text = s;
01109        repaint();
01110     }
01111 
01112     public void paint(Graphics g) {
01113        setBackground(VrijeInvulVeld.bgcolor);
01114        //g.setFont(VrijeInvulVeld.messagefont);    
01115        g.drawString(text,5,20);
01116     }
01117 }
01118 
01119 
01120 /* Handy functions */
01121 
01122 class Misc {
01123     static double distance(double x1, double y1, double x2, double y2) {
01124        return Math.sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
01125     }
01126 }