На самом деле, я столкнулся с чем-то похожим, и я решил с помощью робота . Когда вы хотите узнать, включена ли блокировка прокрутки, и получить правильный статус, позвольте роботу нажать / отпустить кнопку. Кнопка 2 раза. Тем не менее, (возможно, ошибка или около того), статус не является правильным, если вы делаете это мгновенно. Вам нужно будет добавить задержку (не заметную человеку), чтобы получить правильный статус. Это означает, что вам придется делать это в фоновом потоке, а не в EDT, поскольку это приведет к зависанию EDT (когда потоки спят, события не могут происходить).
См. Этот пример (некоторые комментарии внутри кода). Это всегда дает правильный статус блокировки прокрутки, даже если окно не было в фокусе. Кроме того, есть глобальный слушатель клавиш, поэтому вы знаете, нажата ли блокировка прокрутки (но срабатывает только тогда, когда окно имеет фокус).
public class ScrollLockDetection {
private static final int SCROLL_LOCK = KeyEvent.VK_SCROLL_LOCK;
private JFrame frame;
public ScrollLockDetection() {
frame = new JFrame();
frame.setSize(400, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.addWindowFocusListener(new WindowAdapter() {
@Override
public void windowGainedFocus(WindowEvent e) {
showScrollLockStatus();
}
});
registerGlobalScrollLockListener();
frame.setVisible(true);
}
private void registerGlobalScrollLockListener() {
Toolkit.getDefaultToolkit().addAWTEventListener(event -> {
if (event instanceof KeyEvent) {
KeyEvent keyEvent = (KeyEvent) event;
if (keyEvent.getID() == KeyEvent.KEY_RELEASED && keyEvent.getKeyCode() == KeyEvent.VK_SCROLL_LOCK) {
showScrollLockStatus();
}
}
}, AWTEvent.KEY_EVENT_MASK);
}
private void showScrollLockStatus() {
ScrollLockDetector scrollLockDetector = new ScrollLockDetector(b -> {
System.out.println("Scroll lock ON: " + b);
});
scrollLockDetector.execute();
}
class ScrollLockDetector extends SwingWorker<Boolean, Void> {
private Consumer<Boolean> consumer;
public ScrollLockDetector(Consumer<Boolean> consumer) {
this.consumer = consumer;
}
@Override
protected Boolean doInBackground() throws Exception {
//First we have to remove all global key listeners so the robot does not fire them
Toolkit toolkit = Toolkit.getDefaultToolkit();
AWTEventListener[] globalKeyListeners = toolkit.getAWTEventListeners(AWTEvent.KEY_EVENT_MASK);
while (toolkit.getAWTEventListeners(AWTEvent.KEY_EVENT_MASK).length > 0)
toolkit.removeAWTEventListener(toolkit.getAWTEventListeners(AWTEvent.KEY_EVENT_MASK)[0]);
Robot robot = new Robot();
robot.keyPress(SCROLL_LOCK);
robot.keyRelease(SCROLL_LOCK);
Thread.sleep(3);
robot.keyPress(SCROLL_LOCK);
robot.keyRelease(SCROLL_LOCK);
Thread.sleep(3);
//Re-add the global key listeners
Stream.of(globalKeyListeners).forEach(listener -> toolkit.addAWTEventListener(listener, AWTEvent.KEY_EVENT_MASK));
return toolkit.getLockingKeyState(SCROLL_LOCK);
}
@Override
protected void done() {
try {
Boolean isScrollLockOn = get();
consumer.accept(isScrollLockOn);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new ScrollLockDetection();
});
}
}
После объявлений в комментариях (они должны существовать в вопрос), лучший способ добиться включения / выключения блокировки прокрутки - использовать слушатель глобального ключа . Когда ваше приложение запускается, оно принимает состояние блокировки прокрутки с getLockingKeyState
, а затем каждый раз, когда нажимается блокировка прокрутки, вы меняете его.
См. Полный пример:
public class GlobalKeyListenerExample implements NativeKeyListener {
private static boolean scrollLock;
@Override
public void nativeKeyPressed(NativeKeyEvent e) {
}
@Override
public void nativeKeyReleased(NativeKeyEvent e) {
if (e.getKeyCode() == NativeKeyEvent.VC_SCROLL_LOCK) {
scrollLock = !scrollLock;
System.out.println("Scroll lock is:" + (scrollLock ? "ON" : "OFF"));
}
}
@Override
public void nativeKeyTyped(NativeKeyEvent e) {
}
public static void main(String[] args) {
try {
scrollLock = Toolkit.getDefaultToolkit().getLockingKeyState(KeyEvent.VK_SCROLL_LOCK);
System.out.println("Initial state of scrollock: " + (scrollLock ? "ON" : "OFF"));
GlobalScreen.registerNativeHook();
Logger logger = Logger.getLogger(GlobalScreen.class.getPackage().getName());
logger.setLevel(Level.WARNING);
// Don't forget to disable the parent handlers.
logger.setUseParentHandlers(false);
// Don't forget to disable the parent handlers.
} catch (NativeHookException ex) {
System.err.println("There was a problem registering the native hook.");
System.err.println(ex.getMessage());
System.exit(1);
}
GlobalScreen.addNativeKeyListener(new GlobalKeyListenerExample());
}
}
Теперь, чтобы проверьте, включена ли блокировка прокрутки, просто проверьте переменную scrollLock
.