2013-06-24 2 views
3

Я создаю программу обхода дерева, которая позволяет пользователям запускать обходы BFS и DFS, а также добавлять и удалять узлы.Создайте новый узел на JPanel с помощью SSCCE

До сих пор я был в состоянии обновить матрицу смежности, когда кто-то щелкает, чтобы добавить новый дочерний узел к родителю:

enter image description here

Затем я нажимаю Add Node, который добавляет Z родительского A:

enter image description here

Вы можете видеть, что матрица смежности присоединяет Z переда ... но я ожидаю узел Z появляться на левой стороне дерева, а также.

Я думаю, что проблема в обновленном nodeList не отправляется в цикл paintComponent() для рисования ... поэтому он не отображается.

Вот SSCCE моей программы:

import java.util.ArrayList; 

import java.util.Arrays; 
import java.util.List; 
import java.util.Scanner; 

import javax.swing.JFrame; 

public class MainSSCCE extends JFrame { 
    static MainSSCCE run; 
    int amount, nodeWidth, nodeHeight; 
    GraphSSCCE g; 
    JFrame f; 

public MainSSCCE(){ 
    f = new JFrame("DTurcotte's Graph Traversals"); 
    g = new GraphSSCCE(450, 300); 
    f.add(g); 
    f.setSize(g.getWidth(),g.getHeight()); 
    f.setVisible(true); 
    nodeWidth = 25; 
    nodeHeight = 25; 
    f.setResizable(false); 
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   
} 

public static void main(String[] args) { 
    run = new MainSSCCE(); 
} 

} 

График:

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.TextField; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.ArrayList; 
import javax.swing.JButton; 
import javax.swing.JComboBox; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 

public class GraphSSCCE extends JPanel { 
    ArrayList<NodesSSCCE> nodeList; 
    public int[][] adjMatrix; 
    NodesSSCCE rootNode; 
    int size, height, width, x, y, counter; 
    Color color; 
    String message = "", run = "", nodeVal = ""; 
    JButton AddButton; 
    JLabel label; 

    int nodeX = 180, nodeY = 100, nodeWidth, nodeHeight; 

    TextField child; 
    JComboBox parents; 

public GraphSSCCE(int w, int h) { 
    height = h; 
    width = w; 
    nodeList = new ArrayList<NodesSSCCE>(); 

    nodeWidth = 25; 
    nodeHeight = 25; 

    AddButton = new JButton("Add Node"); 
    label = new JLabel("to parent"); 
    label.setForeground(Color.WHITE); 

    child = new TextField(1); 
    parents = new JComboBox(); 

    add(AddButton); 
    add(child); 
    add(label); 
    add(parents); 


    NodesSSCCE nA = new NodesSSCCE("A", nodeX, nodeY, nodeWidth, nodeHeight); 
    NodesSSCCE nB = new NodesSSCCE("B", nodeX, nodeY, nodeWidth, nodeHeight); 
    NodesSSCCE nC = new NodesSSCCE("C", nodeX, nodeY, nodeWidth, nodeHeight); 

    addNode(nA); 
    addNode(nB); 
    addNode(nC); 

    setRootNode(nA); 
    connectNode(nA, nB); 
    connectNode(nA, nC); 


    for (NodesSSCCE n : nodeList) { 
     parents.addItem(n.getValue()); 
    } 

    //send in selected parent from combo box 
    AppendChildren ac = new AppendChildren(child); 
    this.child.addActionListener(ac); 
    this.AddButton.addActionListener(ac); 

} 

class AppendChildren implements ActionListener {  
    private TextField child;  
    public AppendChildren(TextField child) { 
    this.child = child; 
    } 
    public void actionPerformed(ActionEvent ae) { 
     String childName = child.getText(); 
     NodesSSCCE newChild = new NodesSSCCE(childName, nodeX, nodeY, nodeWidth, nodeHeight); 
     appendNode(rootNode, newChild); 
    } 
} 


public int getHeight() { 
    return height; 
} 
public int getWidth() { 
    return width; 
} 


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, NodesSSCCE parentNode) { 
    ArrayList<NodesSSCCE> nodePrintList = new ArrayList<NodesSSCCE>(); 

    if (nodeList.indexOf(parentNode)==nodeList.size()) { 
     System.out.println("\nend"); 
    } 
    else { 
     nodePrintList = getChildren(parentNode);  
     int x = parentNode.getX()-50; 

     //PAINT TREE: THIS IS NOT PAINTING THE NEWLY APPENDED NODE 
     for (NodesSSCCE 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; 
      paintComponent(g, child); 
      g.setColor(child.getColor()); 
      g.drawLine(parentNode.getX()+10, parentNode.getY()+23, child.getX()+10, child.getY()); 
     } 

     //PAINT ADJACENCY MATRIX 
     for (int i = 0; i < adjMatrix.length; i++) { 
      for (int j = 0; j < adjMatrix[i].length; j++) { 
       g.setColor(Color.white); 
       g.drawString("" + adjMatrix[i][j], (i*19)+350, (j*19)+100); 

       g.setColor(Color.gray); 
       g.drawString("" + nodeList.get(i).getValue(), (i*19)+350, 75); 
      } 
      g.drawString("" + nodeList.get(i).getValue(), 325, (i*19)+100); 
     }  
    } 
} 

