2015-01-27 2 views
1

Exercise1609 : 화살표 키를 사용하여 선분을 그리는 프로그램을 작성하십시오. 선은 프레임의 중심에서 시작하여 오른쪽 화살표 키, 위쪽 화살표 키, 왼쪽 화살표 키 또는 아래쪽 화살표 키를 누르면 동쪽, 북쪽, 서쪽 또는 남쪽 방향으로 그립니다. 즉, 미로를 그립니다. 내 질문에 대한 설명은 아래의 의견을 참조하십시오.paintComponent() 내에서 x 좌표와 y 좌표를 초기화해야하는 이유는 무엇입니까?

import java.awt.*; 
    import java.awt.event.*; 
    import javax.swing.JFrame; 
    import javax.swing.JPanel; 

    public class Exercise1609 extends JFrame { 

     private KeyboardPanel panel = new KeyboardPanel(); 

     public Exercise1609() { 
      add(panel); 
      panel.setFocusable(true); 
     } 

     public static void main(String[] args) { 
      Exercise1609 frame = new Exercise1609(); 
      frame.setTitle("Tegn med piltaster"); 
      frame.setSize(600, 300); 
      frame.setLocationRelativeTo(null); 
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      frame.setVisible(true); 
     } 

     //The panel that listens for key and responds by drawing    
     public static class KeyboardPanel extends JPanel { 

      private int x,y,previousX,previousY; 
      private boolean firstTime = true; 

      public KeyboardPanel() { 

       /** 
       * why must x and y be initialized inside paintComponent? 
       * if I want to start drawing from the middle of the panel? 
       * If I remove the if-block inside paintComponent and instead 
       * place the initialization here, as shown with the two lines below: 
       * x = previousX = getWidth()/2; 
       * y = previousY = getHeight()/2; 
       * ...then the program will not start to draw from the middle, 
       * but upper left corner of the screen 
       */ 
       addKeyListener(new KeyAdapter() { 
        @Override 
        public void keyPressed(KeyEvent e) { 
         previousY = y; 
         previousX = x;   
         switch (e.getKeyCode()) { 
         case KeyEvent.VK_DOWN: 
          y++; 
          break; 
         case KeyEvent.VK_UP:   
          y--; 
          break; 
         case KeyEvent.VK_RIGHT: 
          x++; 
          break; 
         case KeyEvent.VK_LEFT: 
          x--; 
          break; 
         } 
         repaint(); 
        } 
       }); 
      }//end constructor 

      @Override 
      protected void paintComponent(Graphics g) { 
       super.paintComponents(g); 

       if(firstTime) { 
       //Why can't x and y be initialized outiside paintComponent? 
       //Why can't they be initialized inside the constructor of this class? 
       x = previousX = getWidth()/2; 
       y = previousY = getHeight()/2; 
       firstTime = false; 
       } 
       g.drawLine(previousX, previousY, x, y); 
       System.out.println(x + " " + y); 

      } 
     } 

    } 

마지막 줄 System.out.println(x + " " + y); 출력 I는 x와 y 다른 곳 만의 paintComponent()을 초기화하려고 0,0합니다. paintcomponent() 내에서 초기화 될 때 출력은 292,131 ... 내가 원하는 것입니다.

+0

읽어 보시기 바랍니다 [어떻게 숙제 질문을하고 답변을합니까? ] (http://meta.stackexchange.com/a/10812/235574) –

+0

아마도 getWidth() 및 getHeight()와 관련이 있습니다. 그 코드를 제공해 주시겠습니까? – adamdc78

답변

2

getWidth()getHeight()은 UI 요소가 레이아웃 단계를 통과 할 때까지 올바르게 설정되지 않습니다. 이것은 paintComponent()이 호출되기 전에 발생하지만, 호출하려고 시도한 다른 지점에서는 그렇지 않을 수도 있습니다.

참조 : getWidth() and getHeight() are 0 after calling setPreferredSize()

당신이 구성 요소의 폭과 높이를 설정/변경 될 때 통지 할 필요가있는 경우, ComponentListener 체크 아웃 : http://docs.oracle.com/javase/7/docs/api/java/awt/event/ComponentListener.html

+0

좌표를 설정하기 전에 수동으로 검증하면 문제가 해결 될 것이라고 생각하십니까? –

+0

당신은 "이것은 손님 보장이 아닙니다 ..."라고 말합니까? –

+0

@Vince Emigh :이 문제를 해결하려면 별도의 "문서"좌표계에서 선을 표시 할 좌표계를 그리는 것이 좋습니다. 그런 다음 패널을 문서의 뷰포트로 간주합니다. 이것은 아마 숙제에 대한 과잉이다. 그래서 나는 아마도 offsetX/offsetY를 추적하고 패널의 현재 중앙에서 (중심 + 오프셋)을 그릴 것이다. –

관련 문제