(Примечание: мне известен этот вопрос , в котором пользователь должен был бы ввести команду терминала для решения этой проблемы, но я бы предпочел решение, в котором решение может быть введено в приложение.)
Чтобы объяснить, я использую привязки клавиш в приложении 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();
}
}