Restoring Clipboard after pasting programmatically in Java - java

I'm trying to programmatically add some text to the system clipboard, paste it to a random application from there and restore the clipboard to the state it was before, but Java seems to have a problem with that.
Out of ten tries it never pastes the text more than eight times and sometimes even the wrong text (the text that was in the clipboard before) is pasted.
Any help would be greatly appreciated!
public class ClipboardTestClass {
static Robot robot;
public static void main(String[] args) {
try {
robot = new Robot();
} catch (AWTException ex) {
Logger.getLogger(TestApp.class.getName()).log(Level.SEVERE, null, ex);
}
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
Logger.getLogger(TestApp.class.getName()).log(Level.SEVERE, null, ex);
}
for(int i = 0; i< 10; i++){
enterString("Hello\n");
}
}
public static void enterString(String myString){
System.out.println("Trying to paste string \"" + myString + "\"");
StringSelection stringSelection = new StringSelection(myString);
//save clipboard content
Transferable clipboardContent = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null);
//enter new clipboard content
Toolkit.getDefaultToolkit().getSystemClipboard().setContents((Transferable) stringSelection, null);
//paste clipboard content with Robot class
robot.keyPress(VK_CONTROL);
robot.keyPress(VK_V);
robot.keyRelease(VK_CONTROL);
robot.keyRelease(VK_V);
//restore clipboard content
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(clipboardContent, null);
}
}

