2013-10-20 3 views
0

문제점 : Main.repaint()가 작동하지 않습니다. repaint()는 Main에서 내 페인트 메소드를 호출하지 않습니다. 필자는 다시 칠하기 전에 validate를 호출 해 보았지만 성공하지는 못했습니다. 주 그림은 처음부터 완벽하게 크기가 조정되었지만 코드에서 repaint()을 호출하면 아무 것도 일어나지 않습니다. 여기JApplet repaint()가 작동하지 않습니다.

프로그램이 지금까지 link

그래서 자바 게임을 레벨 선택 화면을 만들려고 메신저 모습입니다. 내 게임은 JApplet입니다. 나는 다음과 같은 구조를 가지고 : JApplet에를 확장하고

LevelScreen 홈페이지가 호출하는 페인트 방법이있다 LevelScreen 클래스의 객체를 포함

  1. 내 주요 클래스입니다.

레이아웃 관리자가 디자인에 문제가있어서 스윙을 사용하지 않으려 고했습니다. 그래서 나는 더 간단하고 내 필요에 더 적합한 구조를 만들려고 노력했습니다.

페인트() 내 버튼의 코드에서

public class Main extends JApplet { 

    public static final int WIDTH = 700, HEIGHT = 500; 
    private static Main instance; 

    private LevelScreen levelScreen = new LevelScreen(); 
    private View view = View.LEVELSCREEN; 

    public static Main getInstance() { 
     if (instance == null) 
      instance = new Main(); 
     return instance; 
    } 

    @Override 
    public void init() { 
     setSize(WIDTH, HEIGHT); 
     addMouseMotionListener(new MouseAdapter() { 
      @Override 
      public void mouseMoved(MouseEvent e) { 
       Point p = e.getPoint(); 
       if (view == View.LEVELSCREEN) { 
        levelScreen.mouseMoved(p); 
       } 
      } 
     }); 
    } 

    @Override 
    public void paint(Graphics g) { 
     Graphics2D g2 = (Graphics2D) g; 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
       RenderingHints.VALUE_ANTIALIAS_ON); 

     if (view == View.LEVELSCREEN) 
      levelScreen.paint(g2); 
    } 

    public enum View { 
     GAME, LEVELSCREEN; 
    } 
} 

Main.java

에서 나는 마우스 버튼을 떠날 때 애니메이션 페이드를 만들고 싶어하기 때문에 홈페이지 칠하려고합니다. 이것은 당신이 싱글 디자인을 구현하는 방식에 문제가

public void mouseExited() { 
     //start new thread to make fade out animation when mouse leave 
     mouseOver = false; 
     TimerTask task = new TimerTask() { 

      @Override 
      public void run() { 
       while (!mouseOver && opacity > 0.6) { 
        opacity -= 0.02; 
        //set level to 999 so i can see if the game repaints() 
        level = 999; 
        Main.getInstance().repaint(); //this doesnt work!! 
        try { 
         Thread.sleep(20); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
       } 
      } 
     }; 
     new Thread(task).start(); 
} 

답변

1

: 내 문제는 내가 칠하고() 여기

내가 (다시 칠 전화)와 메인에 페인트 (그래픽 g)를 호출하지 못할 것입니다 무늬. 애플릿 컨테이너로 인스턴스가 생성되는 애플릿에서는 작동하지 않습니다. 당신이 스윙 구성 요소에서 paint을 무시해서는 안

instance = this; 

을 그건 그렇고 : 당신은 다음과 같이 getInstance을 변경하여 문제를 해결할 수 있습니다

public Main getInstance() { 
    return instance; 
} 

을 그리고 init 방법이 줄을 추가 JApplet입니다. 대신 paintComponent을 무시하고 super.paintComponent(g)을 첫 번째 행으로 호출해야합니다. 이렇게하면 문제가 해결됩니다.

+0

완벽하게 작동했습니다! JApplet이 브라우저가 아닌 프로그램에서 어떻게 생성되었는지 오해했습니다. – Bjorn

1
Main.getInstance().repaint(); //this doesnt work!! 

나는 놀랍지 않습니다. 브라우저가 JApplet의 인스턴스를 만드는 사람이 아닙니다.

이 전화

... 당신은 실제로 화면에있는 일이 아니다, 그래서 당신은 repaint를 호출 할 때, 스윙 간다 애플릿의 두 번째 인스턴스를 생성하는

public static Main getInstance() { 
    if (instance == null) 
     instance = new Main(); 
    return instance; 
} 

" 어떤 점도, 당신은 심지어 표시 할 수 없다 "고 아무것도하지 않는다.

더 이상 코드가 없으면 getInstance이 필요하지 않고 대신 Main.this을 사용하여 현재 인스턴스를 참조하십시오.

Performing Custom Painting도 고려해야합니다.

JAppelt과 같은 최상위 컨테이너는 이중 버퍼링되지 않으므로 더 많은 작업이 직접 수행됩니다. 대신 응용 프로그램을 JPanel 같은 것을 기반으로 이동하고 대신 paintComponent 메서드를 재정의하십시오.

도장은 복잡한 다중 레이어 방식입니다. 페인트 체인을 보존하고 가능한 모든 문제를 방지하려면 super.paintXxx으로 전화해야합니다.

+0

JFrame 대신 JApplet을 사용하는 이유는 내 게임이 어느 시점에서 브라우저에서 실행되기를 원했기 때문입니다. 컴파일러는 Main.this에 접근 할 수 없다고 말합니다. 나는 템포가 더러운 해결책을 발견했다.이 해결책은 특정 시간 간격으로 Main repaint()를 사용하는 것이다. – Bjorn