2013-06-20 2 views
2

Я пытаюсь оживить обход дерева (BFS и DFS) на JPanel с помощью timer и paintComponent ... вроде как так ...траверсы дерева, основанные на таймер

enter image description here

Прямо сейчас алгоритм BFS мгновенно проходит все узлы и краски посещенных узлов cyan ... Но я хочу, чтобы люди могли видеть, как проходит дерево ... узел за узлом ... Поэтому я пытаюсь чтобы добавить таймер к задержке при следующем while loop итерационных запусков ... Он вообще не работает ...

Таймер:

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: перерисовывает узлы, как они пересекли

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); 
    } 
} 

Есть мысли? Благодаря!

+0

У вас есть объект таймера с тем же именем, как функция? Это, вероятно, не самая лучшая практика .... – bcrawford

+0

1. util.Timer может использоваться для AWT Canvas/Panel, но не для JPanel с paintComponent, используйте Swing Timer 2. никогда не прикасаться к RepaintManager в Swing, но возможно, и я использовал это, – mKorbel

ответ

3

Вы можете, например, создать Queue<Nodes>, который будет принимать узлы для рисования. А именно, в вашем методе bfs(), где вы установили цвет child.setColor(Color.cyan);, добавьте этот узел в Queue. Итак:

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

И в таймере, при фиксированной задержке, poll эта очередь и окрасить узел:

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

Ты лучший! – Growler