2017-10-02 5 views
0

현재 작은 코딩 프로젝트에서 작업 중이며 문제가 있습니다. 나는 과거의 일을 살펴 봤는데 왜이 프로그램이 페인트 법을 부르지 않는지 알아낼 수 없다. 현재 프레임에 원을 그리려하고 있습니다.객체 클래스가 화면에 페인팅하지 않습니다.

다음은 그리려는 간단한 원에 대한 창과 개체 클래스를 만듭니다.

public class Main { 

public static void main(String[] args) { 

    final int WIDTH = 700, HEIGHT = 900; 

    JFrame frame = new JFrame("Physics Demo"); 
    JPanel content = new JPanel(); 

    content.setLayout(new GridLayout(1, 0, 0, 0)); 

    Character ball = new Character(WIDTH, HEIGHT); 

    Timer changeFrame = new Timer (100, ball); 

    frameSetup(frame, content, WIDTH, HEIGHT, ball, changeFrame); 

} 

public static void frameSetup(JFrame frame, JPanel content, int WIDTH, int HEIGHT, Character ball, Timer changeFrame){ 

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    frame.setContentPane(content); 

    content.add(ball); 

    frame.addKeyListener(ball); 

    frame.setPreferredSize(new Dimension(WIDTH, HEIGHT)); 

    frame.setResizable(false); 
    frame.pack(); 
    frame.setLocationRelativeTo(null); 

    frame.setVisible(true); 
    changeFrame.start(); 

} 

}

아래의 클래스는 내가 프로그램을 실행할 때 콘솔에서 응답을, 객체 클래스입니다. 캐릭터는 한 번 (한 번씩) 트리거하고 actionPreformed 메소드는 타이머와 함께 루프에서 실행됩니다. 어떤 이유로 페인트 클래스를 실행하지 않습니다.

public class Character extends JPanel implements ActionListener, KeyListener{ 
/* Identify the Objects values and physics, 
* Characters weight, size and properties are below. 
* 
*/ 
private static final long serialVersionUID = 1L; 

final int characterRadius = 30; 

final double characterWeight = 0.5; 

int characterY, characterX; 

boolean bouncy; 

public Character(int WIDTH, int HEIGHT){ 

    System.out.println("Character called upon... " + WIDTH); 

} 

public void characterObject(Graphics g, int WIDTH, int HEIGHT){ 

    super.paint(g); 

    System.out.println("characterObject graphics called upon... " + WIDTH); 

    g.setColor(Color.BLUE); 
    g.fillOval(350, 450, characterRadius, characterRadius); 

} 

/* 
* Ball does not have any player interactions 
*/ 

@Override 
public void keyPressed(KeyEvent buttonPressed) { 


} 

@Override 
public void keyReleased(KeyEvent arg0) { 

} 

@Override 
public void keyTyped(KeyEvent arg0) { 


} 

//****************************************** 

@Override 
public void actionPerformed(ActionEvent arg0) { 

    System.out.println("actionPreformed called upon..."); 

    repaint(); 

} 

}

는 지금 잠시 동안 시행 착오를하고있다 그리고 나는 내가 최후의 수단으로이 사용하고 그것을 알아낼 수없는 것.

필요한 경우 더 많은 정보를 제공 할 수 있습니다.

+2

왜 'characterObject'에서'super.paint'를 호출하고 있습니까? 이것은 사용자 정의 그림이 작동하는 방식이 아닙니다. 페인팅 프로세스를 제어하지 않으면 API는 – MadProgrammer

답변

0

페인트를 직접 호출하면 안됩니다. 재 페인트가 필요할 때마다 프레임 워크에서 호출됩니다. 다시 그리기를 강요하려면 'repaint()'를 호출하십시오.

EventQueue.invokeLater(new Runnable() 
{ 
    @Override 
    public void run() 
    { 
    ball.repaint(); 
    } 
}); 

아, 그리고 당신이 정말로 paint 메소드 오버라이드 (override) :

@Override 
public void paint(Graphics g) 
{ 
    super.paint(g); 
    g.setColor(Color.BLUE); 
    g.fillOval(350, 450, characterRadius, characterRadius); 
} 
+3

이후 javax.swing.Timer'는 EDT에 등록 된 ActionListener를 호출하고 Ball 클래스는 ActionListener 인터페이스를 구현하고 그 안에서'repaint'를 호출합니다. RepaintManager가 작동하는 방식 때문에 토론 할 수도 있습니다.'repaint'는 일반적으로 쓰레드에 안전한 몇 가지 메소드 중 하나입니다 – MadProgrammer

3
을 경우

당신은 당신이 EventDispatchThread로를 의미 동부 서머 타임에 통화를 보류해야 할 수도 타이머에서 호출

super.paintcharacterObject으로 부르는 이유는 무엇입니까? 이것은 사용자 정의 그림이 작동하는 방식이 아닙니다. 페인팅 프로세스를 제어하지 않으면 API가 수행합니다.

API가 다시 그리려는 구성 요소를 원할 때 호출되는 메서드 중 하나를 재정의해야합니다. 일반적인 권장 사항으로, 이것은 paintComponent 방법,

public class Character extends JPanel implements ActionListener, KeyListener { 

    /* Identify the Objects values and physics, 
    * Characters weight, size and properties are below. 
    * 
    */ 
    private static final long serialVersionUID = 1L; 

    final int characterRadius = 30; 

    final double characterWeight = 0.5; 

    int characterY, characterX; 

    boolean bouncy; 

    public Character(int WIDTH, int HEIGHT) { 

     System.out.println("Character called upon... " + WIDTH); 

    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); //To change body of generated methods, choose Tools | Templates. 
     System.out.println("characterObject graphics called upon... " + WIDTH); 

     g.setColor(Color.BLUE); 
     g.fillOval(350, 450, characterRadius, characterRadius); 

    } 

    /* 
    * Ball does not have any player interactions 
    */ 
    @Override 
    public void keyPressed(KeyEvent buttonPressed) { 

    } 

    @Override 
    public void keyReleased(KeyEvent arg0) { 

    } 

    @Override 
    public void keyTyped(KeyEvent arg0) { 

    } 

    //****************************************** 
    @Override 
    public void actionPerformed(ActionEvent arg0) { 

     System.out.println("actionPreformed called upon..."); 

     repaint(); 

    } 
} 
예를

위해 나는 그림이 실제로 스윙에서 작동하는 방법에 대한 자세한 내용은 Performing Custom PaintingPainting in Swing의 읽기를 가지고 추천 할 것입니다 것입니다.

나는 또한 당신에게 다음 명백한 문제를 해결합니다 KeyListener를 대체, 같은 How to use Key Bindings 한 번 봐 가지고 권하고 싶습니다

는 또한 Java Coding Conventions의 읽기를 할 수 있습니다

, 다른 사람들을 위해 쉽게 만들 것입니다 코드를 읽고 다른 사람들을 더 쉽게 읽을 수 있습니다.

당신은 Character 생성자에 widthheight을 통과하고 있지만이를 무시하고있다, 나는 당신이 인스턴스 필드에 해당 값을 할당하고 paintComponent 방법에서 그들을 사용하는 필요 해요 좋을 것