Прямо сейчас у меня есть класс, расширяющий JPanel и реализующий KeyListener. Я создал экземпляр этого класса для другого класса, который запускает его в моем цикле. Класс KeyListener выглядит как
public class Keyboard extends JPanel implements KeyListener{
public Keyboard()
{
this.addKeyListener(this);
}
public void update()
{
}
@Override
public void keyPressed(KeyEvent e)
{
if (keyCode == KeyEvent.VK_S){
System.out.println("Made it");
}
}
@Override
public void keyReleased(KeyEvent e)
{
}
@Override
public void keyTyped(KeyEvent e)
{
}
}
Я реализовал это в другом классе, который отлично использует MouseListener в классе Game. Но почему-то не слушает клавиатуру.
public class Main
{
public static final int WIDTH = 640;
public static final int HEIGHT = 640;
public static final String NAME = "Game";
private static BufferedImage image;
private static Graphics2D g;
private static boolean forceQuit;
private static Game game;
private static Keyboard keyboard;
public Main(){
}
private static void init()
{
image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
g = (Graphics2D) image.getGraphics();
g.setBackground(Color.BLACK);
game = new Game();
keyboard = new Keyboard();
}
private static void start()
{
run();
}
public static void stop()
{
forceQuit = true;
}
public static void run()
{
@SuppressWarnings("unused")
int frames = 0;
double unprocessedSeconds = 0;
long lastTime = System.nanoTime();
double secondsPerTick = 1.0 / 60.0;
int tickCount = 0;
while (!forceQuit)
{
if (keyboard.isSwampland()){
game.setSwampland(true);
}
long now = System.nanoTime();
long passedTime = now - lastTime;
lastTime = now;
if (passedTime < 0)
passedTime = 0;
if (passedTime > 100000000)
passedTime = 100000000;
unprocessedSeconds += passedTime / 1000000000.0;
boolean ticked = false;
while (unprocessedSeconds > secondsPerTick)
{
game.update();
keyboard.update();
unprocessedSeconds -= secondsPerTick;
ticked = true;
tickCount++;
if (tickCount % 60 == 0)
{
// System.out.println("FPS:" + frames);
lastTime += 1000;
frames = 0;
}
}
if (ticked)
{
game.render(g);
Graphics gg = game.getGraphics();
gg.drawImage(image, 0, 0, null);
gg.dispose();
frames++;
}
else
{
try
{
Thread.sleep(1);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
public static void main(String[] args)
{
Main.init();
JFrame frame = new JFrame(NAME);
frame.setDefaultCloseOperation(3);
frame.setContentPane(game);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
Main.start();
}
}




Итак, ряд вопросов ...
Используйте Key Bindings API, он преодолевает недостатки API KeyListener
KeyListener будет генерировать KeyEvent только в том случае, если компонент, для которого он зарегистрирован, является фокусируемым И имеет фокус клавиатуры.
Я вижу проблемы с вашим кодом ...
Keyboard на самом деле ни к чему не добавляется, поэтому он не отображается на экране, поэтому он никогда не сможет получить фокус.KeyListener действительно должен быть зарегистрирован на Game напрямую, это просто меньше компонентов, которыми нужно управлять.getGraphics из Component не рекомендуется, рисование должно выполняться не так. Компоненты Swing по умолчанию имеют двойную буферизацию, поэтому, как правило, было бы лучше использовать его встроенный процесс рисования, и если вы ДЕЙСТВИТЕЛЬНО хотите контролировать процесс рисования, вы должны использовать Canvas и BufferStrategy, иначе рискуете сгенерировать состояние гонки между вашим кодом рисования и существующим процессом рисования APIя делаю это
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class DrawPoints
{
Frame f;
KeyBoard key;
Mouse mouse;
Paint c;
public void GUI()
{
f = new Frame("DrawPoints");
f.setSize(300, 300);
mouse = new Mouse();
c = new Paint(mouse);
c.setSize(300, 300);
c.setBackground(Color.WHITE);
c.addMouseListener(mouse);
c.addMouseMotionListener(mouse);
key = new KeyBoard();
c.addKeyListener(key);
f.add(c);
f.pack();
f.setVisible(true);
f.addWindowListener(new WindowAdapter()
{
@Override
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
}
}
class KeyBoard implements KeyListener
{
@Override
public void keyPressed(KeyEvent e)
{
int key = e.getKeyCode();
if (key == KeyEvent.VK_SPACE)
{
System.out.println("SPACE");
}
}
@Override
public void keyTyped(KeyEvent e)
{
System.out.println("Typed");
}
@Override
public void keyReleased(KeyEvent e)
{
System.out.println("Released");
}
}
class Main
{
public static void main(String[] args)
{
DrawPoints app = new DrawPoints();
app.GUI();
}
}
class Paint extends Canvas
{
Mouse mouse;
public Paint(Mouse mouse)
{
this.mouse = mouse;
}
@Override
public void paint(Graphics g)
{
g.drawRect(mouse.getX(), mouse.getY(), 30, 30);
repaint();
}
}
class Mouse implements MouseListener, MouseMotionListener
{
private int x;
private int y;
public int getX()
{
return this.x;
}
public int getY()
{
return this.y;
}
// MouseMotionListener
@Override
public void mouseMoved(MouseEvent e)
{
x = e.getX();
y = e.getY();
//System.out.println(e.getX() + " " + e.getY());
}
@Override
public void mouseDragged(MouseEvent e)
{
System.out.println("mouseDragged");
}
// MouseListener
@Override
public void mouseEntered(MouseEvent e)
{
System.out.println("MOUSE Entered");
}
@Override
public void mousePressed(MouseEvent e)
{
System.out.println("MOUSE Pressed");
}
@Override
public void mouseReleased(MouseEvent e)
{
System.out.println("MOUSE Released");
}
@Override
public void mouseClicked(MouseEvent e)
{
System.out.println("MOUSE Clicked");
}
@Override
public void mouseExited(MouseEvent e)
{
System.out.println("MOUSE Exited");
}
}