2013-08-19 77 views
0

我寫了一些應用程序,並希望添加一些鍵盤輸入。 我的主類擴展了一個JPanel,所以我可以將keyAdapter添加到構造函數中。 keyAdapter是一個名爲「InputAdapter」的新類,通過它的keyPressed()和keyReleased()方法擴展了keyadapter。點擊或釋放控制檯應打印一些字符串,例如這裏「測試」沒有鍵盤輸入工作KeyAdapter

我不知道爲什麼,但控制檯不會打印任何文字。另外,當我告訴它將精靈的可見性變爲虛假時,也不會發生任何事情。

所以我想KeyAdapter工作不正常,所以有人可以仔細看看我的代碼行嗎?

我想這個問題與我寫的其他實現類無關,因爲當刪除它們時,非工作鍵盤輸入的問題仍然存在。

package com.ochs.game;

public class Game extends JPanel implements Runnable{ 
private static final long serialVersionUID = 1L; 

public static final int WIDTH = 320; 
public static final int HEIGHT = 240; 
public static final int SCALE = 3; 

public boolean isRunning; 

public Game() { 
    addKeyListener(new InputAdapter()); 
    setFocusable(true); 
    requestFocus(); 
    start(); 
} 

public void start() { 
    isRunning = true; 
    new Thread(this).start(); 
} 

public void stop() { 
    isRunning = false; 
} 

public void run() { 
    init(); 
    while(isRunning) { 

     update(); 
     repaint(); 

     try { 
      Thread.sleep(5); 
     } catch (InterruptedException e) { 
      System.out.println("Thread sleep failed."); 
     } 
    } 
} 

public void init() { 

} 

public void update() { 

} 

public void paint(Graphics g) { 
    super.paint(g); 
    Graphics2D g2d = (Graphics2D)g; 

} 

public static void main(String[] args) { 
    Game gameComponent = new Game(); 
    Dimension size = new Dimension(WIDTH*SCALE, HEIGHT*SCALE); 

    JFrame frame = new JFrame("Invaders"); 
    frame.setVisible(true); 
    frame.setSize(size); 
    frame.setLocationRelativeTo(null); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setResizable(false); 
    frame.add(gameComponent); 
} 
public class InputAdapter extends KeyAdapter { 

    @Override 
    public void keyPressed(KeyEvent arg0) { 
     System.out.println("Test"); 
    } 

    @Override 
    public void keyReleased(KeyEvent arg0) { 
     System.out.println("Test"); 
    } 


} 
} 

回答

1

你的代碼工作對我來說:

java version "1.6.0_27" 
OpenJDK Runtime Environment (IcedTea6 1.12.6) (6b27-1.12.6-1ubuntu0.12.04.2) 
OpenJDK Client VM (build 20.0-b12, mixed mode, sharing) 

提示1 - 您應該重寫paintComponent(圖形G)我想,不是paint()方法

public void paintComponent(Graphics g){ 

    super.paintComponent(g); 
    //... 
} 

提示2 - 使用您的JPanel上的addNotify()

public void addNotify(){ 

    super.addNotify(); 
    //start from here 
    new Thread(this).start(); 
} 

提示3 - 啓動您的應用程序這種方式,從美國東部時間線(見What does SwingUtilities.invokeLater do?

SwingUtilities.invokeLater(new Runnable() { 

    public void run(){ 

    //your code 

    } 
}); 

希望它能幫助!

1

有很多可能的原因,這可能無法正常工作。 KeyListener非常挑剔。它要求註冊的組件不僅是可以調焦的,而且還有焦點。

即使您的組件看起來都是這些東西,但如果出於某種原因焦點被另一個組件佔用,KeyListener將停止工作。

您應該使用requestFocusInWindowrequestFocus是不可靠的,但一個更好的解決辦法是使用Key bindings,其中有過度附帶重點所有雜亂的能力...

你應該避免覆蓋paint和使用paintComponent相反,請查看Performing Custom Painting瞭解更多詳情。

使用Swing混合線程很棘手,您還需要確保在更新狀態時不違反Swing的單線程規則。查看Concurrency in Swing瞭解更多詳情

+0

+1將舊的AWT設計的代碼轉換爲Swing代碼。 – camickr

1

您的基本代碼設計是舊的AWT繪畫代碼。我回應MadProgrammer所說的更好的Swing設計。

此外:

  1. 沒有必要爲一個空init()方法。擺脫方法和調用方法。
  2. 與update()方法相同。

發佈的代碼的一個大問題是,在框架可見後,將面板添加到框架。你應該總是使框架可見之前將組件添加到幀:

JFrame frame = new JFrame("Invaders"); 
frame.add(gameComponent); 
... 
frame.setVisible(true); 

不要採取簡單的出路,只是作出上述變化。爲Swing程序編寫代碼,而不是AWT程序。

+0

+1 setVisible'陷阱! – MadProgrammer