对于大学作业,我正在制作解决旅行商问题的Java实现。我将删除大部分代码,使其不那么“繁忙”,但如果它不再有意义,请告诉我。 为了使它工作,我有一个用所有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);
}
}
}
我还有Canvas类,它包含paint组件;
//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
}
}
第三,我有一个节点对象,我希望在那里有一个draw(g)
方法;
//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);
}
}
最后我有一个算法类,它将包含解决问题的所有不同算法,包括随机路由生成器;
//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
}
}
}
问题是,我想将我的处理代码与Window类分开,但是能够在Window中声明的Canvas实例上绘制。 我还需要能够刷新paintComponent中包含的内容。
代码中的任何小问题都是我为问题重新输入的结果
感谢。
编辑: 所以我修改了Canvas(现在的MyCanvas)类方法setProcess;
public void setProcess(int set)
{
process = set;
repaint();
}
我也可以接受一组节点;
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]);
}
}
最后,我还更改了paintComponent中的switch case语句;
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;
}
但是,setProcess中的repaint()不会重新运行paintComponent。 我出错的任何想法?
答案 0 :(得分:0)
请勿致电您的班级Canvas
。这个名称的AWT类已经存在,因此使用相同的名称会引起混淆。
但是能够在Window中声明的Canvas实例上绘制。
不要在另一个类中外部绘图。
相反,如果要对MyCanvas
类进行更改,则需要引用该类,并且需要创建允许根据需要添加/删除节点的方法。然后addNode / removeNode方法只会调用repaint(),而MyCanvas
类将重新绘制自己。
编辑:
process = set;
repaint();
process = 0;
你不能使用这样的逻辑。您无法控制何时完成组件的绘制。 repaint()方法调用RepaintManager,它将在适当的时间进行绘制。因此,在调用paintComponent()方法时,流程变量将为0.只需在代码中添加System.out.println(...)语句即可验证。
一套的目的???方法是更改类的属性。所以只保留值,不要将其重置为0.