2016-10-28 3 views
1

저는 대학에서 타원을 그리고 버튼을 한 번만 누르면 화면에서 단계적으로 움직이게하는 임무가 있습니다. 내가 때마다 여전히 타원은 위치를 그리지 않고 마지막 반복에 정의 된 지점으로 원점에서 근본적으로 이동주기() 함수 다시 그리기를 호출하지만Java에서 키를 한 번 눌러 모양 이동을 만드는 방법은 무엇입니까?

public class Window extends JPanel { 

private static Ellipse2D.Double Ellipse; 
private JFrame frame; 

public Window() { 
    super(); 
    int width = 20; 
    int height = 30; 
    Ellipse = new Ellipse2D.Double(width, height, 100, 50);   
} 

public Dimension getPreferredSize() 
{ 
    return (new Dimension(frame.getWidth(), frame.getHeight())); 
} 

@Override 
public void paintComponent(Graphics g) { 
    super.paintComponents(g); 
    Graphics2D brush = (Graphics2D) g; 
    int width = getWidth(); 
    int height = getHeight(); 
    g.clearRect(0, 0, width, height); 
    brush.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
    brush.draw(Ellipse); 
} 
public class MoveCircle implements KeyListener, ActionListener { 

    @Override 
    public void keyPressed(KeyEvent e) { 
     System.out.println("Working on top!"); 
     double newX = 0; double newY = 0; 
     if (e.getKeyCode() == Event.ENTER) {     
      for (int i = 0; i < 26; i ++) 
      { 
       System.out.println("Working on bottom!"); 
       newX = Ellipse.x + 10; 
       Ellipse.x = newX; 
       newY = Ellipse.y + 10; 
       Ellipse.y = newY; 
       repaint();     
      }     
     } 
    } 

    @Override 
    public void keyReleased(KeyEvent e) { 
     // TODO Auto-generated method stub 
    } 

    @Override 
    public void keyTyped(KeyEvent e) { 
     // TODO Auto-generated method stub 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     // TODO Auto-generated method stub 

    } 
} 
private void createAndDisplayGUI(Window window) 
{ 
    frame = new JFrame(); 
    Container container = frame.getContentPane();  
    container.add(window); 
    window.addKeyListener(new MoveCircle());   
    frame.setSize(400, 400); 
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
    frame.setVisible(true); 
    window.requestFocusInWindow(); 
} 

public static void main(String[] args) { 
    SwingUtilities.invokeLater(new Runnable() 
    { 
     public void run() 
     { 
      Window window = new Window(); 
      window.createAndDisplayGUI(window); 
     } 
    }); 
} 

}

: 여기 내 코드입니다 각 반복에서 타원의. 스윙 타이머를 사용하여 각 반복에서 타원을 다시 칠할 수 있습니까? 나는 이것에 도움을받는 것이 매우 기쁘다.

+1

아래에 조립 한대로, 스윙 타이머와 함께이 문제를 해결할 수있다''TimerTask' 여러 번 사용할 수 없습니다 –

+2

@ RomanGräf : EDT에서 잠을 자지 마라. _do_ [* 스윙 타이머 사용 방법 *] (http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html)을 참조하십시오. – trashgod

답변

3

두 가지 문제가 있습니다. 첫 번째는 루프가 UI 스레드에서 실행되고 있다는 것입니다. 두 번째는 페인트 칠하는 법에 대한 오해입니다. 모든 다시 칠함은 반환하기 위해 UI 스레드에 요청을 추가합니다. 그것은 그 자체로 다시 그리기를 수행하지 않습니다. 따라서 UI 스레드에서 작업을 실행하는 경우 여러 번 호출해도 아무런 효과가 없습니다. 당신이 제안한 것처럼 내가 당신`에 Thread.sleep()를 사용할 수 있습니다

ActionListener al = new ActionListener() { 
    int iterations = 0; 
    public void actionPerformed(ActionEvent ae) { 
      if (iterations == 25) { 
      timer.stop(); 
      } 
      interations++; 
      System.out.println("Working on bottom!"); 
      newX = Ellipse.x + 10; 
      Ellipse.x = newX; 
      newY = Ellipse.y + 10; 
      Ellipse.y = newY; 
      repaint();     
    } 
}; 

final timer = new javax.swing.Timer(delay, al); 
timer.start(); 
+1

어리석은 질문에 사과 드려 죄송합니다. 스윙을 사용하는 첫 번째 프로젝트 중 하나입니다. 그래서 어떤 방법으로 특별히 작성해야합니까? –

+0

그것은 루프 코드가 나오는 keyPressed 메소드에 있어야합니다. 또한, 제시 한 코드에서 Timer.stop()에 대한 호출을 생략했습니다. 26 회 반복 한 후에 타이머를 .stop()해야합니다. – ControlAltDel

+0

인내심을 가져 주셔서 감사합니다. 정말 도움이되었습니다. 다시 감사합니다. –

관련 문제