Остановить диакритические знаки OSX, отключив привязки клавиш в Java для всех пользователей? - PullRequest
0 голосов
/ 24 июня 2018

(Примечание: мне известен этот вопрос , в котором пользователь должен был бы ввести команду терминала для решения этой проблемы, но я бы предпочел решение, в котором решение может быть введено в приложение.)

Чтобы объяснить, я использую привязки клавиш в приложении Java;однако, если вы держите клавишу, например, a, e, i, o, u, n, s и т. д., диакритическое меню, используемое OSX, каким-то образом полностью отключает ввод с клавиатуры.

Однако это не влияет на мышьвведите, если это уместно.

Вот пример кода, в котором проблема может быть продемонстрирована.Если вы нажмете и удерживаете одну из вышеупомянутых клавиш в OSX в течение приблизительно одной секунды или более, привязки клавиш полностью перестанут работать.(Однако, для большей уверенности я рекомендую удерживать клавишу нажатой.

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.WindowConstants;

public class Test extends JPanel implements ActionListener {
    private static final long serialVersionUID = 1L;

    private static JFrame frame;

    private static boolean up = false, down = false, left = false, right = false;

    private static int x = 275, y = 275;

    public static void main(String[] args) {
        Test t = new Test();
        t.setBounds(0, 0, 1200, 600);
        t.setVisible(true);

        Timer repaintTimer = new Timer(2, t);

        frame = new JFrame();
        frame.setSize(600, 600);

        setUpKeyActions(t);

        frame.add(t);

        Dimension dim = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setLocation((dim.width - frame.getWidth()) / 2, (dim.height - frame.getHeight()) / 2);
        frame.getContentPane().setLayout(null);
        frame.setAlwaysOnTop(true);
        frame.setResizable(false);

        repaintTimer.start();

        frame.setVisible(true);
        frame.requestFocus();
    }

    private static void setUpKeyActions(Test t) {
        int condition = WHEN_IN_FOCUSED_WINDOW;

        new KeyAction(t, condition, KeyEvent.VK_UP, 0, false) {
            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                up = true;
            }

        };

        new KeyAction(t, condition, KeyEvent.VK_UP, 0, true) {
            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                up = false;
            }

        };

        new KeyAction(t, condition, KeyEvent.VK_LEFT, 0, false) {
            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                left = true;
            }

        };

        new KeyAction(t, condition, KeyEvent.VK_LEFT, 0, true) {
            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                left = false;
            }

        };

        new KeyAction(t, condition, KeyEvent.VK_RIGHT, 0, false) {
            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                right = true;
            }

        };

        new KeyAction(t, condition, KeyEvent.VK_RIGHT, 0, true) {
            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                right = false;
            }

        };

        new KeyAction(t, condition, KeyEvent.VK_DOWN, 0, false) {
            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                down = true;
            }

        };

        new KeyAction(t, condition, KeyEvent.VK_DOWN, 0, true) {
            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                down = false;
            }

        };

    }

    private static abstract class KeyAction extends AbstractAction {
        private static final long serialVersionUID = 1L;

        KeyAction(JComponent component, int condition, int keyCode, int modifiers, boolean onKeyRelease) {
            InputMap inputMap = component.getInputMap(condition);
            ActionMap actionMap = component.getActionMap();
            KeyStroke keyStroke = KeyStroke.getKeyStroke(keyCode, modifiers, onKeyRelease);
            inputMap.put(keyStroke, keyStroke.toString());
            actionMap.put(keyStroke.toString(), this);
        }

    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        if(up)
            y -= 1;
        if(down)
            y += 1;
        if(right)
            x += 1;
        if(left)
            x -= 1;
        if(x < 0)
            x = 0;
        else if(x > frame.getWidth() - 30)
            x = frame.getWidth() - 30;
        if(y < 0)
            y = 0;
        else if(y > frame.getHeight() - 50)
            y = frame.getHeight() - 50;
        g.drawRect(x, y, 30, 30);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        frame.repaint();
    }

}

1 Ответ

0 голосов
/ 05 июля 2018

Чтобы ответить на мой вопрос, проблема была в версии Java.

У меня был JDK 1.8.0_151, но, очевидно, эта проблема была исправлена ​​в некоторой итерации вплоть до JDK 1.8.0_172.

Итак, чтобы эта проблема не возникала у пользователей моего приложения, мне потребуется JDK 1.9 или выше с использованием org.apache.commons.lang3.SystemUtils и использование метода isJavaVersionAtLeast(JavaVersion requiredVersion) из этого ответа..

Обновление:

Я на самом деле планирую использовать метод, полученный из моего вопроса здесь , поскольку он позволяет мне не иметьтребовать JRE 1.9, но вместо этого позволяет мне сделать минимальный 1.8.0_172.

...