2012-06-25 2 views
2

체스 게임을 사용하려고합니다. 게임 루프에서 내 JFrame 중 하나에서 repaint() 메서드를 호출하려고합니다. 이 특정 JFrame은 각 플레이어의 총 킬수를 보여줍니다. 나는 실제로 repaint()이 실제로 호출되고 있음을 확신하지만 어떤 이유로 각 플레이어에 대해 킬 (Kill) 값의 수를 유지하기로되어있는 JLabels를 올바르게 업데이트하지 않는 것 같습니다.repaint()를 호출 할 때 JFrame이 업데이트되지 않습니다.

여기는 살인을 나타내는 JLabels가있는 사용자 정의 JFrame 확장 클래스의 코드입니다.

public static void main(String[] args) throws InterruptedException { 

    JFrame gameFrame = new ChessMain(); 
    gameFrame.setDefaultCloseOperation(DISPOSE_ON_CLOSE); 
    gameFrame.pack(); 
    gameFrame.setResizable(true); 
    gameFrame.setLocationRelativeTo(null); 
    gameFrame.setVisible(true); 
    gameFrame.setTitle("Chess X"); 

    LoginFrame loginFrame = new LoginFrame(((ChessMain) gameFrame).getGame()); 

    System.out.println(((ChessMain) gameFrame).getGame().toString()); 
    System.out.println(((ChessMain) gameFrame).getGame().currentPlayer.getName()+ ", it's your turn."); 

    //this is what creates the kills frame. 
    KillsFrame kf = new KillsFrame(((ChessMain) gameFrame).getGame()); 

    while(true){ 

     ((ChessMain) gameFrame).getGame().run(); 
     kf.repaint();//************************************* 
     Thread.sleep(1); 

    } 

} 

하나를 모든 도움을 크게 감사합니다 :

private ChessGame game; 
private JPanel killsPanel; 
private String p1kills; 
private String p2kills; 
private JLabel kills; 
private JLabel p1, p2; 
private JLabel p1NumKills = new JLabel(); 
private JLabel p2NumKills = new JLabel(); 


//the player's kill values are increasing and registering, just not within the jlabels representing them 
public KillsFrame(ChessGame game){ 
    this.game = game; 
    killsPanel = new JPanel(new MigLayout("", "[center][right][left][c]", "[top][center][b]")); 
    kills = new JLabel("KILLS"); 
    p1 = new JLabel(game.getCurrentPlayer().getName() + " - "); 
    p2 = new JLabel(game.getOtherPlayer().getName() + " - "); 

    //this is the part that should be working but isn't. 
    //p1kills and p2kills aren't being updated or something. 
    p1kills = "" + game.getCurrentPlayer().getKills(); 
    p2kills = "" + game.getOtherPlayer().getKills(); 
    p1NumKills.setText(p1kills); 
    p1NumKills.setText(p2kills); 

    killsPanel.add(kills, "span"); 
    killsPanel.add(p1); 
    killsPanel.add(p1NumKills, "wrap"); 
    killsPanel.add(p2); 
    killsPanel.add(p2NumKills, "wrap"); 

    killsPanel.setBackground(Color.lightGray); 
    add(killsPanel); 
    pack(); 
    setTitle("Scoreboard"); 
    setDefaultCloseOperation(DISPOSE_ON_CLOSE); 
    setResizable(true); 
    setVisible(true); 
    setLocationRelativeTo(null); 
} 

그럼 난 그냥 다른 클래스의 주요 방법이 프레임의 재 페인트()를 호출합니다.

+2

이 [예제] (http://stackoverflow.com/a/2562685/230513) 및 [유사] (http://stackoverflow.com/a/2563350/230513)도 참조하십시오. – trashgod

+2

'setText (...)'가 호출 될 때 라벨이 이것을 수행하기 때문에 JLabel에서 텍스트 변경을 표시하기 위해'repaint()'를 호출 할 필요가 없습니다. –

+2

더 중요한 것은 : 게임 루프, 'while (true) {...}'비트의 코드가 필요없고 실제로 생산성이 떨어지는 것입니다. 이 코드를 없애고 Swing의 이벤트 중심 아키텍처를 대신 사용하십시오. –

답변

1

오류는 주 스레드를 "잠자기"하려고 할 때 발생합니다. GUI를 응답하지 않는 경우 오류가 발생할 수 있습니다. 가장 좋은 방법은 swing.Timer 클래스 (자습서 http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html)를 사용하는 것입니다. 다시 칠하기 위해 규칙적인 간격으로 사격을하십시오(). 이렇게하면 부드러운 애니메이션이됩니다.

어떤 이유로 수면 스윙 프로그램 스레드해야 경우 SwingWorker의 클래스 (그리고하지, 그렇지 않으면)를 사용하여 새 스레드를 만들 수 있습니다. http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html#process(java.util.List 참조)

관련 문제