Я хочу найти способ сделать своеобразное действие «вставить из буфера обмена». Давайте для простоты предположим, что содержимое буфера обмена — текст, а не файл. Всякий раз, когда вы нажимаете Ctrl+V
, он вставляет этот контент (который является текстом) в текущий открытый файл, который имеет фокус.
У меня есть приложение для ловли Глобальный горячая клавиша. Обратите внимание, что это не оконное приложение, а консольное, и оно ловит горячую клавишу глобально. Допустим, у меня есть горячая клавиша Ctrl+U
, Итак, что я хочу сделать, это когда я нажимаю Ctrl+U
Я хочу вставить некоторый предопределенный текст в текущий открытый файл. Как Ctrl+V
делает! Отличия от стандарта Ctrl+V
что я хочу вставить предопределенный текст и горячая клавиша разные.
Как мне это сделать?
Я бы предпочел кросс-платформенное решение, но прежде всего я собираюсь сделать это для Linux, в частности, для Ubuntu. Язык не важен, но Java или Scala были бы лучше. Конечно, я понимаю, что решения для Java используют API для собственных ОС.
Я надеюсь, что это хакерское решение будет работать, но оно все еще не проверено, я не уверен, как отловить событие для горячей клавиши.
Идея этого кода состоит в следующих пяти шагах:
Это должно создать видимость нового буфера обмена (если нет, надеюсь, это вдохновит вас на поиск лучшего, менее хакерского решения).
Без дальнейших церемоний, вот мой код. Сначала у меня есть простой вспомогательный метод для установки значения в буфер обмена (как мы делаем это дважды).
public static void setClipboard(String s) {
StringSelection contents = new StringSelection(s);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(contents, contents);
}
И затем, у меня есть основной метод, где я прохожу пять шагов по порядку.
public static void main(String[] args) {
// Step 1 ) get old text
String oldText = "";
try {
oldText = (String) Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.stringFlavor);
} catch (UnsupportedFlavorException ufe) {
ufe.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
}
// Step 2 ) paste our text in clipboard
setClipboard("This lorem ipsum predefined string blows my mind.");
// Step 3 ) trigger paste event
Robot robot = null;
try {
robot = new Robot();
} catch (AWTException awte) {
awte.printStackTrace();
}
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_V);
// Step 4 ) Release paste event
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.keyRelease(KeyEvent.VK_V);
// Step 5 ) Reset clipboard
setClipboard(oldText);
}
[Редактировать]:
Вот некоторый код для проверки того, какое содержимое находится в буфере обмена — изображение, текст и т. Д. Ошибка в кодировке Unicode возникла из-за того, что старое содержимое буфера обмена было чем-то, что не могло быть представлено простой строкой. Чтобы исправить эту ошибку, вам нужно будет проверить, было ли старое содержимое изображением, а старое — текстом, и сохранить их соответствующим образом.
public static int kindOfContents() {
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
Transferable contents = clipboard.getContents(null);
if(contents.isDataFlavorSupported(DataFlavor.stringFlavor)) {
// String, save temporarily as string and write back as string
return 0;
} else if(contents.isDataFlavorSupported(DataFlavor.imageFlavor)) {
// Image, save temporarily as BufferedImage and write back as image
return 1;
} else if(contents.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
// List of files, save temporarily as java.util.List interface and write back as the file lists
return 2;
}
}
Если содержимое является текстовым, то для сохранения и записи содержимого вы должны использовать старый метод, приведенный ниже для удобства.
// Step 1 ) get old text
String oldText = "";
try {
oldText = (String) Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.stringFlavor);
} catch (UnsupportedFlavorException ufe) {
ufe.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
}
// Step 5 ) Reset clipboard
setClipboard(oldText);
Однако, если содержимое является изображением, для временного сохранения и перезаписи необходимо выполнить следующее. Обратите внимание, что код для написания изображения не мой, но взят из принятого ответа на Установка изображений в буфер обмена — Java
// Step 1 ) get old image
BufferedImage img = null;
try {
img = (BufferedImage) Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.imageFlavor);
} catch (UnsupportedFlavorException ufe) {
ufe.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
}
Взято из Установка изображений в буфер обмена — Java :
// Step 5 ) Reset clipboard
ImageTransferable transferable = new ImageTransferable( image );
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(transferable, null);
static class ImageTransferable implements Transferable
{
private Image image;
public ImageTransferable (Image image)
{
this.image = image;
}
public Object getTransferData(DataFlavor flavor)
throws UnsupportedFlavorException
{
if (isDataFlavorSupported(flavor))
{
return image;
}
else
{
throw new UnsupportedFlavorException(flavor);
}
}
public boolean isDataFlavorSupported (DataFlavor flavor)
{
return flavor == DataFlavor.imageFlavor;
}
public DataFlavor[] getTransferDataFlavors ()
{
return new DataFlavor[] { DataFlavor.imageFlavor };
}
}
Других решений пока нет …