Java切换jpanels和新面板没有响应

时间:2014-05-28 03:40:47

标签: java swing jframe jpanel keyevent

我使用启动JPanel的JFrame开始我的游戏。然后,当JPanel准备就绪时,JPanel会转到下一个。我可以切换到新的JPanel,但它不响应我的按键。第二个JPanel以前工作正常,所以我认为问题是它们之间的转换。 (我删除了一些不相关的方法)

public class GameRunner extends JFrame
{       
public GameRunner()
{
    super("Scrolling Shooter");

    Toolkit tk = Toolkit.getDefaultToolkit();  
    int width = ((int) tk.getScreenSize().getWidth());  
    int height = ((int) tk.getScreenSize().getHeight());  
    setSize(width, height);

    TitleScreen title = new TitleScreen(this);

    ((Component)title).setFocusable(true);
    getContentPane().add(title);

    setVisible(true);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

public static void main(String args[])
    {new GameRunner();}
}

public class TitleScreen extends JPanel implements KeyListener, Runnable
{
private JFrame frame;           //the JFrame
private ImageItem background;   //the background
private String name = "";       //the player's name

/**
 * Constructs a title screen
 * @param f the JFrame
 */
public TitleScreen (JFrame f)
{
    frame = f;

    ImageItem fix = new ImageItem();
    fix.fixMainPath();              //fixes the main path for all the ImageItems
    background = new ImageItem(0, 0, frame.getWidth(), frame.getHeight(), "splashscreen.png");  //makes background stretch between the top and bottom walls

    setVisible(true);
    addKeyListener(this);   
    new Thread(this).start();
}

/**
  * Draws the stuff on the screen
  * @param g some Graphics object
  */
protected void paintComponent(Graphics g)
{
    background.draw(g);
    if (!(name.equals("")))
    {
        g.setFont(g.getFont().deriveFont(80f));
        g.drawString(name, frame.getWidth() / 3, frame.getHeight() - 60);
    }
}

/**
 * When a key is typed it is added to the name
 * @param key the key typed
 */
public void keyTyped(KeyEvent key) 
{
    if (!(key.getKeyCode() == KeyEvent.VK_ENTER))
        name += key.getKeyChar();
}   

/**
 * Enter makes moves to the game if the name is ok
 * @param key the key pressed
 */
public void keyPressed(KeyEvent key)
{
    if (key.getKeyCode() == KeyEvent.VK_ENTER)
    {
        boolean isValid = false;

        if (name.length() > 20)
            JOptionPane.showMessageDialog(frame, "That name is too long. Try again.");

        if (!name.equals(""))
        {
            try {if (!hasBannedWord(name)) isValid = true;}         //breaks the loop if there are no banned words in the name
            catch (FileNotFoundException e) {e.printStackTrace();}
        }

        if (!isValid)
        {
            JOptionPane.showMessageDialog(frame, "Bad name. Try again.");
            name = "";
        }

        if (isValid)
        {
            ScrollingShooter game = new ScrollingShooter(frame, name);
            ((Component)game).setFocusable(true);
            frame.getContentPane().removeAll();
            frame.getContentPane().add(game);
            frame.setVisible(true);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
    }   
}

public void run()
{
  try
  {
    while(true)
    {
       Thread.currentThread().sleep(0);
       repaint();
    }
  }     
  catch(Exception e){e.printStackTrace();}
}

2 个答案:

答案 0 :(得分:1)

使用the key bindings API代替KeyListener,可以更好地控制生成关键事件所需的焦点水平

为了使KeyListener生成KeyEvent,其注册的组件必须是可聚焦的并且具有焦点。没有" easy"保证组件可以获得/抓住焦点的方法。

你还应该考虑使用CardLayout在你的屏幕之间移动,它是为它设计的,并且会让生活变得更轻松

您还应该调用super.paintComponent以确保组件/ Graphics上下文已准备好进行绘制

答案 1 :(得分:1)

您正在使用KeyListener和KeyListener经常会遇到焦点问题,如果您尝试交换这些焦点问题。

我建议您使用Key Bindings来帮助您解决焦点问题,并将JPanels与CardLayout交换。