2013-06-20 11 views
2

Je suis en train d'animer l'arbre d'un traversal (BFS et DFS) à un JPanel en utilisant un timer et paintComponent ... Un peu comme si ...Traverse arbre basé sur la minuterie

enter image description here

En ce moment, l'algorithme BFS boucle instantanément tous les nœuds et peint les nœuds visités cyan ... Mais je voudrais permettre aux gens de voir comment l'arbre est traversé ... nœud par nœud ... Donc j'essaie ajouter une temporisation pour retarder la prochaine itération while loop ... Cela ne fonctionne pas du tout ...

Timer:

public void timer() { 
    int initialDelay = 1000; 
    timer.scheduleAtFixedRate(new TimerTask() { 
     public void run() { 
      if (cancelTimer) { 
       timer.cancel(); 
      } 
      if (counter == 3) { 
       //reset 
       counter = 0; 
      } 
      if (counter < 3) { 
       ++counter; 
       System.out.println(counter); 
      }  
     } 
    }, initialDelay, 1000); 
} 

paintComponent: redessine les noeuds comme ils traversèrent

public void paintComponent(Graphics g) { 
    g.setColor(Color.BLACK); 
    g.fillRect(0, 0, width, height); 

    g.setColor(rootNode.getColor()); 
    g.fillRect(rootNode.getX(), rootNode.getY(), rootNode.getWidth(), rootNode.getHeight()); 

    g.setColor(Color.WHITE); 
    g.drawString(rootNode.getValue(), rootNode.getX()+9, rootNode.getY()+16); 
    paintComponent(g, rootNode);  
} 

public void paintComponent(Graphics g, Nodes parentNode) { 
    //keep generating new nodePrintList to load with new Children 
    ArrayList<Nodes> nodePrintList = new ArrayList<Nodes>();  

    //base case: end of nodeList 
    if (nodeList.indexOf(parentNode)==nodeList.size()-1) { 
     System.out.println("\nend"); 
    } 
    else { 
    //traverse nodeList recursively 
     nodePrintList = getChildren(parentNode);  
     //loop through and print all children of node n 
     //System.out.println(); 
     int x = parentNode.getX()-50; 

     for (Nodes child : nodePrintList) {    
      g.setColor(child.getColor()); 
      child.setX(x); 
      child.setY(parentNode.getY()+50); 
      g.fillRect(child.getX(), child.getY(), child.getWidth(), child.getHeight());   
      g.setColor(Color.WHITE); 
      g.drawString(child.getValue(), child.getX()+9, child.getY()+16); 
      x+=50; 
      //System.out.print("PARENT: " + parentNode.getValue() + " | x,y: " + parentNode.getX() + ", " + parentNode.getY() + "...\n CHILD: " + child.getValue() + " | x,y: " + child.getX() + ", " + child.getY()); 
      paintComponent(g, child); 
      g.drawLine(parentNode.getX()+10, parentNode.getY()+23, child.getX()+10, child.getY()); 
     }   
    } 
    repaint(); 

} 

BFS():

public void bfs() { 

    Queue q = new LinkedList(); 
    q.add(rootNode); 
    rootNode.visited(true); 
    rootNode.setColor(Color.cyan); 
    printNode(rootNode); 
    //only perform check when counter = 10; 
    while (!q.isEmpty()) {   
     Nodes n = (Nodes)q.remove(); 
     Nodes child = null; 
     //put all unvisited children in the queue 
     while ((child = getUnvisitedChildNode(n)) != null) 
     {   
      if (counter == 3) { 
       child.visited(true); 
       printNode(child); 
       q.add(child); 
       child.setColor(Color.cyan); 
      } 
     } 
    } 
    if (q.isEmpty()) { 
     cancelTimer = true; 
     //RepaintManager.currentManager(this).markCompletelyClean(this); 
    } 
} 

Toute pensée? Merci!

+0

Avez-vous un objet de minuterie avec le même nom en fonction? Ceci n'est probablement pas la meilleure pratique .... – bcrawford

+0

1. util.Timer peut être utilisé pour AWT Canvas/Panel, mais pas pour JPanel avec paintComponent, utilisez le timer 2. ne jamais toucher le RepaintManager dans Swing, mais est possible et je l'ai utilisé, – mKorbel

Répondre

3

Vous pouvez, par exemple, créer un Queue<Nodes> qui acceptera les nœuds à peindre. A savoir, dans votre méthode bfs(), où vous définissez la couleur child.setColor(Color.cyan); ajoutez ce nœud à un Queue. Alors:

if (counter == 3) { 
    child.visited(true); 
    printNode(child); 
    q.add(child); 
    paintQueue.add(child); 
} 

Et dans la minuterie à délai fixe, poll cette file d'attente et peindre le nœud:

timer.scheduleAtFixedRate(new TimerTask() { 
    public void run() { 
     if (!paintQueue.isEmpty()) { 
      Nodes node= paintQueue.poll(); 
      node.setColor(Color.cyan); 
     }  
    } 
}, initialDelay, 1000); 
+0

Vous êtes le meilleur! – Growler

Questions connexes