Я работаю над приложением Java FX, которое включает использование «мышки» для захвата текста, выделенного мышью. Это работало без проблем при компиляции и запуске с Java 8, но в настоящее время я должен использовать Java 10, что вызвало проблему в Mac OS X (нет проблем при запуске в Windows 10).
Проблема заключается в том, что при выделении текста из документа (например, текста в TexEdit) выделенный текст удаляется и заменяется на 'c', а не копируется. Это происходит не каждый раз, но случается очень часто.
Я сократил класс mouseHook до базового теста, который показывает проблему:
Класс MouseHook --------------------------------------------- ------------
package problem;
import org.jnativehook.GlobalScreen;
import org.jnativehook.mouse.NativeMouseEvent;
import org.jnativehook.mouse.NativeMouseInputListener;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.event.KeyEvent;
import java.util.Timer;
import java.util.TimerTask;
public class MouseHook implements NativeMouseInputListener
{
private static MouseHook mouseHook = null;
private Robot mouseRobot = null;
private boolean mouseLeftButtonDown = false;
private boolean dragged = false;
private MouseHook()
{
//disable console output from JNativeHook's internal logger (mouse-tracking, etc)
java.util.logging.Logger logger = java.util.logging.Logger.getLogger(GlobalScreen.class.getPackage().getName());
logger.setLevel(java.util.logging.Level.OFF);
}
public static synchronized MouseHook getInstance()
{
if(mouseHook == null)
{
mouseHook = new MouseHook();
GlobalScreen.addNativeMouseListener(mouseHook);
GlobalScreen.addNativeMouseMotionListener(mouseHook);
}
return mouseHook;
}
@Override
public void nativeMousePressed(NativeMouseEvent e)
{
//If left button pressed, set mouseLeftButtonDown and look-out for dragging
if(e.getButton() == NativeMouseEvent.BUTTON1)
{
mouseLeftButtonDown = true;
}
}
@Override
public void nativeMouseDragged(NativeMouseEvent e)
{
//only record a drag if left mouse button is held down.
//NativeMouseEvent doesn't say which button was the source, hence test the variable.
if(mouseLeftButtonDown)
{
dragged = true;
}
}
@Override
public void nativeMouseReleased(NativeMouseEvent e)
{
//copy text if the mouse was dragged while the left mouse button was held down.
if(e.getButton() == NativeMouseEvent.BUTTON1)
{
final Timer timer = new Timer("ReleaseDetect");
timer.schedule(new TimerTask()
{
@Override
public void run()
{
if(dragged)
{
copy();
dragged = false;
}
mouseLeftButtonDown = false;
timer.cancel();
}
}, 500);
}
}
@Override
public void nativeMouseClicked(NativeMouseEvent e)
{}
@Override
public void nativeMouseMoved(NativeMouseEvent e)
{}
private synchronized void copy()
{
try
{
if(mouseRobot == null)
{
mouseRobot = new Robot();
mouseRobot.setAutoDelay(100);
mouseRobot.setAutoWaitForIdle(true);
}
if(System.getProperty("os.name").toLowerCase().contains("mac"))
{
mouseRobot.keyPress(KeyEvent.VK_META);
mouseRobot.keyPress(KeyEvent.VK_C);
mouseRobot.keyRelease(KeyEvent.VK_C);
mouseRobot.keyRelease(KeyEvent.VK_META);
}
else
{
mouseRobot.keyPress(KeyEvent.VK_CONTROL);
mouseRobot.keyPress(KeyEvent.VK_C);
mouseRobot.keyRelease(KeyEvent.VK_C);
mouseRobot.keyRelease(KeyEvent.VK_CONTROL);
}
Thread.sleep(250);
Transferable t=Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null);
if(t != null && t.isDataFlavorSupported(DataFlavor.stringFlavor))
{
String activeContent = (String) t.getTransferData(DataFlavor.stringFlavor);
System.out.println(activeContent);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
Класс для запуска примера ------------------------------------------ --------------
package problem;
import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
public class Runnit
{
private static MouseHook mouseHook;
public static void main(String[] args)
{
try
{
GlobalScreen.registerNativeHook();
}
catch(NativeHookException e)
{
System.out.println("Cannot set up the NativeHook listener on the GlobalScreen");
}
mouseHook = MouseHook.getInstance();
}
}
Я использую Java 10.0.2 и jNativeHook 2.1.0 от Oracle с Mac OS High Sierra (10.13.6) на Mac mini.
Кажется, проблема в том, чтобы сделать это java.awt.Robot, а не jNativeHook.
например. Если я заменю VK_C keyPress / Release на VK_B, то мышиный крюк удалит выделенный текст и заменит его на 'b'.
Моим внутренним ощущением было то, что нажатие клавиши VK_META игнорировалось. Я пытался вставить задержку до того нажатия, но это не имеет значения.
Я также пытался использовать другую мышь и чужой Macintosh, но проблема все еще возникает. Как я уже сказал, это происходит только в Mac OS X, а не в Windows 10, когда код компилируется и запускается с Java 10.
Буду признателен, если у кого-нибудь появятся идеи относительно того, является ли это безнадежным делом или есть обходной путь. Возможно, я упустил что-то очевидное, так как обычно работаю в Windows и знаком с lsss с Mac OS X.