Reputation: 12718
I'm building a Tree traversal program which allows users to run BFS and DFS traversals, as well as add and remove nodes.
So far I've been able to update the adjacency matrix when someone clicks to add a new child node to a parent:
Then I click Add Node
, which adds Z to parent A:
You can see that the adjacency matrix appends Z to A... but I'm expecting the node Z
to appear on the left side tree as well.
I think the problem is the updated nodeList
is not being sent to paintComponent()
loop for painting... so it's not being shown.
Here is a SSCCE of my program:
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();
}
}
Graph:
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;
}
}
Nodes class:
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;
}
}
Upvotes: 3
Views: 230
Reputation:
Nope, ignore my comment.
You forget to update size
correctly.
In the GraphSSCCE
, go to method getChildren(NodesSSCCE)
and change the loop condition from col < size
to col < nodeList.size()
.
Being able to debug your own programs can save a lot of time.
Upvotes: 3