2014-01-28 1 views
3

저는 여러 개의 패널을 가진 JFrame 클래스를 가지고 있으며, paintComponent (Graphics g) 메서드를 사용하여 드로잉하여 모든 그래픽을 처리하므로 CardLayout을 사용하지 않아도됩니다. 프레임을 전환하려면 입력과 같은 버튼을 누르기 만하면되지만 패널을 전환하면 paintCompenent의 왼쪽 위에있는 그래픽이 그대로 남아 있습니다. 나는 또한 panel.setVisible (false)를 사용하여 패널을 볼 수있게 만들려고 노력했다. 그리고 그 패널을 내가 바뀌는 패널이 true로 설정 한 후에도 보이지 않는 것을 제외하고는 다소 도움이되었다. 새 패널에 대한 버튼과 명령이 작동하고 첫 번째 패널로 다시 전환되므로 전환이 제대로 작동하는지 알 수 있으므로, 원하는대로 표시하지 않습니다.키보드로 JPanels 바꾸기

//JFRAME CLASS 
package main; 

import gameStates.Instruction; 
import gameStates.Menu; 
import gameStates.State; 

import java.awt.Dimension; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import java.util.ArrayList; 

import javax.swing.JFrame; 

@SuppressWarnings("serial") 
public class GameFrame extends JFrame implements KeyListener{ 

    //panels for Game States in order: 
    static ArrayList<State> panels = new ArrayList<State>();//holds all of the game states that the game will eventually reach 

    private static int currentState=0;//STATES: 0 - Menu 
           //1 - Instruction 
           //2 - Level 1 and States 3 through 7 are the levels up one respectively up to level 6 

    public GameFrame() { 
     panels.add(new Menu(this)); 
     panels.add(new Instruction(this)); 

     addKeyListener(this); 
     setSize(640,480); 
     setPreferredSize(new Dimension(640,480)); 
     setResizable(false); 
     setLocation(20,50); 
     setName("FBLA: A Success Story"); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 

     add(panels.get(1)); 
     add(panels.get(0)); 
     panels.get(1).setVisible(false); 
     panels.get(0).setVisible(true); 

     pack(); 
     setVisible(true); 


    } 

    @SuppressWarnings("unused") 
    public static void main(String[] args) { 
     GameFrame g = new GameFrame(); 
    } 


    public void keyTyped(KeyEvent e) { 
    } 
    public void keyPressed(KeyEvent e) { 
     if(e.getKeyCode() == KeyEvent.VK_ESCAPE) 
      System.exit(0); 
     else { 
      panels.get(currentState).buttons(e); 
     } 
    } 
    public void keyReleased(KeyEvent e) { 
    } 

    public void nextState(int state) { 
     panels.get(currentState).setVisible(false); 
     panels.get(state).setVisible(true); 
     currentState = state; 
    } 

} 
//////////////////////INITIAL PANEL////////////////////////// 
package gameStates; 

import java.awt.Color; 
import java.awt.Font; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.ActionEvent; 
import java.awt.event.KeyEvent; 
import java.awt.image.BufferedImage; 

import javax.imageio.ImageIO; 
import javax.swing.Timer; 

import main.GameFrame; 

@SuppressWarnings("serial") 
public class Menu extends State { 

    //general items 
    public BufferedImage bg; 
    public String[] options = new String[3]; 
    public double x, y, velX, velY; 
    public int selected; 
    public Graphics2D g2; 

    //time stuff 
    Timer t = new Timer(5,this); 

    public Menu(GameFrame g) { 
     super(g); 
     setup(); 
    } 
    public void setup() { 
     try { 
      bg = ImageIO.read(Menu.class.getResourceAsStream("/backgrounds/FBLAmenubg.gif")); 
     } 
     catch (Exception e) { 
      e.printStackTrace(); 
     } 

     options[0] = "PLAY"; 
     options[1] = "INSTRUCTIONS"; 
     options[2] = "QUIT"; 
     selected = 0; 

     x=y=velY=0; 
     velX=-.1; 

     t.start(); 
    } 

    public void paintComponent(Graphics g) { 
     g2 = (Graphics2D)g; 
     g2.drawImage(bg, (int)x, (int)y, null); 
     g2.drawImage(bg, (int)x + 640, (int)y, null); 
     Font f = new Font("FreeSerif", Font.ROMAN_BASELINE, 48); 
     g2.setFont(f); 
     g2.setColor(Color.WHITE); 
     for(int j=0;j<3;j++){ 
      if(selected == j) 
       g2.setColor(Color.RED); 
      g2.drawString(options[j], 120, 80 + j*48); 
      g2.setColor(Color.WHITE); 
     } 

    } 

