2011-11-28 3 views
1

SpacePotaters (JFrame의 하위 클래스)라는 최상위 GUI 클래스가 있고 contentLayout 레이아웃 관리자를 사용하는 panelViews라는 내용의 내용 패널에 JPanel을 추가합니다. 무엇보다도, 나는 mainMenu 객체 (JPanel의 서브 클래스)와 GameView 객체 (JPanel의 서브 클래스)를 카드로서 panelView에 추가한다.잘못된 JPanel이 CardLayout에 표시됩니다.

경우의 유용에
public SpacePotaters(){ 
    super("Space Potaters"); 
    Container content = getContentPane(); 

    // initialize components 
    gameView = new GameView(this); 
    mainMenu = new MainMenu(this); 
    leaderboard = new Leaderboard(this); 
    instructions = new JPanel(); // to do 
    cLayout = new CardLayout(); 

    // add "cards" to CardLayout manager 
    panelViews = new JPanel(cLayout); 
    panelViews.setPreferredSize(new Dimension(WINDOW_WIDTH, WINDOW_HEIGHT)); 
    panelViews.add("gameView", gameView); 
    panelViews.add("mainMenu", mainMenu); 
    panelViews.add("leaderboard", leaderboard); 
    panelViews.add("instructions", instructions); 

    // initially display menu menu 
    content.add(panelViews); 
    cLayout.show(panelViews,"mainMenu"); 

    addWindowListener(this); 
    pack(); 
    setResizable(false); 

    // relocate window to center of screen 
    setLocationRelativeTo(getRootPane()); 
} 

, 메인 메뉴 페인트 방법은 여기에 있습니다 :

@Override 
public void paintComponent(Graphics g){ 
    super.paintComponent(g); 
    g.drawImage(mainMenuBackground, 0, 0, spTop.getWindowWidth(), spTop.getWindowHeight(), null); 

} 

지금 난 그냥 배경 이미지를 페인트 - 나중에 내가 클릭하면 다른 카드로 전환됩니다 JButton의를 추가 할 것 .

기본 메뉴 카드로 시작하여 필요한 경우 다른 카드로 전환하는 것이 좋습니다. 프로그램을 실행하고 메인 메뉴 카드가 gameView 용으로 생성 된 이미지로 대체되기 전에 잠시 깜박임을 확인했습니다. 실제로 카드로 전환 할 때까지 gameView 그래픽을 렌더링해야하므로 게임이 너무 일찍 시작하지 않도록해야한다는 것을 알고 있습니다. 그것은 내가 혼란스럽지 않은 곳이 아닙니다. 기다리지 않아도 gameView를 보지 않아도 게임을 시작할 수 있습니까? 다시 말해, mainMenu가 gameView 내부에서 진행되는 상황과 상관없이 유일하게 보이는 카드로 남아 있지 않아야합니까?

나는 게임 뷰에서 액티브 렌더링과 더블 버퍼링을 사용하는 것이 문제라고 생각했습니다. - 만에는 mainMenu 도시

public void paintScreen(){ 
    // get fresh graphics context for GameView each time 
    Graphics context = getGraphics(); 
    if (context != null && dbImage != null){ 
     context.drawImage(dbImage, 0, 0, null); 
    } 
    context.dispose(); 
} 

이 메소드의 본문을 주석 원하는 결과이 생성 GameView 게임의 모든 루프가 한번 호출 방법이있다. 나는 이것이 왜 그런지 혼란 스럽다. 각 구성 요소 (JFrame, JPanel 등)에는 자체 그래픽 컨텍스트가 있다고 생각했습니다. 그래서 GameView 내부에서 getGraphics()를 호출하면 spTop 또는 panelViews의 그래픽 컨텍스트가 아닌 gameView 패널의 그래픽 컨텍스트를 반환하지 않아야합니까? 그리고 특정 그래픽 컨텍스트 만 변경하기 때문에, gameView 패널이 보이지 않으면 (mainMenu 객체에서 CardLayout의 show() 메서드를 사용하면 안됩니다), 그러면 주 메뉴의 내 뷰에 영향을 미치지 않습니다. . 어떤 아이디어?

