Desktop.getDesktop.open() in Java fails - java

I have this piece of code:
public void openSelectedFiles(MouseEvent mouseEvent){
ListView<String> listView = (ListView<String>) ((Node) mouseEvent.getSource())
.getScene().lookup("#listOfReferenceFiles");
String selectedFileString = listView.getSelectionModel().getSelectedItem();
System.out.println(Desktop.isDesktopSupported());
File fileToOpen = new File(selectedFileString);
System.out.println(fileToOpen.exists());
try {
Desktop.getDesktop().open(fileToOpen);
} catch (IOException e) {
e.printStackTrace();
}
}
I am using Java 8, and it seems to be working, until this line:
Desktop.getDesktop().open(fileToOpen);
It does not throw an exception, it just freezes my application. Is this a bug?

You must check first if desktop is allowed and if file exists to avoid this kind of problems:
//first check if Desktop is supported by Platform or not
if(!Desktop.isDesktopSupported()){
System.out.println("Desktop is not supported");
return;
}
Desktop desktop = Desktop.getDesktop();
// after check if file exists and open it
if(file.exists()) desktop.open(file);

Related

Desktop.getDesktop().open(file) on Ubuntu not working

I have a Java application, and when I use java.awt.Desktop:
Desktop.getDesktop().open(file);
It works fine on Windows (opens a file in my default program), but on Ubuntu (with openJdk 13), the Java application gets stuck and I do not even get any log error or anything. I have to force quit the app in order to recover.
The file path it correct, otherwise I would actually get an Exception. Also, isDesktopSupported a isSupported(Action.OPEN) returns true.
What can I do? Can I check some system settings or logs? Or perhaps get some logs from java.awt.Desktop? Or does this not work on Ubuntu/Linux?
Are there any alternatives?
From here:
In order to use the API, you have to call java.awt.EventQueue.invokeLater() and call methods of the Desktop class from a runnable passed to the invokeLater():
void fxEventHandler() {
EQ.invokeLater(() -> {
Desktop.open(...);
});
}
I am just going to add an example function
private static void OpenFile(String filePath){
try
{
//constructor of file class having file as argument
File file = new File(filePath);
if(!Desktop.isDesktopSupported())//check if Desktop is supported by Platform or not
{
System.out.println("not supported");
return;
}
Desktop desktop = Desktop.getDesktop();
if(file.exists()) { //checks file exists or not
EventQueue.invokeLater(() -> {
try {
desktop.open(file);
} catch (IOException e) {
throw new RuntimeException(e);
}
});
}
}
catch(Exception e)
{
e.printStackTrace();
}
}

Jar file with openCV and javafx

