2016-05-09 22 views
3

Ich habe ein einfaches Programm, das verteilte Umgebung simuliert. Ich möchte das Prozessorverhalten mithilfe der GraphStream-Bibliothek visualisieren. Jeder Prozessor ist ein Thread, sie einige Berechnungen zu tun, aber nicht die ganze Zeit, nur dann, wenn ich die switch VariableVisualisierung des Graphen

while(running){ 
    if(switch) 
    computate(); 
} 

Ich habe eine Klasse geschrieben, den processorList nehmen und Graphvisualisierung vorzubereiten. Es gibt eine Funktion für diese Aufgabe

public void adjustBFSGraph2(){ 
    for(Edge e: this.g.getEdgeSet()) 
    { 
     e.clearAttributes(); 
    } 
    try { 
     Thread.sleep(2000); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    for(Processor p : processorList) 
    { 
     p.getNode().setAttribute("ui.label", "Pid" +" " + p.getPID() +" "+"Dist: " + p.getFieldValue("bfs") + " " + "Parent" + " " + p.getFieldValue("parent")); 
     if(!p.getFieldValue("parent").equals("-1")) 
     { 
      Edge e = p.getNode().getEdgeBetween(p.getFieldValue("parent")); 
      if(e != null) 
      { 
       e.setAttribute("ui.color", p.getColor()); 
       e.setAttribute("ui.label", "added" + p.getPID()); 

      } 
     } 
    } 
} 

Mein Problem ist, dass ich Farben auf Kanten nur für Blinzeln des Auges und dann Farbe disapear sehen. Es sieht so aus, als ob es das Attribut "ui.color" hinzufügt und es in der gleichen Schleife entfernt, aber wie ist es möglich? @update Ich habe meinen Code bearbeitet, jetzt kann ich sehen, Kanten für die Zeit in thread.sleep() nach der ersten Schleife, gut, ich verstehe nicht, warum nach dem Löschen aller Attribute kann ich sie tatsächlich sehen. hier ist, wie ich meine Funktion

bin Aufruf
while(true) 
      { i++; 
//if any processor is not runing 
       boolean aux = false; 
       while(!aux) { 
        for (Processor proc : s.processorList) { 
         aux = aux || proc.isEnabled(); 
        } 
        aux = !aux; 
       } 
       s.gp.adjustBFSGraph(); 
       Thread.sleep(5000); 
       for(Processor proc: s.processorList) 
       { 
        proc.enable(); 
       } 
      } 

Wenn Thread.sleep() innerhalb Funktion einstellen, um weniger als 100 ms gesetzt, es wieder zu blinken beginnt.

Weil es ein wenig unklar sein kann, was ich tue ich kleinere Beispiel erstellt haben

Dies entspricht meiner Prozessorklasse

public class SomeObjectWithNode { 
    public Node n; 
    public Color c; 
    public SomeObjectWithNode(Node n) 
    { 
     Random rand = new Random(); 
     float r = rand.nextFloat(); 
     float g = rand.nextFloat(); 
     float b = rand.nextFloat(); 
     Color randomColor = new Color(r, g, b); 
     c = randomColor; 
     this.n = n; 
    } 

} 

Hier ist eine Klasse Hexe Änderung Graph Styling/es Zeichnung

public class TestDraw { 
    Vector<SomeObjectWithNode> n; 
    Graph g; 
    public TestDraw(Vector<SomeObjectWithNode> k, Graph g) 
    { 
     this.g= g; 
     this.n = k; 
    } 
    public void adjust() 
    { 
     Random rand = new Random(); 
     for(Edge e: g.getEdgeSet()) 
     { 
      e.clearAttributes(); 
     } 
     for(SomeObjectWithNode k: n) 
     { 
      k.n.addAttribute("ui.color", k.c); 
      for(Edge e: k.n.getEdgeSet()) 
      { 
       float r = rand.nextFloat(); 
       float g = rand.nextFloat(); 
       float b = rand.nextFloat(); 
       Color randomColor = new Color(r, g, b); 
       e.addAttribute("ui.color", randomColor); 
      } 
     } 
    } 
} 

und hier ist Hauptklasse

public class TestGs { 

     public static void main(String[] args) { 
      Node lastNode; 
      TestDraw t; 
      Vector<SomeObjectWithNode> a = new Vector<SomeObjectWithNode>(); 
      System.setProperty("gs.ui.renderer", "org.graphstream.ui.j2dviewer.J2DGraphRenderer"); 
      Graph g = new SingleGraph("test1"); 
      g.display(); 
      g.addAttribute("ui.stylesheet", "node { fill-mode: dyn-plain; size: 10px;} edge { fill-mode: dyn-plain; size: 2px;}"); 
      a.add(new SomeObjectWithNode(g.addNode(Integer.toString(0)))); 
      lastNode = g.getNode("0"); 
      for(int i = 1; i < 10; i++) 
      { 
       a.add(new SomeObjectWithNode(g.addNode(Integer.toString(i)))); 
       g.addEdge(Integer.toString(i-1).concat(Integer.toString(i)), a.get(i).n, lastNode); 
       lastNode = a.get(i).n; 
      } 
      t = new TestDraw(a,g); 
      while(true) 
      { 
       t.adjust(); 
       try { 
        Thread.sleep(3000); 
       } catch (InterruptedException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 

     } 

    } 

Wenn ich laufe Beispiel können wir Graph hat Farben nur für das Blinzeln des Auges statt Anzeige für Zeit in Thread.sleep()

+0

Irgendwelche Kommentare von Ihrer Seite? –

+0

Ich habe meine Antwort korrigiert Ich hoffe, das ist es, was Sie suchen –

Antwort

1

Das Hauptproblem ist e.clearAttributes(); in Verfahren adjust() sehen. Sie entfernen ALLE Attribute nicht nur "ui.color". Sie können stattdessen e.setAttribute("ui.color", randomColor);e.addAttribute("ui.color", randomColor); verwenden und Block mit e.clearAttributes() überhaupt entfernen (siehe Original example Nummer 2).

Ich habe Ihren Code entsprechend geändert und meine Kommentare auf gist.github geteilt. Jetzt ändert sich die Farbe alle 2 Sekunden.

PS: jetzt wegen der Ursache der Blinken. Ich hatte eine kurze Untersuchung des GraphStream-Quellcodes (viel Java-Code, sorry). AbstractElement.java (nur interessante Methoden):

public void clearAttributes() { 
      if (attributes != null) { 
       for (Map.Entry<String, Object> entry : attributes.entrySet()) 
        attributeChanged(AttributeChangeEvent.REMOVE, entry.getKey(), 
          entry.getValue(), null); 

       attributes.clear(); 
      } 
     } 
... 
    public void setAttribute(String attribute, Object... values) { 
     addAttribute(attribute, values); 
    } 
... 
    public void addAttribute(String attribute, Object... values) { 
     if (attributes == null) 
      attributes = new HashMap<String, Object>(1); 

     Object oldValue; 
     Object value; 
     if (values.length == 0) 
      value = true; 
     else if (values.length == 1) 
      value = values[0]; 
     else 
      value = values; 

     AttributeChangeEvent event = AttributeChangeEvent.ADD; 
     if (attributes.containsKey(attribute)) // In case the value is null, 
      event = AttributeChangeEvent.CHANGE; // but the attribute exists. 

     oldValue = attributes.put(attribute, value); 
     attributeChanged(event, attribute, oldValue, value); 
    } 
... 

Wie Sie setAttribute sehen und addAttribute ist wirklich ähnlich. Jetzt attributeChanged() -Implementierung in GraphicElement.java:

@Override 
    protected void attributeChanged(AttributeChangeEvent event, 
      String attribute, Object oldValue, Object newValue) { 
     if (event == AttributeChangeEvent.ADD 
       || event == AttributeChangeEvent.CHANGE) { 
      if (attribute.charAt(0) == 'u' && attribute.charAt(1) == 'i') { 
       if (attribute.equals("ui.class")) { 
        mygraph.styleGroups.checkElementStyleGroup(this); 
        // mygraph.styleGroups.removeElement(tis); 
        // mygraph.styleGroups.addElement(this); 
        mygraph.graphChanged = true; 
       } else if (attribute.equals("ui.label")) { 
        label = StyleConstants.convertLabel(newValue); 
        mygraph.graphChanged = true; 
       } else if (attribute.equals("ui.style")) { 
        // Cascade the new style in the style sheet. 

        if (newValue instanceof String) { 
         try { 
          mygraph.styleSheet.parseStyleFromString(
            new Selector(getSelectorType(), getId(), 
              null), (String) newValue); 
         } catch (Exception e) { 
          logger.log(Level.WARNING, String.format("Error while parsing style for %S '%s' :", getSelectorType(), getId()), e); 
         } 
         mygraph.graphChanged = true; 
        } else { 
         logger.warning("Unknown value for style [" + newValue + "]."); 
        } 
       } else if (attribute.equals("ui.hide")) { 
        hidden = true; 
        mygraph.graphChanged = true; 
       } else if (attribute.equals("ui.clicked")) { 
        style.pushEventFor(this, "clicked"); 
        mygraph.graphChanged = true; 
       } else if (attribute.equals("ui.selected")) { 
        style.pushEventFor(this, "selected"); 
        mygraph.graphChanged = true; 
       } else if (attribute.equals("ui.color")) { 
        style.pushElementAsDynamic(this); 
        mygraph.graphChanged = true; 
       } else if (attribute.equals("ui.size")) { 
        style.pushElementAsDynamic(this); 
        mygraph.graphChanged = true; 
       } else if (attribute.equals("ui.icon")) { 
        mygraph.graphChanged = true; 
       } 
       // else if(attribute.equals("ui.state")) 
       // { 
       // if(newValue == null) 
       // state = null; 
       // else if(newValue instanceof String) 
       // state = (String) newValue; 
       // } 
      } else if (attribute.equals("label")) { 
       label = StyleConstants.convertLabel(newValue); 
       mygraph.graphChanged = true; 
      } 
     } else // REMOVE 
     { 
      if (attribute.charAt(0) == 'u' && attribute.charAt(1) == 'i') { 
       if (attribute.equals("ui.class")) { 
        Object o = attributes.remove("ui.class"); // Not yet removed 
                   // at 
                   // this point ! 
        mygraph.styleGroups.checkElementStyleGroup(this); 
        attributes.put("ui.class", o); 
        mygraph.graphChanged = true; 
       } else if (attribute.equals("ui.label")) { 
        label = ""; 
        mygraph.graphChanged = true; 
       } else if (attribute.equals("ui.hide")) { 
        hidden = false; 
        mygraph.graphChanged = true; 
       } else if (attribute.equals("ui.clicked")) { 
        style.popEventFor(this, "clicked"); 
        mygraph.graphChanged = true; 
       } else if (attribute.equals("ui.selected")) { 
        style.popEventFor(this, "selected"); 
        mygraph.graphChanged = true; 
       } else if (attribute.equals("ui.color")) { 
        style.popElementAsDynamic(this); 
        mygraph.graphChanged = true; 
       } else if (attribute.equals("ui.size")) { 
        style.popElementAsDynamic(this); 
        mygraph.graphChanged = true; 
       } 
      } else if (attribute.equals("label")) { 
       label = ""; 
       mygraph.graphChanged = true; 
      } 
     } 
    } 

Hinweis: Wie Sie sehen können, wenn Sie klaren Attribute, wird dynamischer Stil hinzugefügt werden/entfernt von Methoden popElementAsDynamic/pushElementAsDynamic. Und implementiert diese Methoden in StyleGroup.java: Gut

 /** 
    * Indicate the element has dynamic values and thus cannot be drawn in bulk 
    * operations. Called by the GraphicElement. 
    * 
    * @param element 
    *   The element. 
    */ 
    protected void pushElementAsDynamic(Element element) { 
     if (dynamicOnes == null) 
      dynamicOnes = new HashSet<Element>(); 

     dynamicOnes.add(element); 
    } 

    /** 
    * Indicate the element has no more dynamic values and can be drawn in bulk 
    * operations. Called by the GraphicElement. 
    * 
    * @param element 
    *   The element. 
    */ 
    protected void popElementAsDynamic(Element element) { 
     dynamicOnes.remove(element); 

     if (dynamicOnes.isEmpty()) 
      dynamicOnes = null; 
    } 

wenn wir/setAttribute fügen wir nur neue Elemente in existierte hashmap hinzuzufügen. Wenn wir clearAttributes verwenden, erstellen wir neue Instanzen HashMap für dynamicOnes. Wahrscheinlich haben wir in diesem Fall ein Synchronisationsproblem und das ist der Grund für das Blinken.

+0

Ich akzeptiere es, aber es sagt nicht, warum das Entfernen von Attributen und das Hinzufügen später zu einem blinkenden Effekt – whd

+0

@whd hinzugefügt PS Teil, bitte überprüfen –