참고 : gameView와 mainMenu를 모두 isVisible()로 테스트하면 gameView가 false를 반환하고 mainMenu가 true를 반환합니다. 또한 getMraphics()를 사용하여 mainMenu, spTop 및 gameView 그래픽 컨텍스트가 모두 다르게 테스트되었는지 테스트했습니다. 그래서 gameView는 자신의 그래픽 컨텍스트에서 이미지를 그리는 중이고 은 보이지 않지만 paintScreen() 내에서 drawImage()의 효과는 여전히입니다! 정말 혼란스러워.

+1

더 나은 도움을 받으려면 [SSCCE] (http://sscce.org/)를 게시하십시오. –

+0

gameView가 활성 카드가되기 전에 paintScreen()을 호출하는 코드가 있습니까? GameView가 표시되는 패널인지 여부에 관계없이 해당 메서드가 게임 스크린을 칠하는 것처럼 보입니다. –

+1

사용자 정의 페인팅을 위해 getGraphics()를 사용하지 마십시오. 그림은 일시적인 것입니다. JComponent 또는 JPanel의 paintComponent() 메소드를 오버라이드 (override)합니다. – camickr

답변

0

무슨 일이 일어나는지 알아 내려고 너무 많은 시간을 보냈다면 최소한 임베디드 그래픽 구성 요소 내에서 활성 렌더링은 적어도 해당 구성 요소의 가시성을 무시한다고 결론 지을 수 있습니다. 따라서 paintScreen() 내의 drawImage()는 호출 된 JPanel이 표시되는지 여부에 관계없이 항상 표시되는 결과를 표시합니다.

필자는 완전히 혼란 스럽지만,이 혼란은 능동 렌더링과 수동 렌더링을 혼합하려는 것과 관련이 있다고 생각합니다. mainMenu는 paintComponent()를 오버라이드하므로 수동 렌더링을 사용하여 페인트합니다. 내 gameView의 가시성을 false로 설정하면 최상위 JFrame이 단순히 gameView의 paintComponent()를 호출하지 않을 수도 있습니다. 그러나, gameView는 paintScreen()으로 그리기 때문에 가시성을 false로 설정해도 그 동작에는 영향을 미치지 않습니다. 이것에 대한 구체적인 정보를 찾을 수 없기 때문에 이것은 실험을 기반으로 한 모든 추측입니다.

또한 BufferStrategy를 사용하여 활성 렌더링을 수행하려고한다면 동일한 결과를 얻었을지 확실하지 않습니다.BufferStrategy의 show()가 관련 그래픽 구성 요소의 가시성을 무시하고 가시적 화면에도 그려지는 경우). 그것은 여전히 ​​조사되어야 할 것입니다.

필자는 현재의 프로그램과이 이해를 어떻게 조화시킬 것인가 - 모든 것을 다시 쓰고 싶지 않기 때문에 하이브리드 접근 방식을 사용하기로 결정했습니다. 필자는 CardLayout을 사용하여 내 panelViews/"cards"를 전환하기 위해 패시브 렌더링을 사용하려고합니다. gameView로 전환 할 때만 액티브 렌더링 동작을 켭니다. 나가서 다른 카드로 돌아 왔을 때, 나는 gameView의 액티브 렌더링을 되돌려 놓습니다. 수동 및 능동 렌더링을 혼합하는 것은 바람직하지 않지만 두 가지 전략을 동시에 사용하지 않으므로 아무런 문제가 발생하지 않기를 바랍니다. 이 접근법은 현재 mainMenu와 gameView 사이에서 전환하기 때문에 작동하므로 다른 수동적으로 렌더링 된 구성 요소를 추가 할 때 작동합니다.

관련 문제