I made a rubiks cube application which includes a cube detection system, As im getting closer to wrapping up the project I wanted to make a JAR file. I get errors when running the JAR file and it really sucks because I can only run the project in IntelliJ(IDE).
I face two problems:
1) I cant get the JAR to link openCV properly
2)I have a problem loading an FXML file(this will occur assuming it did not crash while trying to load openCV.
For case 1 here is the code and errors:
static {
// try {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
// } catch (UnsatisfiedLinkError e) {
// System.err.println("Could not find OpenCV Library!");
// }
}
and the error message:
Exception in thread "JavaFX Application Thread" Exception in thread "main" java.lang.UnsatisfiedLinkError: no opencv_java342 in java.library.path:
Now If i remove the try catch comments i get this error:
static {
try {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
} catch (UnsatisfiedLinkError e) {
System.err.println("Could not find OpenCV Library!");
}
}
#Override
public void start(Stage primaryStage) throws Exception {
//Loader
FXMLLoader loader = new FXMLLoader(main.class.getResource("FXML_layouts\\MainScreen.fxml"));
Scene scene = new Scene(loader.load());
((mainController)loader.getController()).setStage(primaryStage);
primaryStage.setScene(scene);
primaryStage.show();
}
Error:
Could not find OpenCV Library!
Exception in Application start method
java.lang.reflect.InvocationTargetException
....
Caused by: java.lang.IllegalStateException: Location is not set.
Here is my file structure:
and here is my artifact config:
Just go with the steps below:
Put the opencv_java342.dll in a folder let call it dll_libs in a
drive e.g C:\dll_libs
Then go to Environment Variable -> Edit path -> put C:\dll_libs ->
Apply -> OK
Restart your IDE
OR: Just put the opencv_java342.dll file in the C:\Windows\System32 folder
And it is : )
Update (for your second question): If you want to give the executable package to someone else to run the program, there are almost 2 ways:
Let them to create the environment manually, just as the answer to
your question.
Do the job programmatically, just within your code write a function
which set the .dd environment variable on the program startup, and
then load the lib.
If you choose the second one, here I will give an example code to refere to:
public static void loadOpenCVLib() throws Exception {
File file = new File(OpenCVUtil.class.getProtectionDomain().getCodeSource().getLocation().getPath());
File opencv_libs = new File("oc_lib"); // this path is where is the lib going to copy to
String model = System.getProperty("sun.arch.data.model");
String localLibPath; // this is the path inside your program resource
if (model.equals("64")) {
localLibPath = "oc_lib/64bit";
} else {
localLibPath = "oc_lib/x86";
}
if (file.isFile()) { // when run from jar
JarFile jar = new JarFile(file);
if (!opencv_libs.exists() || !opencv_libs.isDirectory()) {
try {
JarUtils.copyResourcesToDirectory(jar, localLibPath, opencv_libs.getAbsolutePath());
} catch (Exception e) {
throw new IOException("Failed to create load opencv libs!!");
}
} else {
String[] list = opencv_libs.list();
if (list != null && list.length != 2) {
try {
JarUtils.copyResourcesToDirectory(jar, localLibPath, opencv_libs.getAbsolutePath());
} catch (Exception e) {
throw new IOException("Failed to create load opencv libs!!");
}
}
}
} else { // when run from IDE
File libPath = new File(OpenCVUtil.class.getResource("/"+localLibPath).getFile());
if (!opencv_libs.exists() || !opencv_libs.isDirectory()) {
boolean isDone = opencv_libs.mkdir();
if (!isDone && !opencv_libs.exists()) {
throw new IOException("Failed to create load opencv libs!!");
}
try {
FileUtils.copyDirectory(libPath, opencv_libs);
} catch (IOException e) {
throw new IOException("Failed to create load opencv libs!!");
}
} else {
String[] list1 = opencv_libs.list();
String[] list2 = libPath.list();
boolean contentEquals = list1 != null && list2 != null && list1.length == list2.length;
if (contentEquals) {
try {
FileUtils.copyDirectory(libPath, opencv_libs);
} catch (IOException e) {
throw new IOException("Failed to create load opencv libs!!");
}
}
}
}
System.setProperty("java.library.path", opencv_libs.getAbsolutePath());
Field sys_paths = ClassLoader.class.getDeclaredField("sys_paths");
sys_paths.setAccessible(true);
sys_paths.set(null, null);
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
// it is for the ffmpeg name
String[] list = opencv_libs.list();
assert list != null;
String ffmpeg_dll_file_name = null;
for (String s : list) {
if (s.contains("ffmpeg")) {
ffmpeg_dll_file_name = s.substring(0, s.indexOf("."));
}
}
System.loadLibrary(ffmpeg_dll_file_name);
}
Hope it can help!!

how to close an application in java by releasing memory

I am using a java application which opens a scratch file during run time. The scratch file communicates with the arduino board and gives the output. once the communication starts i am unable to use my User interface in java which has a close button instead i tried closing my entire application using end task in task manager. Can you please tell me as how to release the memory associated with the files. I used process. destroy and system.exit(0) but did not work.
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
if("Disconnect".equals(jButton1.getText()))
{
System.exit(0);
}
jButton1.setText("Disconnect");
if(jComboBox2.getSelectedItem()==null)
{
System.out.println("Select one port");
}
else
{ Runtime r = Runtime.getRuntime();
try {
this.hide();
//p = r.exec("C:\\Program Files\\Scratch 2\\Scratch 2.exe C:\\Users\\Admin\\Desktop\\fwdbckpwm12.sb2");
p = Runtime.getRuntime().exec("C:\\Program Files\\Scratch 2\\Scratch 2.exe C:\\Users\\Admin\\Desktop\\scratch files new.sb2");
//p.destroy();
//r.exec("C:\\Windows\\notepad.exe C:\\Windows\\ss.txt");
A4S a4sObj = new A4S(new String[]{jComboBox2.getSelectedItem().toString()}); //defaultline
// A4S a4sObj = new A4S(new String[]{"COM16"}); //addedline
r.gc();
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
} catch (IOException ex) {
Logger.getLogger(serialportselection.class.getName()).log(Level.SEVERE, null, ex);
}
finally{
p.destroy();
System.gc();
}
}
}

Opening print dialog using java.awt.Desktop