This will never work reliably. You would have to handle all formats, no matter what the size. Read up on Delayed Rendering (where the data doesn't actually exist on the clipboard at all until a request is made to paste it), and you will start to understand the problem. Some apps, like Excel, can provide the data in 25+ formats, some of them very large and complex. There isn't time or RAM to render them all.
So you can't restore the clipboard the way it was.
And you can't update the clipboard at all, without triggering other clipboard-aware apps from doing "their thing".
And lastly, you should not be using the clipboard this way. The clipboard is a shared resource, provided for the convenience of the USER, not the programmer.
Find another way.

For String type content (ONLY!!!), I came up with this snippet:
import static java.awt.Toolkit.getDefaultToolkit;
public class Main {
public static void main(String[] args) throws IOException, UnsupportedFlavorException {
Clipboard systemClipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
// Save the old data
String oldData = (String) systemClipboard.getContents(null).getTransferData(DataFlavor.stringFlavor);
// Now lets put some new data to clipboard!
StringSelection stringSelection = new StringSelection("Jai Hind!! Vandee Maatharam!!!!");
systemClipboard.setContents(stringSelection, null);
// Lets print the clipboard content
String newData = (String)
systemClipboard.getContents(null).getTransferData(DataFlavor.stringFlavor);
System.out.println("Here is the new data: [" + newData + "]");
// Now setting back the old clipboard content
StringSelection oldDataSelection = new StringSelection(oldData);
systemClipboard.setContents(oldDataSelection, null);
//Now hit CTRL+V in an editor and you should get back the old clipboard content (NOTE: Only String Contents!!!)
}

Related

No X11 DISPLAY variable was set. How to get data from clipboard in linux with java?

I try to get data from the clipboard and try to use follow code:
public static String getValueFromClipboard() {
Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard(); // {1}
try {
return (String) c.getData(DataFlavor.stringFlavor);
} catch (Exception e){
throw new RuntimeException("An error was occurs while clipboard parsing. " + e.getMessage());
}
}
This code works well when I launch the project on Windows, but when the project executes on the server (CentOS/Fedora) I get the following error:
No X11 DISPLAY variable was set, but this program performed an operation which requires it.
This error occurs on the line {1}:
Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
How to correctly get the data from the clipboard with Linux?

Selenium Java - Copy Image from URL to clipboard and Paste it as image

I want to copy image/gif from URL without download it,
for example, I want to copy this gif to clipboard https://media.giphy.com/media/l49JL8rJ2vOEXlmM0/giphy.gif
and paste this gif to this site
https://paste.pics/
I tried everything but it's not working.
Code trials :
Copy to clipboard :
StringSelection data = new StringSelection ("https://media.giphy.com/media/xThtap5F0MFyAkoBPi/giphy.gif");
Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
cb.setContents(data, data);
Paste 1
try {
Transferable t = cb.getContents(null);
if (t.isDataFlavorSupported(DataFlavor.stringFlavor))
System.out.println(t.getTransferData(DataFlavor
.stringFlavor));
driver.findElement(By.xpath("elementFromSite")).sendKeys(t.getTransferData(DataFlavor
.imageFlavor).toString());
} catch (UnsupportedFlavorException | IOException ex) {
System.out.println("issue");
}
Paste 2
driver.findElement(By.id(elementFromSite)).sendKeys(Keys.chord(Keys.CONTROL,"v"));
so I don't have any idea how can I achieve it
Please assist
Here's what I would try:
driver.get("https://media.giphy.com/media/l49JL8rJ2vOEXlmM0/giphy.gif");
driver.find_by_css_selector('a._3X9Zhs_atixoQRBDsNGQnl > img').sendKeys(Keys.CONTROL+ "c");
driver.get("https://paste.pics/");
Actions action = new Actions(driver);
action.keyDown(Keys.CONTROL).sendKeys("v").keyUp(Keys.CONTROL).perform();
If that doesn't work you could try doing ctrl+v on an element on the page, like
driver.find_element_by_css_selector('whatever selector you want to target some element on the page').sendKeys(Keys.CONTROL+ "v");
Does that help at all?

Copy words to clipboard from double click

I am trying to copy words from anywhere (like MS word, pdf, not from any java component) to clip board when I double click on it. Therefore, I use awt.Robot to copy that selected word to clip board after double click on it. After copy, the word will return. Therefore, I use two method copy_From_Original and copy_From_ClipBoard.
The problem is when I copy word, it will show the previous word that clipboard content not the current copied one.
If there are, another ways to do this process feel free to say it.
Thanks. Sorry for my bad English.
public class copyWord {
public static String copy_From_Original() {
try {
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_C);
robot.keyRelease(KeyEvent.VK_C);
robot.keyRelease(KeyEvent.VK_CONTROL);
} catch (AWTException ex) {
Logger.getLogger(copyWord.class.getName()).log(Level.SEVERE, null, ex);
}
String word = copy_From_ClipBoard();
return word;
}
private static String copy_From_ClipBoard() {
Toolkit toolkit = Toolkit.getDefaultToolkit();
Clipboard clipboard = toolkit.getSystemClipboard();
try {
String result = (String) clipboard.getData(DataFlavor.stringFlavor);
return result;
} catch (Exception e) {
System.out.println("ERROR");
return null;
}
} }
Do not use Robot for this. You haven’t said what type of component contains the double-clicked text, but if it’s a JTextField or JTextArea or any other subclass of JTextComponent, you can simply call copy().
If it’s an AWT TextField or TextArea, you can use place the selection on the clipboard yourself:
String text = textField.getSelectedText();
Clipboard clipboard = textField.getToolkit().getSystemClipboard();
clipboard.setContents(new StringSelection(text), null);

How to convert an image from 8-Bit to RGB in ImageJ2 using Java

I'm trying to use ImageJ2 directly from Java to create a binarised image coming from an input image.
A somewhat working version of my code looks like this:
final File file = new File("input.png");
try {
DefaultDataTypeService dataTypeService = new DefaultDataTypeService();
Dataset dataset = imageJ.dataset().open(file.getAbsolutePath());
Img inputImg = dataset.getImgPlus();
PluginInfo pluginInfo = imageJ.plugin().getPlugin(Binarize.class);
Binarize binarizeOp = (Binarize) pluginInfo.createInstance();
binarizeOp.setContext(imageJ.getContext());
binarizeOp.setChangeInput(true);
binarizeOp.setFillMaskBackground(true);
binarizeOp.setFillMaskForeground(true);
binarizeOp.setInputData(dataset);
binarizeOp.setInputMask(null);
binarizeOp.setMaskColor(Binarize.WHITE);
binarizeOp.setMaskPixels(Binarize.INSIDE);
binarizeOp.setThresholdEachPlane(false);
binarizeOp.setDefaultThresholdMethod();
binarizeOp.run();
dataset.rgbChange();
DefaultDatasetService defaultDatasetService = new DefaultDatasetService();
Img outputImg = dataset.getImgPlus();
outputImg = outputImg.factory().imgFactory(new UnsignedByteType()).create(outputImg,new UnsignedByteType());
Dataset outputDataset = defaultDatasetService.create(outputImg);
imageJ.dataset().save(outputDataset,"input_binary.png");
} catch (IOException e) {
e.printStackTrace();
} catch (InstantiableException e) {
e.printStackTrace();
} catch (IncompatibleTypeException e) {
e.printStackTrace();
}
Running this code I have the problem that "input_binary.png" will be completely black, a behaviour I can reproduce using the ImageJ client application.
What I need to do in the client is to change the image type from "8-bit Color" to "RGB-Color". But I can not figure out how to reproduce that in Java using the current version of the net.imagej library.
I know that it would be possible using the 1.x library but I would like to to it using the 2.x.
Any help would be greatly appreciated.
You're getting black images because of this:
outputImg = outputImg.factory().imgFactory(new UnsignedByteType()).create(outputImg,new UnsignedByteType());
Which is just copying the dimensionality of your source image, not its values.
A few other key points:
It's best practice to have your Contextual objects (e.g. Services) derived from the Context instead of manually constructed.
The Binarize command has a Dataset output so it's not necessary to go Dataset > ImgPlus > Dataset
If you do want to write the dataset out you need to convert from the BitType output by Binarize to one that's supported.
See below for an example of running Binarize, getting the output, converting it and writing it out. Hope that helps!
public static void main(String... args) {
final File file = new File("inpath.png");
final File out = new File("outpath.png");
// This is just sugar for the point of illustration.
// The purpose here is just to have access to a Context
ImageJ imagej = new ImageJ();
// Cache the context for future use.
Context context = imagej.getContext();
try {
// Use the context to get the services we want to ensure they are all
// properly initialized.
// If this was a Command these could all be #Parameters to be populated
// automatically.
DatasetService datasetService = context.getService(DatasetService.class);
CommandService commandService = context.getService(CommandService.class);
DatasetIOService datasetIOService =
context.getService(DatasetIOService.class);
Dataset input = datasetIOService.open(file.getAbsolutePath());
// Start the command
Future<CommandModule> future =
commandService.run(Binarize.class, true, "inputData", input);
// Get the command output
Dataset binarized = (Dataset) future.get().getOutput("outputMask");
// The output type is a binary image which, at the moment, needs to be
// explicitly converted to something that can be written out.
// Adapted from:
// http://fiji.sc/ImgLib2_Examples#Example_2c_-_Generic_copying_of_image_data
Img inputImg = input.getImgPlus().getImg();
Img outputImg = binarized.getImgPlus().getImg();
Img typedImg =
inputImg.factory().create(inputImg, inputImg.firstElement());
scale(outputImg, typedImg);
Dataset output = datasetService.create(typedImg);
// Save the output dataset
datasetIOService.save(output, out.getAbsolutePath());
}
catch (IOException exc) {
exc.printStackTrace();
}
catch (InterruptedException exc) {
exc.printStackTrace();
}
catch (ExecutionException exc) {
exc.printStackTrace();
}
finally {
// Dispose of the context to shut down
context.dispose();
}
}
public static <T extends IntegerType<T>> void scale(
final RandomAccessible<BitType> source, final IterableInterval<T> target)
{
// create a cursor that automatically localizes itself on every move
Cursor<T> targetCursor = target.localizingCursor();
RandomAccess<BitType> sourceRandomAccess = source.randomAccess();
// iterate over the input cursor
while (targetCursor.hasNext()) {\
// move input cursor forward
targetCursor.fwd();
// set the output cursor to the position of the input cursor
sourceRandomAccess.setPosition(targetCursor);
// set the value of this pixel of the output image
BitType b = sourceRandomAccess.get();
if (b.get()) {
targetCursor.get().setOne();
}
else {
targetCursor.get().setZero();
}
}
}

Copy from swing and paste in other Windows application

I'ved searched some time but no satisfying result showed thus would like to ask here.
Basicallly I have a JAVA Swing GUI table, it has some rows, let's say 3 columns each row, you see "1 david good" on a row. the content of this row is converted from a raw message, i.e. a xml message.
What I want to do is, when I selected a row and press ctrl+c, the a raw msg could be copied to clipboard then I could paste it in other Windows application like notepad or Word.
I tried toolkit to get system clipboard and put raw message in(via keylistener). But when I press ctrl+v in notepad, I still get "1 david good" as default.
I printed the raw message from clipboard in Swing code, thus I am guessing if my code only works in Swing, customized content could not be retrieved in Windows?
Could somebody tell me if it's possible to do in Swing? thanks a lot.
You can use this example:
String str = "Which String to copy to clipboard";
StringSelection stringSelection = new StringSelection (str);
Clipboard clpbrd = Toolkit.getDefaultToolkit().getSystemClipboard ();
clpbrd.setContents (stringSelection, null);
So this code can be when clicking on some button while calling it from actionPerformed()
And for pasting issue:
public String getClipboardContents() {
String result = "";
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
//odd: the Object param of getContents is not currently used
Transferable contents = clipboard.getContents(null);
boolean hasTransferableText =
(contents != null) &&
contents.isDataFlavorSupported(DataFlavor.stringFlavor)
;
if (hasTransferableText) {
try {
result = (String)contents.getTransferData(DataFlavor.stringFlavor);
}
catch (UnsupportedFlavorException | IOException ex){
System.out.println(ex);
ex.printStackTrace();
}
}
return result;
}

Categories

Resources