Annotation of java/classes/org/w3c/rdf/VisRDF.java, revision 1.2

1.1       jsaarela    1: /**
                      2:  * Visualize RDF descriptions and allow user to navigate within the
                      3:  * the RDF data model
                      4:  *
                      5:  * Copyright © World Wide Web Consortium, (Massachusetts Institute of
                      6:  * Technology, Institut National de Recherche en Informatique et en
                      7:  * Automatique, Keio University).
                      8:  *
                      9:  * All Rights Reserved.
                     10:  *
                     11:  * Please see the full Copyright clause at
                     12:  * <http://www.w3.org/Consortium/Legal/copyright-software.html>
                     13:  *
1.2     ! jsaarela   14:  * $Log: VisRDF.java,v $
        !            15:  * Revision 1.1  1999/01/13 15:00:40  jsaarela
        !            16:  * Finished conformance testing with PR-rdf-syntax-19990105 version
        !            17:  * of the RDF M&S spec.
        !            18:  *
1.1       jsaarela   19:  *
                     20:  * @author     Janne Saarela <jsaarela@w3.org>
1.2     ! jsaarela   21:  * @version    $Id: VisRDF.java,v 1.1 1999/01/13 15:00:40 jsaarela Exp $
1.1       jsaarela   22:  */
                     23: package org.w3c.rdf;
                     24: 
                     25: import java.awt.*;
                     26: import java.util.Vector;
                     27: import java.util.Hashtable;
                     28: import java.util.Enumeration;
                     29: import java.io.*;
                     30: import java.net.URL;
                     31: 
                     32: public class VisRDF extends java.applet.Applet {
1.2     ! jsaarela   33:   public static final String VERSION = "$Id: VisRDF.java,v 1.1 1999/01/13 15:00:40 jsaarela Exp $";
1.1       jsaarela   34: 
                     35:   public boolean bApplication = false;
                     36: 
                     37:   /* storage elements */
                     38:   private Node         m_selectedNode = null;
                     39:   private Arc          m_selectedArc = null;
                     40:   private Hashtable    m_prop = new Hashtable ();
                     41:   private Hashtable    m_propobj = new Hashtable ();
                     42:   private Hashtable    m_propvalue = new Hashtable ();
                     43:   private Vector       m_vNodes = new Vector ();
                     44:   private Vector       m_vArcs = new Vector ();
                     45: 
                     46:   /* GUI elements */
                     47:   private Panel                m_options = new Panel ();
                     48:   private Panel                m_nodes = new Panel ();
                     49:   private Panel                m_buttons = new Panel ();
                     50:   private Panel                m_checkboxes = new Panel ();
                     51:   private Label                m_urlLabel = new Label ("Type in an ID");
                     52:   public TextField     m_url = new TextField("", 20);
                     53:   private Button       m_start = new Button ("Start query");
                     54:   private Button       m_clear = new Button ("Clear canvas");
                     55: 
                     56:   private Checkbox     m_genidsCB = new Checkbox ("Show generated IDs");
                     57:   private Checkbox     m_shortnamesCB = new Checkbox ("Show long names");
                     58: 
                     59:   private List         m_schemas = new List (5, true);
                     60: 
                     61:   String m_input = new String ();
                     62: 
                     63:   public VisRDF () {
                     64:   }
                     65: 
                     66:   public String getAppletInfo() {
                     67:       String info = "This is RDF visualization applet version "+VERSION+
                     68:          "\nby Janne Saarela/W3c <jsaarela@w3.org>. You can use it to\n" +
                     69:          "interactively browse RDF data models with the mouse.";
                     70:       return info;
                     71:   }
                     72: 
                     73:   public void init () {
                     74:     if (!bApplication) {
                     75:        String sTriples = getParameter ("triples");
                     76:        if (sTriples != null && sTriples.length() > 0)
                     77:            parseTriples (new StringBufferInputStream (sTriples));
                     78:        String sStart = getParameter ("start");
                     79:        if (sStart != null && sStart.length() > 0)
                     80:            m_url.setText (sStart);
                     81:     }
                     82: 
                     83:     setLayout (new BorderLayout());
                     84: 
                     85:     m_nodes.setLayout (null);
                     86:     m_nodes.setBackground (Color.white);
                     87: 
                     88:     m_buttons.setLayout (new GridLayout (1, 3));
                     89:     m_checkboxes.setLayout (new GridLayout (2, 1));
                     90: 
                     91:     add("West", m_options);
                     92:     add("Center", m_nodes);
                     93:     add("South", m_buttons);
                     94: 
                     95:     m_options.setLayout (new GridLayout (4,1));
                     96: 
                     97:     m_options.add (m_urlLabel);
                     98:     m_options.add (m_url);
                     99:     m_options.add (new Label ("Select visualized schemas"));
                    100:     m_options.add (m_schemas);
                    101: 
                    102:     m_buttons.add (m_start);
                    103:     m_buttons.add (m_clear);
                    104:     m_buttons.add (m_checkboxes);
                    105: 
                    106:     m_checkboxes.add (m_genidsCB);
                    107:     m_checkboxes.add (m_shortnamesCB);
                    108:   }
                    109: 
                    110:   public void parseTriples (InputStream is) {
1.2     ! jsaarela  111:       Vector vTriples = new Vector ();
        !           112: 
1.1       jsaarela  113:     try {
                    114:        StreamTokenizer st = new StreamTokenizer (is);
                    115:        st.whitespaceChars(',', ',');
                    116:        st.quoteChar('\'');
                    117:        
                    118:        int token1, token2, token3, token4, token5, token6, token7;
                    119:        while ((token1 = st.nextToken()) != StreamTokenizer.TT_EOF) {
                    120:            token2 = st.nextToken ();
                    121:            token3 = st.nextToken ();
                    122:            String sPredicate = st.sval;
                    123:            token4 = st.nextToken ();
                    124:            String sSubject = st.sval;
                    125:            token5 = st.nextToken ();
                    126:            String sObject = st.sval;
                    127:            token6 = st.nextToken ();
                    128:            token7 = st.nextToken ();
                    129: 
1.2     ! jsaarela  130:            /**
        !           131:             * Check an identical triple has not been added, yet
        !           132:             */
        !           133:            boolean bFound = false;
        !           134:            for (int x = 0; x < vTriples.size(); x++) {
        !           135:                Triple oldT = (Triple)vTriples.elementAt(x);
        !           136:                if (oldT.predicate().toString().equals (sPredicate) &&
        !           137:                    oldT.subject().toString().equals (sSubject) &&
        !           138:                    oldT.object().toString().equals (sObject)) {
        !           139:                    bFound = true;
        !           140:                    break;
        !           141:                }
        !           142:            }
        !           143:            if (bFound) continue;
        !           144: 
        !           145:            Triple t = new Triple (new Property(sPredicate),
        !           146:                                   new Resource(sSubject),
        !           147:                                   new Literal(sObject));
        !           148:            vTriples.addElement (t);
1.1       jsaarela  149:            index (t);
                    150: 
                    151:            addSchema (sPredicate);
                    152:        }
                    153:     } catch (Exception e) {
                    154:        e.printStackTrace();
                    155:     }
                    156: 
1.2     ! jsaarela  157:     vTriples = null; // allow garbage collection of this vector
        !           158: 
1.1       jsaarela  159:     for (int x = 0; x < m_schemas.countItems(); x++) {
                    160:        m_schemas.select (x);
                    161:     }
                    162:   }
                    163: 
                    164:   /**
                    165:    * Figure out if a schema name can be extracted and added
                    166:    * to the list box
                    167:    */
                    168:   public void addSchema (String sPredicate) {
                    169:       int iHash = sPredicate.indexOf ('#');
                    170:       if (iHash > -1) {
                    171:          String sSchema = sPredicate.substring (0, iHash);
                    172:          int iItems = m_schemas.countItems ();
                    173:          for (int x = 0; x < iItems; x++) {
                    174:              if (m_schemas.getItem (x).equals (sSchema))
                    175:                  return;
                    176:          }
                    177:          m_schemas.addItem (sSchema, 0);
                    178:          return;
                    179:       }
                    180: 
                    181:       int iSlash = sPredicate.indexOf ('/');
                    182:       if (iSlash > -1) {
                    183:          String sSchema = sPredicate.substring (0, iSlash);
                    184:          int iItems = m_schemas.countItems ();
                    185:          for (int x = 0; x < iItems; x++) {
                    186:              if (m_schemas.getItem (x).equals (sSchema))
                    187:                  return;
                    188:          }
                    189:          m_schemas.addItem (sSchema, 0);
                    190:       }
                    191:   }
                    192: 
                    193:   /**
                    194:    * Return a Vectorful of items that point to
                    195:    * the given URL
                    196:    */
                    197:   public Vector matchTO (String sURL) {
                    198:     Vector v = (Vector)m_propvalue.get (sURL);
                    199:     Vector v2 = new Vector ();
                    200:     if (v == null)
                    201:        return new Vector ();
                    202: 
1.2     ! jsaarela  203:     for (int y = 0; y < v.size(); y++) {
        !           204:        Triple t = (Triple)v.elementAt(y);
        !           205: 
        !           206:        for (int x = 0; x < m_schemas.countItems(); x++) {
        !           207:            if (m_schemas.isSelected (x)) {
        !           208:                String sSchema = m_schemas.getItem (x);
        !           209: 
        !           210:                if (t.predicate().toString().startsWith (sSchema)) {
        !           211:                    // require the predicate().toString() is followed by # or /
1.1       jsaarela  212:                    // character
1.2     ! jsaarela  213:                    if (t.predicate().toString().substring(sSchema.length(), sSchema.length()+1).equals ("#") ||
        !           214:                        t.predicate().toString().substring(sSchema.length(), sSchema.length()+1).equals ("/")) {
1.1       jsaarela  215:                        v2.addElement (t);
1.2     ! jsaarela  216:                        break;
        !           217:                    }
1.1       jsaarela  218:                }
                    219:            }
                    220:        }
                    221:     }
                    222: 
                    223:     return v2;
                    224:   }
                    225: 
                    226:   /**
                    227:    * Return a Vectorful of items that point from
                    228:    * the given URL
                    229:    */
                    230:   public Vector matchFROM (String sURL) {
                    231:     Vector v = (Vector)m_propobj.get (sURL);
                    232:     Vector v2 = new Vector ();
                    233:     if (v == null)
                    234:        return new Vector();
                    235: 
1.2     ! jsaarela  236:     for (int y = 0; y < v.size(); y++) {
        !           237:        Triple t = (Triple)v.elementAt(y);
        !           238: 
        !           239:        for (int x = 0; x < m_schemas.countItems(); x++) {
        !           240:            if (m_schemas.isSelected (x)) {
        !           241:                String sSchema = m_schemas.getItem (x);
        !           242: 
        !           243:                if (t.predicate().toString().startsWith (sSchema)) {
        !           244:                    // require the predicate().toString() is followed by # or /
1.1       jsaarela  245:                    // character
1.2     ! jsaarela  246:                    if (t.predicate().toString().substring(sSchema.length(), sSchema.length()+1).equals ("#") ||
        !           247:                        t.predicate().toString().substring(sSchema.length(), sSchema.length()+1).equals ("/")) {
1.1       jsaarela  248:                        v2.addElement (t);
1.2     ! jsaarela  249:                        break;
        !           250:                    }
1.1       jsaarela  251:                }
                    252:            }
                    253:        }
                    254:     }
                    255: 
                    256:     return v2;
                    257:   }
                    258: 
                    259:   /**
                    260:    * Return a Vectorful of items that have a given property
                    261:    */
                    262:   public Vector matchPredicate (String sPredicate) {
                    263:     Vector v = (Vector)m_prop.get (sPredicate);
                    264:     if (v == null)
                    265:        return new Vector();
                    266: 
                    267:     return v;
                    268:   }
                    269: 
                    270:   /**
                    271:    * Index each Triple instance according to each element
                    272:    */
                    273:   public void index (Triple t) {
1.2     ! jsaarela  274:       String sType = t.predicate().toString();
1.1       jsaarela  275:       Vector v = (Vector)m_prop.get (sType);
                    276:       if (v == null) {
                    277:          v = new Vector ();
                    278:       }
1.2     ! jsaarela  279:       v.addElement (t);
        !           280:       m_prop.put (sType, v);
1.1       jsaarela  281: 
1.2     ! jsaarela  282:       String sSubject = t.subject().toString ();
1.1       jsaarela  283:       v = (Vector)m_propobj.get (sSubject);
                    284:       if (v == null) {
                    285:          v = new Vector ();
                    286:       }
1.2     ! jsaarela  287:       v.addElement (t);
        !           288:       m_propobj.put (sSubject, v);
1.1       jsaarela  289: 
1.2     ! jsaarela  290:       String sObject = t.object().toString();
1.1       jsaarela  291:       v = (Vector)m_propvalue.get (sObject);
                    292:       if (v == null) {
                    293:          v = new Vector ();
                    294:       }
1.2     ! jsaarela  295:       v.addElement (t);
        !           296:       m_propvalue.put (sObject, v);
1.1       jsaarela  297:   }
                    298: 
                    299:   /*
                    300:    * manage the button events
                    301:    */
                    302:   public boolean handleEvent (Event e) {
                    303:     if (e.id == Event.ACTION_EVENT) {
                    304:       if (m_start == e.target) {
                    305:          query (null);
                    306:        return true;
                    307:       } else if (m_clear == e.target) {
                    308:          m_nodes.removeAll();
                    309:          m_vNodes.removeAllElements();
                    310:          m_vArcs.removeAllElements();
                    311:          repaint();
                    312:        return true;
                    313:       } else if (m_genidsCB == e.target) {
                    314:        if (m_genidsCB.getState() == true)
                    315:            Node.GENIDS = true;
                    316:        else
                    317:            Node.GENIDS = false;
                    318:        repaint ();
                    319:        return true;
                    320:       } else if (m_shortnamesCB == e.target) {
1.2     ! jsaarela  321:          if (m_shortnamesCB.getState() == true) {
1.1       jsaarela  322:              Arc.SHORTNAMES = false;
1.2     ! jsaarela  323:              Node.SHORTNAMES = false;
        !           324:          } else {
1.1       jsaarela  325:              Arc.SHORTNAMES = true;
1.2     ! jsaarela  326:              Node.SHORTNAMES = true;
        !           327:          }
1.1       jsaarela  328:          repaint ();
                    329:          return true;
                    330:       }
                    331:     } else if (e.id == Event.MOUSE_MOVE &&
                    332:               e.target == m_nodes) {
                    333:        Rectangle r = m_options.bounds();
                    334:        Point p = new Point (e.x - r.width, e.y);
                    335:        boolean bRepaint = false;
                    336: 
                    337:        /**
                    338:         * Try to figure out the closest
                    339:         * 1. Node -> make it selected
                    340:         * 2. Arc -> make it selected along with the originating node
                    341:         */
                    342: 
                    343:        Node potentialNode = null;
                    344:        Arc potentialArc = null;
                    345: 
                    346:        Enumeration enum = m_vNodes.elements();
                    347:        while (enum.hasMoreElements()) {
                    348:            Node n = (Node)enum.nextElement();
                    349:            if (n.distance(p) < 150) {
                    350:                potentialNode = n;
                    351:            }
                    352:        }
                    353: 
                    354:        enum = m_vArcs.elements ();
                    355:        while (enum.hasMoreElements()) {
                    356:            Arc a = (Arc)enum.nextElement();
                    357:            if (a.distance(p) < 150) {
                    358:                potentialArc = a;
                    359:                potentialNode = null; // make sure it is null
                    360:            }
                    361:        }
                    362: 
                    363:        if (potentialNode != null) {
                    364:            if (m_selectedArc != null) {
                    365:                m_selectedArc.setColor (Arc.DEFAULT_COLOR);
                    366:                m_selectedArc = null;
                    367:            }
                    368:            if (potentialNode != m_selectedNode)
                    369:                bRepaint = true;
                    370: 
                    371:            if (m_selectedNode != null)
                    372:                m_selectedNode.setColor (Node.DEFAULT_COLOR);
                    373:            m_selectedNode = potentialNode;
                    374:            m_selectedNode.setColor (Node.SELECTED_COLOR);
                    375: 
1.2     ! jsaarela  376:            // showStatus ("Click on the node to follow it further");
1.1       jsaarela  377:        } else if (potentialArc != null) {
                    378:            if (m_selectedNode != null) {
                    379:                m_selectedNode.setColor (Node.DEFAULT_COLOR);
                    380:                m_selectedNode = null;
                    381:            }
                    382:            if (potentialArc != m_selectedArc)
                    383:                bRepaint = true;
                    384: 
                    385:            if (m_selectedArc != null)
                    386:                m_selectedArc.setColor (Arc.DEFAULT_COLOR);
                    387:            m_selectedArc = potentialArc;
                    388:            m_selectedArc.setColor (Arc.SELECTED_COLOR);
                    389: 
1.2     ! jsaarela  390:            // showStatus ("Click on the arc to fetch similar properties");
1.1       jsaarela  391:        } else {
1.2     ! jsaarela  392:            // showStatus ("Place the mouse over a node or an arc");
1.1       jsaarela  393:        }
                    394: 
                    395:        if (bRepaint)
                    396:            repaint ();
                    397:        return true;
                    398:     } else if (e.id == Event.MOUSE_UP) {
                    399:        if (m_selectedNode != null) {
                    400:            String sOldText = m_url.getText ();
                    401:            m_url.setText (m_selectedNode.name());
                    402: 
                    403:            /**
                    404:             * If the text within the central node was a valid URL, bring
                    405:             * it up on the browser. If not, continue with the
                    406:             * applet execution
                    407:             */
                    408:            boolean bValidURL = true;
                    409:            URL url = null;
                    410:            try {
                    411:                url = new URL (m_selectedNode.name());
                    412:            } catch (Exception ex) {
                    413:                bValidURL = false;
                    414:            }
                    415:            if (bValidURL &&
                    416:                sOldText.equals (m_selectedNode.name())) {
                    417:                getAppletContext().showDocument (url);
                    418:            } else {
                    419:                query (m_selectedNode.name());
                    420:            }
                    421:            return true;
                    422:        } else if (m_selectedArc != null) {
                    423:            queryPredicate (m_selectedArc.relation());
                    424:            return true;
                    425:        }
                    426:     } else if (e.id == Event.LIST_SELECT ||
                    427:               e.id == Event.LIST_DESELECT) {
                    428:        query (null);
                    429:     }
                    430: 
                    431: 
                    432:     return false;
                    433:   }
                    434: 
                    435:   /**
                    436:    * query
                    437:    *
                    438:    * 1. reads the new Triple from m_url
                    439:    * 2. create a new Node for the found item
                    440:    * 3. create new Nodes for all other Nodes associaed with it
                    441:    * 4. adds all these to the m_nodes Panel
                    442:    * (5. nodes draw themselves using paint() method)
                    443:    */
                    444: 
                    445:   public void query (String sObject) {
                    446:     m_vNodes.removeAllElements ();
                    447:     m_vArcs.removeAllElements ();
                    448: 
                    449:     /**
                    450:      * 1.
                    451:      */
                    452:     String sURL;
                    453:     if (sObject == null)
                    454:       sURL = m_url.getText ();
                    455:     else
                    456:       sURL = sObject;
                    457: 
                    458:     /**
                    459:      * 2.
                    460:      */
                    461:     Rectangle r = m_nodes.bounds ();
                    462:     Dimension d = new Dimension (r.width, r.height);
                    463:     Point center = new Point (d.width/2, d.height/2);
                    464: 
                    465:     Node centerNode = new Node (sURL, center);
                    466:     centerNode.setColor (Node.SELECTED_COLOR);
                    467:     m_selectedNode = centerNode;
                    468:     m_vNodes.addElement (centerNode);
                    469: 
                    470:     /**
                    471:      * 3.
                    472:      */
                    473:     Vector v = matchTO (sURL);
                    474: 
                    475:     for (int i = 0; i < v.size(); i++) {
                    476:       Triple triple = (Triple)v.elementAt(i);
                    477: 
                    478:       double   dAngle = - (i * Math.PI / (v.size() + 1) + Math.PI / (v.size() + 1));
                    479:       int      iRadius = d.height/2 - 50;
                    480: 
                    481:       Point p = new Point (d.width/2  + (int)(iRadius * Math.cos(dAngle)),
                    482:                           d.height/2 + (int)(iRadius * Math.sin(dAngle)));
1.2     ! jsaarela  483:       Node n = new Node (triple.subject().toString(), p);
1.1       jsaarela  484: 
                    485:       n.addNextNode (centerNode);
                    486: 
                    487:       m_vNodes.addElement (n);
                    488: 
1.2     ! jsaarela  489:       m_vArcs.addElement (new Arc (triple.predicate().toString(),
1.1       jsaarela  490:                                   p, center,
                    491:                                   n, centerNode));
                    492:     }
                    493: 
                    494:     v = matchFROM (sURL);
                    495: 
                    496:     for (int i = 0; i < v.size(); i++) {
                    497:       Triple triple = (Triple)v.elementAt(i);
                    498: 
                    499:       double   dAngle = - Math.PI - ( i * Math.PI / (v.size() + 1) + Math.PI / (v.size() + 1));
                    500:       int      iRadius = d.height/2 - 50;
                    501: 
                    502:       Point p = new Point (d.width/2  + (int)(iRadius * Math.cos(dAngle)),
                    503:                           d.height/2 + (int)(iRadius * Math.sin(dAngle)));
1.2     ! jsaarela  504:       Node n = new Node (triple.object().toString(), p);
        !           505:       
1.1       jsaarela  506:       centerNode.addNextNode (n);
                    507: 
                    508:       m_vNodes.addElement (n);
                    509: 
1.2     ! jsaarela  510:       m_vArcs.addElement (new Arc (triple.predicate().toString(),
1.1       jsaarela  511:                                   center, p,
                    512:                                   centerNode, n));
                    513:     }
                    514: 
                    515:     repaint ();
                    516:   }
                    517: 
                    518:   /**
                    519:    * queryPredicate
                    520:    *
                    521:    */
                    522: 
                    523:   public void queryPredicate (String sPredicate) {
                    524:     m_vNodes.removeAllElements ();
                    525:     m_vArcs.removeAllElements ();
                    526: 
                    527:     Rectangle r = m_nodes.bounds ();
                    528:     Dimension d = new Dimension (r.width, r.height);
                    529: 
                    530:     Vector v = matchPredicate (sPredicate);
                    531: 
                    532:     for (int i = 0; i < v.size(); i++) {
                    533:       Triple triple = (Triple)v.elementAt(i);
                    534: 
                    535:       Point sourcePoint = new Point ((i + 1) * r.width / (v.size()+1), (int)(0.2 * r.height));
                    536:       Point destPoint = new Point ((i + 1) * r.width / (v.size()+1), (int)(0.8 * r.height));
                    537: 
1.2     ! jsaarela  538:       Node sourceNode = new Node (triple.subject().toString(), sourcePoint);
        !           539:       Node destNode = new Node (triple.object().toString(), destPoint);
1.1       jsaarela  540: 
                    541:       m_vNodes.addElement (sourceNode);
                    542:       m_vNodes.addElement (destNode);
                    543: 
1.2     ! jsaarela  544:       m_vArcs.addElement (new Arc (triple.predicate().toString(),
1.1       jsaarela  545:                                   sourcePoint, destPoint,
                    546:                                   sourceNode, destNode));
                    547:     }
                    548: 
                    549:     repaint ();
                    550:   }
                    551: 
                    552:   public void paint (Graphics g) {
                    553:     Font f1 = new Font ("Helvetica", Font.PLAIN, 12);
                    554:     Font f2 = new Font ("Helvetica", Font.PLAIN, 10);
                    555:     Rectangle r = m_nodes.bounds ();
                    556:     Dimension d = new Dimension (r.width, r.height);
                    557:     Graphics g2 = m_nodes.getGraphics();
                    558:     
                    559:     g2.clearRect (0, 0, d.width, d.height);
                    560: 
                    561:     Enumeration e = m_vNodes.elements();
                    562: 
                    563:     while (e.hasMoreElements()) {
                    564:       Node n = (Node)e.nextElement();
                    565:       g2.setColor (n.color());
                    566:       g2.setFont (f1);
                    567:       g2.drawString (n.visualName(), n.x()-40, n.y());
                    568:       g2.fillOval (n.x(), n.y(), 6, 6);
                    569:     }
                    570: 
                    571:     e = m_vArcs.elements ();
                    572:     while (e.hasMoreElements()) {
                    573:       Arc a = (Arc)e.nextElement ();
                    574: 
                    575:       int sourceX = a.start().x;
                    576:       int sourceY = a.start().y;
                    577:       int destX = a.end().x;
                    578:       int destY = a.end().y;
                    579: 
                    580:       if (sourceX > destX) {
                    581:          sourceX -= 10;
                    582:          destX += 10;
                    583:       } else if (sourceX < destX) {
                    584:          sourceX += 10;
                    585:          destX -= 10;
                    586:       }
                    587:       if (sourceY > destY) {
                    588:          sourceY -= 10;
                    589:          destY += 10;
                    590:       } else if (sourceY < destY) {
                    591:          sourceY += 10;
                    592:          destY -= 10;
                    593:       }
                    594:       
                    595:       g2.setColor(a.color());
                    596: 
                    597:       g2.drawLine (sourceX, sourceY, destX, destY);
                    598: 
                    599:       /**
                    600:        * Try to make the line look like an arrow
                    601:        */
                    602:       int dY = destY - sourceY;
                    603:       int dX = destX - sourceX;
                    604:       double dLength = Math.sqrt (dX*dX + dY*dY);
                    605:       double dP = 10.0;
                    606:       double dQ = 0.6;
                    607:       
                    608:       int iX1 = (int)(destX - (dX + dQ * dY) * dP/dLength);
                    609:       int iY1 = (int)(destY - (dY - dQ * dX) * dP/dLength);
                    610:       
                    611:       int iX2 = (int)(destX - (dX - dQ * dY) * dP/dLength);
                    612:       int iY2 = (int)(destY - (dY + dQ * dX) * dP/dLength);
                    613:       
                    614:       g2.drawLine (destX, destY, iX1, iY1);
                    615:       g2.drawLine (destX, destY, iX2, iY2);
                    616:       
                    617:       /**
                    618:        * Draw the relation
                    619:        */
                    620:       g2.setFont (f2);
                    621:       g2.drawString (a.visualRelation(),
                    622:                     (sourceX + destX) / 2 - 10,
                    623:                     (sourceY + destY) / 2);
                    624:     }
                    625:   }
                    626: 
                    627:   public static void main (String argv[]) {
1.2     ! jsaarela  628:     Frame FirstWindow = new Frame ("Visual RDF (C)1997-1999 Janne Saarela/World Wide Web Consortium (W3C)");
1.1       jsaarela  629: 
                    630:     VisRDF vs = new VisRDF ();
                    631: 
                    632:     FirstWindow.setLayout (new BorderLayout());
                    633:     FirstWindow.add ("Center", vs);
                    634:     FirstWindow.resize (700, 650);
                    635: 
                    636:     vs.m_input = argv[0];
                    637:     if (argv.length > 1)
                    638:        vs.m_url.setText (argv[1]);
                    639: 
                    640:     try {
                    641:        vs.parseTriples (new FileInputStream (argv[0]));
                    642:     } catch (Exception e) {
                    643:        e.printStackTrace ();
                    644:     }
                    645: 
                    646:     vs.bApplication = true;
                    647:     vs.init ();
                    648:     vs.start ();
                    649: 
                    650:     FirstWindow.show ();
                    651:   }
                    652: }

Webmaster