For a University assignment I’m making a java implementation of Solving the Travelling Salesman Problem. I will be cutting out most of the code to make it less “busy” however if it no longer makes sense, please let me know.
To make it work I have a class which draws the window with all the UI;
//suitable imports
public class Window extends JFrame implements ActionListener
{
int gridX = 0;
int gridY = 0;
String[] xyLength =
{
"1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
"11", "12", "13", "14", "15", "16", "17", "18", "19", "20",
"21", "22", "23", "24", "25", "26", "27", "28", "29", "30",
"31", "32", "33", "34", "35", "36", "37", "38", "39", "40",
"41", "42", "43", "44", "45", "46", "47", "48", "49", "50"
};
Canvas canvas = new Canvas();
JPanel mainPanel = new JPanel();
JPanel westPanel = new JPanel(); //Panel on the left which houses controls
JComboBox<String> xSelectComboBox = new JComboBox<String>(xyLength);
JComboBox<String> ySelectComboBox = new JComboBox<String>(xyLength);
JButton redrawButton = new JButton(“Redraw”);
JButton generateButton = new JButton(“Generate”);
public static void main(String[] args)
{
new Window();
}
public Window()
{
super(“Travelling Salesman Problem”);
setSize(900, 620);
setResizeable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
mainPanel.setLayout(new BorderLayout());
mainPanel.add(canvas, BorderLayout.CENTER);
westPanel.add(xSelectComboBox);
westPanel.add(ySelectComboBox);
redrawButton.addActionListener(this);
westPanel.add(redrawButton);
generateButton.addActionListener(this);
westPanel.add(generateButton);
mainPanel.add(westPanel, BorderLayout.WEST);
add(mainPanel);
setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
Object source = e.getSource();
if(source.equals(redrawButton)
{
gridX = Integer.parseInt((xSelectComboBox.getSelectedItem()).toString());
gridY = Integer.parseInt((ySelectComboBox.getSelectedItem()).toString());
canvas.setXLength(gridX);
canvas.setYLength(gridY);
canvas.repaint();
}
if(source.equals(generateButton))
{
Algorithms.randomRoute(gridX, gridY);
}
}
}
I also have the Canvas class which contains the paint component;
//suitable imports
public class Canvas extends JPanel
{
int process = 0;
int xLength;
int yLength;
Node point = new Node();
public Canvas()
{
xLength = 0;
yLength = 0;
}
public void setProcess(int set)
{
process = set;
}
public void setXLength(int x)
{
xLength = x;
}
public void setYLength(int y)
{
yLength = y;
}
public setNode(Node n)
{
point.copy(n)
}
public void paintComponent(Graphics g)
{
super paintComponent(g);
switch(process)
{
case 0:
drawGrid(g);
break;
case 1:
point.draw(g);
break;
}
}
public void drawGrid(Graphics g)
{
//draws a grid based upon xLength and yLength
}
}
Thirdly I have a Node Object within which I want there to be a draw(g)
method;
//suitable imports
public class Node
{
protected int xCoordinate;
protected int yCoordinate;
protected boolean visitedFlag;
//skipping constructors, sets and gets
public void draw(Graphics g)
{
g.setColor(Color.red);
g.fillArc(xCoordinate, yCoordinate, 6, 6, 0 ,360);
}
}
Finally I have an Algorithm class which will contain all the different algorithms for solving the problem, including a random route generator;
//suitable imports
public class Algorithms
{
public void randomRoute(int xMax, int yMax)
{
nodeMax = 10;
Node[] point = new Node[nodeMax];
Random rand = new Random();
for(int i = 0; i < nodeMax; i++)
{
point[i] = new Node();
point[i].setXCoordinate(rand.nextInt(xMax);
point[i].setYCoordinate(rand.nextInt(yMax);
//insert drawing point[i] here
}
}
}
The issue is, I’d like to keep my processing code separate from the Window class, but be able to draw on the instance of Canvas that I declare within Window.
I also need to be able to refresh what is contained within paintComponent.
Any small issues within the code are as a result of me retyping it for the question
Thanks.
EDIT:
So I've modified the Canvas (now MyCanvas) class method setProcess;
public void setProcess(int set)
{
process = set;
repaint();
}
I also can take in an array of Nodes;
public void setNode(Node[] n, int nodesMax)
{
point = new Node[nodesMax];
nodeMax = nodesMax;
for(int i = 0; i < nodeMax - 1; i++)
{
point[i] = new Node();
point[i].copy(n[i]);
}
}
Finally, I also changed the switch case statement within paintComponent;
switch(process)
{
case 1:
drawGrid(g, this.xLength + 1, this.yLength + 1);
process = 0;
break;
case 2:
g.setColor(Color.red);
for(int i = 0; i < nodeMax; i++)
{
g.fillArc((this.point[i].xCoordinate + 30), (this.point[i].yCoordinate + 30), 100, 100, 0, 360);
}
process = 0;
break;
}
However, the repaint() within setProcess doesn't re-run paintComponent.
Any ideas where I'm going wrong?