Почему Key Listener работает только иногда

Итак, вот мой код. Я реализовал keyListener и actionListener. Я смог изменить координаты панели, чтобы она могла двигаться влево или вправо. Но я заметил, что keyListener не очень хорошо фокусируется. Мне нужно снова и снова закрывать и запускать приложение, чтобы оно работало и я мог его контролировать. Я слышал о keyBidings, но не совсем понимаю. Как я могу реализовать keyBindings, чтобы сделать ответы клавиатуры более точными?

 package brickBreaker;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.Timer;

import javax.swing.JPanel;

public class game extends JPanel implements KeyListener, ActionListener {
    private Timer timer;
    private boolean play = false;
    private int playerx = 650;
    private int ballx=900, bally=500,ballxdir=-1,ballydir=-2;
    int delay =8;
    public game() {
        addKeyListener(this);
        setFocusable(true);
        setFocusTraversalKeysEnabled(false);
        timer = new Timer(delay, this);
        timer.start();

    }


    public void paint(Graphics g) {
        g.setColor(Color.BLACK);
        g.fillRect(1, 1, 1500 ,950);

        // user panel
        g.setColor(Color.CYAN);
        g.fillRect(playerx, 900, 250, 15);

        //ball
        g.setColor(Color.GREEN);
        g.fillOval(ballx, bally, 30, 30);

        g.dispose();
    }



    public void right() {
        play = true;
        playerx += 20;
    }
    public void left() {
        play = true;
        playerx -=20;
    }

    @Override
    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();
        if (key ==KeyEvent.VK_LEFT) {
            System.out.print("Left\n");
            left();
        }if (key == KeyEvent.VK_RIGHT) {
            System.out.print("Right\n");
            right();
        }



    }

    @Override
    public void keyReleased(KeyEvent arg0) {


    }

    @Override
    public void keyTyped(KeyEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void actionPerformed(ActionEvent e) {
        timer.start();
        if (play) {

            ballx +=ballxdir;
            bally +=ballydir;
            if (ballx <0) {
                ballxdir =-ballxdir;
            }
            if (bally <0) {
                ballydir =-ballydir;
            }
            if (ballx <1000) {
                ballxdir =-ballxdir;
            }




        }
        repaint();

    }

}
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
439
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Извините за то, что очень сильно опоздал с ответом, но я думаю, что решил вашу проблему.

Вы правы - вам нужно снова и снова открывать и закрывать JPanel, прежде чем она заработает. Но проблема в следующем: JPanel продолжает терять фокус. Итак, все, что вам нужно сделать, это добавить:

requestFocus(true);

методу paint(), вот так:

public void paint(Graphics g) {
    requestFocus(true);
    g.setColor(Color.BLACK);
    g.fillRect(1, 1, 1500 ,950);

    // user panel
    g.setColor(Color.CYAN);
    g.fillRect(playerx, 900, 250, 15);

    //ball
    g.setColor(Color.GREEN);
    g.fillOval(ballx, bally, 30, 30);

    g.dispose();
}

и программа работает!

Так просто ... так элегантно. Спасибо.

Daniel Palacios 02.04.2018 22:26

Другие вопросы по теме