2014-02-13 2 views
0

대학 과제를 위해 나는 여행 판매원 문제 해결의 자바 구현을하고 있습니다. 더 이상 "바쁘다"고 생각하지 않으려면 대부분의 코드를 잘라낼 것입니다. 그러나 더 이상 이해가되지 않는다면 알려주십시오. 작동하도록하려면 모든 UI로 창을 그리는 클래스가 있어야합니다.다른 클래스에서 생성 된 paintComponent 객체에 드로잉

//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 클래스가 있습니다.

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

마지막으로 나는 무작위 경로 생성기를 포함하여 문제를 해결하기위한 모든 다른 알고리즘을 포함 할 Algorithm 클래스를 가지고 있습니다.

//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 클래스에서 별도의 내 처리 코드를 유지,하지만 난 창 내에서 선언 캔버스의 인스턴스에 그릴 수 있도록하고 싶습니다이다. 또한 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

클래스 Canvas으로 전화하지 마십시오. 그 이름의 AWT 클래스가 이미 있으므로 같은 이름을 사용하면 혼란을 야기 할 수 있습니다.

하지만 Window 내에서 선언 한 Canvas의 인스턴스를 그릴 수 있어야합니다.

다른 클래스의 도면을 외부로 지목하지 마십시오.

MyCanvas 클래스를 변경하려면 해당 클래스에 대한 참조가 있어야하며 필요에 따라 노드를 추가/제거 할 수있는 메소드를 만들어야합니다. 그런 다음 addNode/removeNode 메소드는 repaint()을 호출하고 MyCanvas 클래스는 자체를 다시 그립니다.

편집 :

process = set; 
repaint(); 
process = 0; 

당신은 그런 식으로 논리를 사용할 수 없습니다. 구성 요소의 페인팅이 완료되면 제어 할 수 없습니다.repaint() 메서드는 적절한 시간에 그림을 그리는 RepaintManager를 호출합니다. 따라서 paintComponent() 메서드가 호출 될 때까지 프로세스 변수는 0이됩니다. 코드에 System.out.println (...) 문을 추가하면이를 확인할 수 있습니다.

집합의 목적 ??? 메서드는 클래스의 속성을 변경하는 것입니다. 값을 그대로두고 0으로 재설정하지 마십시오.

+0

의견에 감사드립니다. 귀하의 의견을 이해하지만 다른 문제가 있습니다. 편집을 참조하십시오. – user3304183

+0

@ user3304183, 편집 참조. – camickr

+0

좋아요, 스위치 케이스 (편집 참조)의 각 프로세스가 끝날 때까지 "프로세스 = 0"을 이동 한 후 보았습니다. 감사! – user3304183

관련 문제