Как вы обрабатываете события клавиатуры в Linux?

Я использую убунту. Способ, которым Ubuntu обрабатывает ввод с клавиатуры, отличается от того, что используется в Windows. В ubuntu после запуска события нажатия клавиши сразу после этого запускается событие отпускания клавиши, даже если вы не отпускаете клавишу. Эти ложные события Key Release затрудняют программирование игр, особенно программирование обнаружения столкновений. Каким бы совершенным ни был мой код, я не могу решить проблему.

В качестве доказательства, если вы просто напишете программу, которая будет выводить независимо от того, нажата клавиша или отпущена, вы увидите, что вывод в ubuntu будет выглядеть так: keyPressed > keyReleased > keyPressed > keyReleased и т. д., даже если вы не отпускаете ключ. Тогда как в окнах - Нажата клавиша > Нажата клавиша > Нажата клавиша > Нажата клавиша и так далее.

Вы знаете какой-нибудь способ справиться с этим?

Вот простой код, который прояснит мою проблему, если вы запустите это на Ubuntu: -

import java.awt.Dimension;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Strange extends JPanel implements KeyListener{

    public Strange(){
        this.setPreferredSize(new Dimension(500, 500));

        addKeyListener(this);
        setFocusable(true);

        JFrame frame=new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(this);
        frame.pack();
        frame.setVisible(true);
    }

    @Override
    public void keyPressed(KeyEvent e) {
        if(e.getKeyCode()==KeyEvent.VK_LEFT)
            System.out.println("left is pressed");
    }

    @Override
    public void keyReleased(KeyEvent e) {
        if(e.getKeyCode()==KeyEvent.VK_LEFT)
            System.out.println("left is released");
    }

    @Override
    public void keyTyped(KeyEvent e) {}

    public static void main(String[] args){
        new Strange();
    }
}

person arandomguy    schedule 20.05.2014    source источник
comment
какой язык вы используете. Можете ли вы показать код.   -  person adnan kamili    schedule 20.05.2014
comment
я использую джаву. Но проблема, которую я опубликовал, является проблемой низкого уровня, не зависящей от какого-либо языка программирования.   -  person arandomguy    schedule 20.05.2014
comment
@adnankamili хорошо, я разместил код, чтобы продемонстрировать свою проблему   -  person arandomguy    schedule 20.05.2014
comment
Я на самом деле использую C++ и никогда не сталкивался с этой проблемой. Кажется, вы переопределяете неправильное нажатие клавиши обработчика, обычно эквивалентное keydown + keyup, разве у вас нет событий keyup и keydown.   -  person adnan kamili    schedule 20.05.2014
comment
@adnankamili, вы говорите, что в С++ вы не сталкиваетесь с этой проблемой, почему? ты используешь убунту?   -  person arandomguy    schedule 20.05.2014
comment
да, я использую Ubuntu, и это справедливо для любого дистрибутива Linux, поскольку ядро ​​​​одинаково. Скорее всего, вы переопределяете неправильные обработчики, пожалуйста, рассмотрите мой предыдущий комментарий.   -  person adnan kamili    schedule 20.05.2014
comment
@adnankamili эээ... я так не думаю :D спасибо за комментарий.   -  person arandomguy    schedule 20.05.2014
comment
это дубликат stackoverflow.com/questions/1736828/ или stackoverflow.com/questions/1457071/ Кстати: мой Linux (Arch) не отправляет keyReleased для ВК_LEFT. Это, однако, для обычных ключей.   -  person close2    schedule 21.05.2014


Ответы (1)


Попробуйте использовать метод обновления с таким игровым циклом:

public class Strange extends JPanel implements KeyListener{

public Strange(){
    this.setPreferredSize(new Dimension(500, 500));

    JFrame frame=new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(this);
    frame.pack();
    frame.setVisible(true);

    while(true){
       update();

       try{
           Thread.sleep(10);
       }catch(Exception e){}
    }
}

public void update(){
    addKeyListener(this);
    setFocusable(true);
}

@Override
public void keyPressed(KeyEvent e) {
    if(e.getKeyCode()==KeyEvent.VK_LEFT)
        System.out.println("left is pressed");
}

@Override
public void keyReleased(KeyEvent e) {
    if(e.getKeyCode()==KeyEvent.VK_LEFT)
        System.out.println("left is released");
}

@Override
public void keyTyped(KeyEvent e) {}

public static void main(String[] args){
    new Strange();
}
}

Я не на ubuntu, поэтому я не уверен, что это работает. Но я надеюсь.

person Maial    schedule 20.05.2014
comment
ну это вообще не относится к моему вопросу. - person arandomguy; 21.05.2014