Um programa simples com o KeyAdapter não pode registrar teclas únicas depois de pressionar várias. Solução de código?

Eu só estou tentando entender o básico quando se trata de programas simples de desenho. Eu tenho um programa que desenha um retângulo e depois me permite movê-lo em qualquer direção. Eu uso um thread para ações suaves. No entanto, o que me incomoda é que, se eu pressionar três teclas e soltar duas delas, o programa não detectará a terceira, deixando o retângulo parado.

Estou pedindo muito aqui ou pode estar relacionado a hardware? Eu tenho um teclado bem barato.

Aqui está o programa completo, se você quiser dar um passeio.

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Boxxy extends JFrame implements Runnable{

    int xPos, yPos, xDir, yDir;
    MyPanel panel;
    ImageIcon ii;
    Image i;


    public Boxxy() {
        setSize(400,400);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        panel = new MyPanel();
        add(panel);

        setVisible(true);
    }

    class MyPanel extends JPanel {
        private static final long serialVersionUID = 1L;

        private int squareX = 0;
        private int squareY = 0;
        private int squareW = 20;
        private int squareH = 20;

        private MyPanel() {
            setFocusable(true);
            addKeyListener(new KeyAdapter() {
                public void keyPressed(KeyEvent e) {

                    switch (e.getKeyCode()) {
                    case (KeyEvent.VK_UP): setyDir(-1);
                    break;
                    case (KeyEvent.VK_DOWN): setyDir(1);
                    break;
                    case (KeyEvent.VK_LEFT): setxDir(-1);
                    break;
                    case (KeyEvent.VK_RIGHT): setxDir(1);
                    break;
                    }
                }

                public void keyReleased(KeyEvent e) {
                    switch (e.getKeyCode()) {
                    case (KeyEvent.VK_UP): setyDir(0);
                    break;
                    case (KeyEvent.VK_DOWN): setyDir(0);
                    break;
                    case (KeyEvent.VK_LEFT): setxDir(0);
                    break;
                    case (KeyEvent.VK_RIGHT): setxDir(0);
                    break;
                    }
                }
            });
        }

        private void repaintSquare(int x, int y) {
            int OFFSET = 1;
            if ((squareX!=x) || (squareY!=y)) {
                repaint(squareX,square,Y,squareW+OFFSET,squareH+OFFSET);
                squareX=x;
                squareY=y;
                repaint(squareX,squareY,squareW+OFFSET,squareH+OFFSET);
            }
        }

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);  
            g.setColor(Color.RED);
            g.fillRect(squareX,squareY,squareW,squareH);
        }
    }

    private void move() {
        panel.repaintSquare(xPos, yPos);
        xPos += xDir;
        yPos += yDir;
    }

    private void setxDir(int x) {
        this.xDir = x;
    }

    private void setyDir(int y) {
        this.yDir = y;
    }

    public static void main(String[] args) {
        Thread t = new Thread(new Boxxy());
        t.start();
    }

    @Override
    public void run() {
        try {
            while(true) {
                move();
                Thread.sleep(5);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

questionAnswers(1)

yourAnswerToTheQuestion