我使用启动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();}
}
答案 0 :(得分:1)
使用the key bindings API代替KeyListener
,可以更好地控制生成关键事件所需的焦点水平
为了使KeyListener
生成KeyEvent
,其注册的组件必须是可聚焦的并且具有焦点。没有" easy"保证组件可以获得/抓住焦点的方法。
你还应该考虑使用CardLayout
在你的屏幕之间移动,它是为它设计的,并且会让生活变得更轻松
您还应该调用super.paintComponent
以确保组件/ Graphics
上下文已准备好进行绘制
答案 1 :(得分:1)
您正在使用KeyListener和KeyListener经常会遇到焦点问题,如果您尝试交换这些焦点问题。
我建议您使用Key Bindings来帮助您解决焦点问题,并将JPanels与CardLayout交换。