KeyListener на Canvas: keyReleased задейства, но няма keyPressed или keyTyped

Имам JFrame с Canvas в него (кощунство, знам). Canvas има прикачени MouseListener и KeyListener и е поискал фокус с:

canvas.setFocusable(true);
canvas.requestFocusInWindow();

Когато го стартирам за първи път, всичко се държи според очакванията, като събитията летят навсякъде. След няколко секунди той спира да отговаря на нормално въвеждане на клавиш (keyPressed и keyTyped не се задействат). Странно, държането на детелина (аз съм на OSX) кара всичко да работи нормално.

Какво става? Защо се случва това и какво мога да направя, за да го поправя?

Редактиране: Разбрах какво поведение задейства грешката. Започва да се случва само когато задържите клавиш. Когато го пуснете, събитията keyPressed спират да се задействат. По-долу е моят MCVE.

import java.awt.Canvas;
import java.awt.Graphics2D;
import java.awt.Dimension;
import java.awt.image.BufferStrategy;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;

public class Listener implements MouseListener,KeyListener {

    JFrame frame;
    Canvas screen;

    public Listener() {
        // initialize the screen canvas
        screen = new Canvas();
        Dimension size = new Dimension(640, 480);
        screen.setMinimumSize(size);
        screen.setMaximumSize(size);
        screen.setPreferredSize(size);
        screen.addMouseListener(this);
        screen.addKeyListener(this);
        screen.setFocusable(true);

        // initialize the frame
        frame = new JFrame("Parasite");
        frame.add(screen);
        frame.pack();
        frame.setVisible(true);

        screen.requestFocusInWindow();

        // create buffer strategy (after showing frame)
        screen.createBufferStrategy(2);
    }

    public static void main(String[] args) {
        Listener listener = new Listener();
    }

    public void mouseClicked(MouseEvent e) {
        System.out.println("click");
    }

    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
    public void mousePressed(MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {}

    public void keyTyped(KeyEvent e) {
        System.out.println("t " + e.getKeyChar());
    }

    public void keyPressed(KeyEvent e) {
        System.out.println("p " + e.getKeyChar());
    }

    public void keyReleased(KeyEvent e) {
        System.out.println("r " + e.getKeyChar());
    }
}

person Shriken    schedule 24.11.2014    source източник
comment
Помислете за предоставяне на изпълним пример, който демонстрира вашия проблем. Това ще доведе до по-малко объркване и по-добри отговори. Може да помислите за добавяне на MouseListener към платното и да извиквате requestFocusInWindow всеки път, когато се щракне върху него   -  person MadProgrammer    schedule 25.11.2014
comment
Не мога да го възпроизведа. Моля, предоставете MCVE.   -  person Radiodef    schedule 25.11.2014
comment
Благодаря за съвета. Написах MCVE и това ми помогна да намеря по-точно ситуацията, в която възниква грешката. Подробности в редакцията по-горе.   -  person Shriken    schedule 25.11.2014


Отговори (1)


Оказва се, че грешката е предизвикана от някакво подло взаимодействие с менюто с акценти на osx. Системата по подразбиране (поне за Yosemite) е да изскача меню, което ви предлага гласни с ударение, когато задържите клавиш с буква. Въпреки че не показваше менюто, трябва да е правил нещо зад кулисите, което е обърквало фокуса.

Изключване менюто с акценти реши проблема. За тези, които не искат да кликнат, въведете следното във вашия терминал.

defaults write -g ApplePressAndHoldEnabled -bool false
person Shriken    schedule 26.11.2014