2013-08-19 3 views
0

Я написал какое-то приложение и хотел добавить к нему несколько клавиатурных вводов. Мой основной класс расширяет JPanel, поэтому я могу добавить keyAdapter в конструктор. KeyAdapter - это новый класс, называемый «InputAdapter», расширяющий keyadapter с помощью метода keyPressed() и keyReleased(). нажмите или отпустите консоль, чтобы напечатать некоторую строку, например. здесь «Тест»Работа с клавиатурой не активна. Ключ-адаптер

Я не знаю, почему, но консоль не будет печатать какой-либо текст. Кроме того, когда я говорю, чтобы превратить видимость спрайтов в ложное, ничего не происходит.

Так что, я думаю, что 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 (Графика г) я предполагаю, не краска()

public void paintComponent(Graphics g){ 

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

Совет 2 - Использование addNotify() на вашем JPanel:

public void addNotify(){ 

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

Совета 3 - Запустить приложение таким образом, из EDT Thread (см What does SwingUtilities.invokeLater do?)

SwingUtilities.invokeLater(new Runnable() { 

    public void run(){ 

    //your code 

    } 
}); 

Надеются, что это помогает!

1

Существует много возможных причин, по которым это может не сработать. KeyListener очень суетливый. Для этого требуется, чтобы компонент, который был зарегистрирован, был не только фокусируемым, но и сосредоточенным.

Несмотря на то, что ваш компонент кажется обоим этим, если по какой-либо причине фокус захвачен другим компонентом, то KeyListener перестанет работать.

Вы должны использовать requestFocusInWindow и requestFocus ненадежна, но лучшим решением было бы использовать Key bindings, который имеет возможность более приходят все, что с фокусом беспорядка ...

Вы должны избегать перекрывая paint и использовать paintComponent вместо этого ознакомьтесь с Performing Custom Painting для более подробной информации.

Смешивание потоков с Swing сложно, вы также должны быть уверены, что не нарушаете правила нитей Swing при обновлении своего состояния. Выезд Concurrency in Swing для получения более подробной информации

+0

+1 для преобразования старого кода AWT в код Swing. – camickr

1

Ваша основная конструкция кода - старый код окраски AWT. Я повторяю все, о чем говорит MadProgrammer, для лучшего дизайна Swing.

В дополнение:

  1. нет необходимости в методе пустой инициализации().Избавьтесь от метода и вызова метода.
  2. такой же для метода update().

Большая проблема с размещенным кодом заключается в том, что вы добавляете панель в рамку ПОСЛЕ того, как рамка видна. Вы должны всегда добавлять компоненты к каркасу прежде, чем сделать кадр видимым:

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

Не берите легкий путь и просто сделать выше изменения. Напишите код для программы Swing, а не программу AWT.

+0

+1 для ловушки 'setVisible'! – MadProgrammer

Смежные вопросы