Skip to content

Instantly share code, notes, and snippets.

@TurekBot
Last active April 14, 2019 19:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TurekBot/f639f327747e7f76639a806333756d30 to your computer and use it in GitHub Desktop.
Save TurekBot/f639f327747e7f76639a806333756d30 to your computer and use it in GitHub Desktop.
A program to test out the differences between the AWT Java Clipboard and the JavaFX Clipboard.
package sample;
import com.sun.glass.ui.ClipboardAssistance;
import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ColorPicker;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.Clipboard;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.CornerRadii;
import javafx.stage.Stage;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
/**
* A program to test out the differences between the AWT Java Clipboard and the JavaFX Clipboard.
* <p>
* Based on the code by crusam: https://stackoverflow.com/q/48932575/5432315
*/
public class ClipBoardFxAwtComparison extends Application {
@Override
public void start(final Stage primaryStage) {
final BorderPane root = new BorderPane();
final ImageView view = new ImageView();
final Button awtButton = new Button("AWT");
awtButton.setOnAction(event -> loadImageFromAwtClipboard(view));
final Button javaFXButton = new Button("JavaFX");
javaFXButton.setOnAction(event -> loadImageFromJavaFXClipboard(view));
root.setCenter(view);
final BorderPane buttonPane = new BorderPane();
buttonPane.setLeft(awtButton);
buttonPane.setCenter(new Label("Copy and image then click a button to paste it."));
buttonPane.setRight(javaFXButton);
root.setBottom(buttonPane);
final ColorPicker colorPicker = new ColorPicker();
colorPicker.setOnAction(event -> {
root.setBackground(
new Background(
new BackgroundFill(
colorPicker.getValue(),
CornerRadii.EMPTY,
Insets.EMPTY)
)
);
});
BorderPane.setAlignment(colorPicker, Pos.CENTER);
root.setTop(colorPicker);
final Scene scene = new Scene(root, 400, 400);
primaryStage.setScene(scene);
primaryStage.show();
listenToClipboard();
}
/**
* This little bit of magic comes courtesy of Александр Савостьянов: https://stackoverflow.com/a/47550034/5432315
*/
private void listenToClipboard() {
Clipboard clipboard = Clipboard.getSystemClipboard();
new ClipboardAssistance(com.sun.glass.ui.Clipboard.SYSTEM) {
@Override
public void contentChanged() {
System.out.println("System clipboard content changed.");
System.out.println("Clipboard content types: ");
clipboard.getContentTypes().forEach(System.out::println);
System.out.println();
}
};
}
private void loadImageFromJavaFXClipboard(final ImageView view) {
System.out.println("Adding an image from the JavaFX Clipboard...");
final Clipboard clipboard = Clipboard.getSystemClipboard();
if (clipboard.hasImage()) {
final Image image = clipboard.getImage();
view.setImage(image);
} else {
new Alert(Alert.AlertType.INFORMATION, "No image detected on the Clipboard!").show();
}
}
private void loadImageFromAwtClipboard(final ImageView view) {
System.out.println("Adding an image from the AWT Clipboard...");
try {
final Transferable t = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null);
if (t != null && t.isDataFlavorSupported(DataFlavor.imageFlavor)) {
final java.awt.image.BufferedImage img = (java.awt.image.BufferedImage) t.getTransferData(DataFlavor.imageFlavor);
final Image image = SwingFXUtils.toFXImage(img, null);
view.setImage(image);
} else {
new Alert(Alert.AlertType.INFORMATION, "No image detected on the Clipboard!").show();
}
} catch (final UnsupportedFlavorException | IOException e) {
e.printStackTrace();
}
}
public static void main(final String[] args) {
launch(args);
}
}
@JKostikiadis
Copy link

JKostikiadis commented Apr 14, 2019

Spending some time on your example I can only assume that some specific applications "extract" the image into the clipboard with different image type and the JavaFX can not handle them correctly if loaded from clipboard directly. In order to check that i tried convert the 'broken' image into a bufferedImage and then convert it back to JavaFX Image. I tried many BufferedImage types and the only one who actually work was TYPE_BYTE_INDEXED here is a code i used :

private void loadImageFromJavaFXClipboard(final ImageView view) {
		System.out.println("Adding an image from the JavaFX Clipboard...");
		final Clipboard clipboard = Clipboard.getSystemClipboard();

		if (clipboard.hasImage()) {
			final Image image = clipboard.getImage();

			// convert clipboard image to BufferedImage
			BufferedImage bufferedImage = SwingFXUtils.fromFXImage(image, null);

			// Create a new image with TYPE_BYTE_INDEXED which seems to correct the problem
			BufferedImage imageRGB = new BufferedImage(bufferedImage.getWidth(), bufferedImage.getHeight(),
					BufferedImage.TYPE_BYTE_INDEXED);

			// Create the graphics
			Graphics2D graphics = imageRGB.createGraphics();
			// Draw the new Image
			graphics.drawImage(bufferedImage, 0, 0, null);

			// Convert it back to JavaFX Image
			Image resultImage = SwingFXUtils.toFXImage(imageRGB, null);
			// Lastly display it
			view.setImage(resultImage);

		} else {
			new Alert(Alert.AlertType.INFORMATION, "No image detected on the Clipboard!").show();
		}
	}

Now if you use the code above and try to take some images either from PDF or your application you mentioned in the StackOverflow post you will see its working. So my first hypothesis might be correct. I am guessing the problem lies in javaFX Clipboard implementation, I might give it a better look in future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment