/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.graphviz; import java.util.ArrayList; /** * A helper class for creating record shaped nodes. * * @author Hannu Niemistö */ public class Record { static class IdentifiableField { String id; String label; public IdentifiableField(String id, String label) { super(); this.id = id; this.label = label; } } static class Field { String label; public Field(String label) { super(); this.label = label; } } ArrayList fields = new ArrayList(); boolean rotated = false; public Record() { } /** * Adds a simple nonreferable field to a record. */ public void add(String label) { fields.add(new Field(label)); } /** * Adds a field to a record that can be referred in * connections. Example *
     *   Record r = new Record();
     *   r.add("A field");
     *   r.add("id1", "An another field");
     *   Node n1 = r.toField(g);
     *   Node n2 = new Node(g2);
     *   new Edge(n1.getPort("id1"), n2);
     * 
*/ public void add(String id, String label) { fields.add(new IdentifiableField(id, label)); } /** * Puts a record inside this record. This is most useful * if the record added is rotated. In this way, one can * build records that both horizontally and vertically * divided areas. */ public void add(Record record) { fields.add(record); } /** * Creates a node whose shape is build according to the * record definition. */ public Node toNode(Graph g) { Node node = new Node(g); node.setShape("record"); StringBuilder b = new StringBuilder(); toString(b); node.setLabel(b.toString()); return node; } private void toString(StringBuilder b) { if(rotated) b.append('{'); for(int i=0;i 0) b.append('|'); if(f instanceof Field) { Field ff = (Field)f; b.append(ff.label); } else if(f instanceof IdentifiableField) { IdentifiableField ff = (IdentifiableField)f; b.append('<'); b.append(ff.id); b.append('>'); b.append(ff.label); } else if(f instanceof Record) { ((Record)f).toString(b); } } if(rotated) b.append('}'); } /** * Tells if the record has opposite orientation from * its surroundings. If the record is converted into * node, this means the rankdir of the graph. If * the record is put inside other record, then rotation * is relative to the orientation of the parent record. */ public void setRotated(boolean rotated) { this.rotated = rotated; } }