public void setRootNode(NodesSSCCE n) { 
    rootNode = n; 
} 

public NodesSSCCE getRootNode() { 
    return rootNode; 
} 

public void addNode(NodesSSCCE n) { 
    nodeList.add(n); 
} 

public void appendNode(NodesSSCCE parent, NodesSSCCE child) { 
    //add new node X to nodeList 
    addNode(child); 

    int newSize = nodeList.size(); 

    //make a new adj matrix of the new size... 
    int[][] adjMatrixCopy = new int[newSize][newSize]; 

    int fromNode = nodeList.indexOf(parent); 
    int toNode = nodeList.indexOf(child); 

    //copy adjMatrix data to new matrix... 
    for (int i = 0; i < adjMatrix.length; i++) {  
     for (int j = 0; j < adjMatrix[i].length; j++) { 
      adjMatrixCopy[i][j] = adjMatrix[i][j]; 
     } 
    } 

    adjMatrixCopy[fromNode][toNode] = 1; 
    adjMatrix = adjMatrixCopy; 
    repaint(); 
} 

public void connectNode(NodesSSCCE from, NodesSSCCE to) 
{ 
    if(adjMatrix == null) { 
     size = nodeList.size(); 
     adjMatrix = new int[size][size]; 
    } 

    int fromNode = nodeList.indexOf(from); 
    int toNode = nodeList.indexOf(to); 

    adjMatrix[fromNode][toNode] = 1; 
} 

public ArrayList<NodesSSCCE> getChildren (NodesSSCCE n) { 
    ArrayList<NodesSSCCE> childrenList; 
    childrenList = new ArrayList<NodesSSCCE>(); 
    int index = nodeList.indexOf(n); 
    int col = 0; 

    while (col < size) { 
     if (adjMatrix[index][col] == 1) { 
      childrenList.add(nodeList.get(col)); 
     } 
     col++; 
    } 
    return childrenList; 
} 

} 

Вершины Класс:

import java.awt.Color; 
import java.awt.Graphics; 

public class NodesSSCCE { 
    Boolean visited; 
    String val; 
    Color color; 
    int xLoc, yLoc, width, height; 

public NodesSSCCE(String s, int x, int y, int w, int h) { 
    visited = false; 
    val=s; 
    xLoc = x; 
    yLoc = y; 
    width = w; 
    height = h; 
    color = Color.gray; 
} 

public int getHeight() { 
    return height; 
} 
public int getWidth() { 
    return width; 
} 

public int getX() { 
    return xLoc; 
} 
public int getY() { 
    return yLoc; 
} 

public void setX(int x) { 
    xLoc = x; 
} 
public void setY(int y) { 
    yLoc = y; 
} 


public void visited(Boolean v) { 
    visited = v; 
} 

public String getValue() { 
    return val; 
} 

public void setValue(String value) { 
    val = value; 
} 

public void setColor (Color c) { 
    color = c; 
} 

public Color getColor() { 
    return color; 
}  
} 
+0

Вместо того, чтобы запрашивать панель для перерисовки, запросите рамку. –

+1

@ DaftPunk вы можете уточнить? Все изменения происходят на панели, нет? Во всяком случае, чтобы сделать это, я просто делал бы 'super.repaint()', где бы изменения в классе «graph» не были правильно? – Growler

+0

рад, что у вас это получилось наконец :-) в любом случае, повторяя мой комментарий с другого вопроса: еще одна вещь, которую вы не должны делать, - это изменение состояния окрашенного компонента/данных во время рисования (как вам кажется, в paintComponent (g, родительский), вызвав child.setX) - вместо этого полностью обновите состояние дерева и переименуйте его в конце изменения. – kleopatra

ответ

3

N ope, игнорировать мой комментарий.

Вы забываете обновить size правильно.

В GraphSSCCE, перейти по методу getChildren(NodesSSCCE) и изменить условие цикла от col < size к col < nodeList.size().

Возможность отладки собственных программ может сэкономить много времени.

+0

О, человек, который заводил меня в течение нескольких дней! Как я этого не видел ?! хаха спасибо! – Growler