    private void processSelection() { 

     if(selected == 2) 
      System.exit(0); 
     else if (selected == 1) { 
      parent.nextState(1); 
     } 
     else { 

     } 
    } 

    public void buttons(KeyEvent e) { 
     if(e.getKeyCode() == KeyEvent.VK_DOWN) { 
      selected++; 
      if(selected == 3) 
       selected=0; 
     } 
     if(e.getKeyCode() == KeyEvent.VK_UP) { 
      selected--; 
      if(selected == -1) 
       selected=2; 
     } 
     if(e.getKeyCode() == KeyEvent.VK_ENTER) { 
      processSelection(); 
     } 
    } 

    public void actionPerformed(ActionEvent e) { 
     x += velX; 
     if(x<=-640) 
      x=0;; 
     repaint(); 
    } 

} 

/////////////////////TRANSITION TO THIS PANEL//////////////////////////// 
package gameStates; 

import java.awt.Color; 
import java.awt.Font; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.ActionEvent; 
import java.awt.event.KeyEvent; 
import java.awt.image.BufferedImage; 

import javax.imageio.ImageIO; 
import javax.swing.Timer; 

import main.GameFrame; 

@SuppressWarnings("serial") 
public class Instruction extends State{ 

    public BufferedImage bg; 
    public Graphics2D g2; 
    public Timer t; 

    public Instruction(GameFrame g) { 
     super(g); 
     setup(); 
    } 


    public void buttons(KeyEvent e) { 
     if(e.getKeyCode() == KeyEvent.VK_SPACE) 
      parent.nextState(0); 
    } 

    public void setup() { 

     try { 
      bg = ImageIO.read(Menu.class.getResourceAsStream("/backgrounds/Instructionsbg.gif")); 
     } 
     catch (Exception e) { 
      e.printStackTrace(); 
     } 

     t = new Timer(5,this); 
     t.start(); 

    } 

    public void actionPerformed(ActionEvent e) { 
     repaint(); 
    } 

    public void paintComponent(Graphics g) { 

     g2 = (Graphics2D) g; 
     g2.setColor(Color.WHITE); 
     g2.fillRect(0,0,640,480); 
     g2.drawImage(bg,0,0,null); 
     Font f = new Font("FreeSerif", Font.ROMAN_BASELINE, 20); 
     g2.setFont(f); 
     g2.setColor(Color.RED); 
     g2.drawString("SPACE BAR to go back to menu.", 600, 400); 

    } 

} 

답변

2

이 때문에 CardLayout 사용에 아무 소용이 없다 : 여기 상호 작용이 개 패널을 처리하는 JFrame의 클래스에 코드입니다.

이것은 사용자 정의 페인팅과 관련이 없습니다. CardLayout을 사용할 수 있어야합니다 (또는 실제로 원하는 레이아웃 관리자가 무엇인지).

당신은 결코 그림에 대한 Graphics 컨텍스트를 준비 할 책임이 super.paintComponent를 호출하지 ....

// Should be protected... 
// Should have @Override annotation 
public void paintComponent(Graphics g) { 
    // super.paintComponent(g) goes here... 
    //... 
} 

public Graphics2D g2;도 나를 무서워, 당신은 명시 적으로하지 않았다 어떤 Graphics 컨텍스트에 대한 참조를 유지해서는 안 g.create은 포함되지 않습니다.

Swing의 Graphics 컨텍스트는 일반적으로 동일한 기본 피어 (또는 대부분의 경우 창)에 연결된 모든 구성 요소에 대해 공유됩니다. 이것은 당신이 그것을 청소하지 않는 한, 마지막으로 그렸던 것이 아직도 거기에 남아있을 것임을 의미합니다.

이것은 이전에 Graphics 컨텍스트에 그렸던 내용이 깨끗하게 지워지므로, 일반적으로 유지 관리 참조 번호가 Graphics이거나 일반적인 페인트 사이클 바깥에 페인팅되지 않도록하는 이유를 의미합니다.

도 무작위로 응답하지 KeyListener, 초과 근무, 당신은 또한을 찾을 수 있습니다 자세한 내용

당신을 Painting in AWT and Swing를 살펴 보자. KeyListener에는 여러 구성 요소를 관리하는 데 적합하게 초점을 맞춘 내용이 있습니다.

+0

super.paintComponent는 실제로는 아무 것도하지 않지만 CardLayout을 완전히 이해하지 못하여 어떻게해야하는지 이해할 수 없습니다. 그래서 제안에 감사드립니다! 다시 연구 한 후에 작동했습니다! – Silimerse