В чем проблема, когда KeyListener добавлен, но keyEvent не работает при нажатии? - PullRequest
1 голос
/ 30 марта 2019

Мой слушатель добавлен в JFrame / JPanel. Проблема в том, что когда я нажимал кнопку, ничего не происходит. В чем может быть проблема здесь?

Используются следующие коды:

public class GAMEGAMEHA extends JPanel{

    public static JFrame PacmanMainFrame = new JFrame();
    TheJGame newGame;

    GAMEGAMEHA() {
        setSize(new Dimension(1200, 700));
        JLabel BG = new JLabel();
        JButton start = new JButton();
        JButton howTo = new JButton();
        JButton credit = new JButton();
        JButton exit = new JButton();

        setLayout(null);

        start.setIcon(new ImageIcon(getClass().getResource("/data/SB.png")));

        start.setContentAreaFilled(false);
        start.addActionListener((ActionEvent e) -> {
            newGame = new TheJGame();
            GAMEGAMEHA.PacmanMainFrame.getContentPane().removeAll();
            System.out.println("Removed Components");
            GAMEGAMEHA.PacmanMainFrame.add(newGame);
            System.out.println("Added Game");
            GAMEGAMEHA.PacmanMainFrame.addKeyListener(newGame);
            System.out.println("Added KeyListeners");
            GAMEGAMEHA.PacmanMainFrame.setVisible(true);
            System.out.println("Set Visiblity to True");
        });

        start.setBorderPainted(false);
        add(start);
        start.setBounds(440, 140, 300, 70);

        howTo.setIcon(new ImageIcon(getClass().getResource("/data/HowToButton.jpg")));
        howTo.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e
            ) {
                HowTo HowToScreen = new HowTo();
                GAMEGAMEHA.PacmanMainFrame.getContentPane().removeAll();
                GAMEGAMEHA.PacmanMainFrame.add(HowToScreen);
                GAMEGAMEHA.PacmanMainFrame.setVisible(true);
            }
        });
        howTo.setBorderPainted(false);
        add(howTo);

        howTo.setBounds(440, 220, 300, 70);

        credit.setIcon(new ImageIcon(getClass().getResource("/data/CreditsButton.jpg")));
        credit.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e
            ) {
                Credit CreditScreen = new Credit();
                GAMEGAMEHA.PacmanMainFrame.getContentPane().removeAll();
                GAMEGAMEHA.PacmanMainFrame.add(CreditScreen);
                GAMEGAMEHA.PacmanMainFrame.setVisible(true);
            }
        });
        credit.setBorderPainted(false);
        add(credit);

        credit.setBounds(440, 300, 300, 70);

        exit.setIcon(new ImageIcon(getClass().getResource("/data/ExitButton.jpg")));
        exit.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e
            ) {
                System.exit(JFrame.EXIT_ON_CLOSE);
            }
        }
        );
        exit.setBorderPainted(
                false);
        add(exit);

        exit.setBounds(
                440, 380, 300, 70);

        BG.setIcon(
                new ImageIcon(getClass().getResource("/data/MainMenu.jpg")));
        BG.setText(
                "BackgroundImage");
        add(BG);

        BG.setBounds(
                0, 0, 1200, 700);

    }

    public static void main(String[] args) {
        GAMEGAMEHA GameMENU = new GAMEGAMEHA();
        PacmanMainFrame.setSize(new Dimension(1200, 700));
        PacmanMainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        PacmanMainFrame.setTitle("THE JUNGLE GAME: A Object-Oriented Programming Project");
        PacmanMainFrame.setResizable(false);
        PacmanMainFrame.setLocationRelativeTo(null);
        PacmanMainFrame.add(GameMENU);
        PacmanMainFrame.setVisible(true);
    }

}

Это игра началась: Проблема здесь. Главное меню хорошо, но при переходе сюда оно не принимает и не читает никаких клавиш.

public class TheJGame extends JPanel implements KeyListener {

    BackgroundGame BG = new BackgroundGame();
    MainCharacter bens = new MainCharacter();
    static int MainCx = 22;
    static int MainCy = 20;
    static int BGx = 0;
    static int BGy = 545;

    TheJGame() {
        bens.initializeMChar();
        BG.initializeGGround();
        setBounds(0, 0, 1200, 700);
        setFocusable(true);

    }

    @Override
    public void paint(Graphics g) {

        g.setColor(Color.BLACK);
        g.fillRect(0, 0, 1200, 700);
        g.drawImage(BG.GGround, BGx, BGy, this);
        g.drawImage(BG.GGround, BGx + 1200, BGy, this);
        g.drawImage(bens.MCharacter, MainCx, MainCy, this);
        updateBG();
        updateFall();
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();

        if (key == KeyEvent.VK_SPACE) {
            MainCy+=5;
            repaint();
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }

    public void updateFall() {

        if (MainCy <= 445) {
            MainCy += 1;
            repaint();
        }

    }

    private void updateBG() {
        BGx -= 1;

        if (BGx == -1200) {
            BGx = 0;
        }

        repaint();

    }


}

Ответы [ 2 ]

1 голос
/ 30 марта 2019

Основная проблема

«Основная» проблема заключается в том, что KeyListener является плохим выбором для мониторинга ввода с клавиатуры в Swing, он страдает от проблемы фокуса, когда компонент, на который он зарегистрирован, должен быть фокусируемым и иметь фокусировку клавиатуры, и поскольку вы добавив кнопки в пользовательский интерфейс, они украдут фокус у компонента.

Лучшее общее решение заключается в использовании API связывания клавиш , который дает вам возможность определять, на каком уровне фокусировки должны срабатывать привязки

Дополнительные проблемы ...

null макеты, как известно, сложны в управлении и обслуживании. Есть много факторов, которые влияют на то, как лучше компонент должен отображаться на экране. Вам следует избегать null макетов, где это возможно, и использовать один или несколько менеджеров макетов, они сэкономят вам много волос

Вы переопределили paint, но вы не смогли выполнить цепочку красок (не вызвав super.paint). Живопись - сложный процесс, состоящий из нескольких этапов.

Как правило, вы должны переопределить paintComponent (и вызвать super.paintComponent перед выполнением любой пользовательской рисования).

Прочитайте Рисование в AWT и Swing и Выполнение пользовательской живописи для получения более подробной информации о рисовании в Swing

0 голосов
/ 30 марта 2019

Вы не добавили ключевой слушатель в JPnael, просто реализации интерфейса недостаточно, чтобы добавить его на панель.

addKeyListner(this);

Добавьте эту строку кода в ваш конструктор.

...