I am trying to print an HTML file using java.awt.Desktop.print but the print dialog throws an IOException.
menuPrint.setOnAction((ActionEvent t) -> {
if (Desktop.isDesktopSupported()) {
Desktop desktop = Desktop.getDesktop();
if (desktop.isSupported(Desktop.Action.PRINT)) {
try {
File output = new File(System.getProperty("java.io.tmpdir")+"/Preview.html");
desktop.print(output);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
});
java.io.IOException: Failed to print C:\Users\XXX\AppData\Local\Temp\Preview.html.
Error message: A device attached to the system is not functioning.
I have a PDF printer installed and can open the print dialog using Ctrl+P. Though this same code is working on a separate machine which is connected to an actual printer.
Any clues appreciated. How to make it work?

Not possible to launch a file on a network using Java Desktop?

(I have a problem that I illustrated in this question but had no correct answers. I refined my problem and tried to edit the initial question to reflect that but I guess because of the way SO displays unanswered questions it lost momentum and there is no way to revive it. So I am posting my correct question again).
I have a file that resides on a shared network location :
"\\KUROSAVVAS-PC\Users\kuroSAVVAS\Desktop\New Folder\Warsaw Panorama.JPG"
(The spaces are there intentionally)
The following code :
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
public class Test {
public static void main(String[] args) {
try {
String s = "\\\\KUROSAVVAS-PC\\Users\\kuroSAVVAS\\Desktop\\New Folder\\Warsaw Panorama.jpg";
File f = new File(s);
System.out.println(f.exists());
Desktop.getDesktop().open(f);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Prints to the console that the file exists (System.out.println(f.exists());) but throws this exception! :
java.io.IOException: Failed to open file:////KUROSAVVAS-PC/Users/kuroSAVVAS/Desktop/New%20%20%20%20%20Folder/Warsaw%20%20%20%20Panorama.jpg. Error message: The system cannot find the file specified.
at sun.awt.windows.WDesktopPeer.ShellExecute(WDesktopPeer.java:59)
at sun.awt.windows.WDesktopPeer.open(WDesktopPeer.java:36)
at java.awt.Desktop.open(Desktop.java:254)
at Test.main(Test.java:13)
Has anyone any idea why something like this may happen? I have tried everything from creating URIs to decoding them afterwards... Nothing works.
With java 7 you can do this
public static void main(String[] args) throws IOException {
String s = "\\\\KUROSAVVAS-PC\\Users\\kuroSAVVAS\\Desktop\\New Folder\\Warsaw Panorama.jpg";
Path p = Paths.get(s);
Desktop.getDesktop().browse(p.toUri());
}
Java 6 solution:
public static void launchFile(File file) {
if (!Desktop.isDesktopSupported())
return;
Desktop dt = Desktop.getDesktop();
try {
dt.open(file);
} catch (IOException ex) {
// this is sometimes necessary with files on other servers ie
// \\xxx\xxx.xls
launchFile(file.getPath());
}
}
// this can launch both local and remote files
public static void launchFile(String filePath) {
if (filePath == null || filePath.trim().length() == 0)
return;
if (!Desktop.isDesktopSupported())
return;
Desktop dt = Desktop.getDesktop();
try {
dt.browse(getFileURI(filePath));
} catch (Exception ex) {
ex.printStackTrace();
}
}
// generate uri according to the filePath
private static URI getFileURI(String filePath) {
URI uri = null;
filePath = filePath.trim();
if (filePath.indexOf("http") == 0 || filePath.indexOf("\\") == 0) {
if (filePath.indexOf("\\") == 0){
filePath = "file:" + filePath;
filePath = filePath.replaceAll("#", "%23");
}
try {
filePath = filePath.replaceAll(" ", "%20");
URL url = new URL(filePath);
uri = url.toURI();
} catch (MalformedURLException ex) {
ex.printStackTrace();
} catch (URISyntaxException ex) {
ex.printStackTrace();
}
} else {
File file = new File(filePath);
uri = file.toURI();
}
return uri;
}
This answer was on the bug report, but I've edited it to fix when there is a hash.
TL;DR of ZAMMBI's answer (+1 BTW). (Using Java 6)
This works, as expected
Desktop.getDesktop().open(new File("\\\\host\\path_without\\spaces.txt")); //works
This fails, due to a known Java bug:
Desktop.getDesktop().open(new File("\\\\host\\path with\\spaces.txt")); //fails <shakes fist>
This work-around works
Desktop.getDesktop().browse(new URI("file://host/path%20with/spaces.txt")) //works (note slash direction and escape sequences)
This work-around seems like it should work, but does not:
Desktop.getDesktop().browse((new File("\\\\host\\path with\\spaces.txt")).toURI());
This work-around works, and seems to be the most general form:
File curFile = new File("\\\\host\\path with\\or_without\\spaces\\local or network.txt");
Desktop.getDesktop().browse(new URI(curFile .toURI().toString().replace("file:////","file://")));
It seems that there is a bug when you try to access a resource on a network drive with spaces in the path. See this entry in Sun's bug database.
Since the bug is already a year old, I don't think you'll get a fix anytime soon. Try the latest VM. If that doesn't help, try to get the source for WDesktopPeer. Instead of encoding the path, try to keep it as it was (with backslashes and all) and put quotes around it. That might work.
[EDIT] Specifically, don't replace \ with /, do not prepend file:// and leave the spaces as they are (instead of replacing them with %20)

Categories

Resources