Issue loading style sheet in JavaFX - java

I am developing an application on Linux using OpenJDK 8u20 and OpenJFX 8u5. I am basically trying to set a default style sheet for all scenes. There apparently isn't a a sanctioned way to do that, so the work around is to set the style sheet for each individual scene. The way to do this is "scene.getStylesheets().add(css)" where css is a String representing the location of the style sheet. That representation can be in three flavors: file, URL, or resource.
An example of the URL approach is:
String css = "http://localhost/file.css";
An example of the file approach is:
String css = "file://" + new File("file.css").getAbsolutePath().replace("\\", "/");
An example of the resource is:
String css = this.getClass().getResource("file.css").toString();
Of the three, only the URL approach appears to work as advertised.
The file approach appears to work initally, but subsequent compiles appears to break it. I can see that "scene.getStylesheets().add(css)" is being called with the correct value, but the application runs as if it never was. It only works after the compile that I edit the file that I am adding the stylesheet. If I edit any other file, compile, and run it does not work.
The resource approach just throws a runtime exception, namely "sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)".
I have a work around for now by using the URL approach, but long term I would really like to be able to package that CSS file in the jar and use it from the jar. Does anybody have any ideas or suggestions?

OK, apparently I didn't understand how the resource approach is supposed to work sufficiently. I compile the class files in a temporary directory, and I was not also copying the resource files to that directory. Once I did that getResource starting working. So now both the URL and resource approaches are working for me.
If anybody wants to comment on the odd behavior of the file approach, it would be nice to know what's up with that.

There is a way of setting a default CSS style sheet for all of your scenes and you can accomplish that by invoking the static setUserAgentStyleSheet() method on the JavaFx Application.

Related

executable jar from eclipse unable to use images within packages... sometimes

I have wrote a swing application and it works fine in eclipse but when I export it as a runnable jar parts of the application fail, when dealing with images, this line for example;
logo = getClass().getResource("/com/cogentautomation/logo.jpg").getPath();
eclipse is packaging the images in the com.cogentautomation package and I can see it in the .jar itself, I have tried both export methods, extract required libraries and package required libraries, one says;
FileNotFoundException com\cogentautomation\logo.jpg
the other says;
FileNotFoundException file:\c:\documents\hs.jar!\com\cogentautomation\logo.jpg
I am using a library to parse out a PDF file, which is where this error is occurring, however it works in eclipse and with other images that are on disk that aren't a java resource.
I've read other topics on the problem but nothing really seemed to help.
EDIT: addressing something in the comments, I require a String variable the library I am using requires a string input to read the image;
import org.pdfclown.documents.contents.entities.Image;
Image image = Image.get(logo);
Based on the JavaDocs for org.pdfclown.documents.contents.entities.Image I "guess" the Image.get(String) is forwarding the call to Image.get(File) using the String as the parameter for the constructor of File
This isn't going to work for URL based paths. Instead, you need to look towards Image.get(IInputStream) (why these APIs can't simply use what's already available :P)
So, digging through the API some more IInputStream leads to org.pdfclown.bytes.Buffer, not perfect, but it's a link.
You can use Class#getStreamAsResource and write this into a ByteArrayOutputStream which can then give you a byte[], which can then pass to Image.get(IInputStream)

Applet's getCodeBase returns null

I have an applet, and need to open a stream to a file. This file is a local file located where the applet and HTML file are:
URL localURL = new URL(getCodeBase(), "pixs/icons.zip");
InputStream localInputStream =localURL.openStream();
It used to work fine, but after upgrading to java 1.7 build 25, getCodeBase() always return null.
This is actually documented!, Alas - there is no recommendation how to overcome it.
One things that had worked is to use full path:
URL localURL = new URL("file:c:/myFolder/pixs/icons.zip");
Is there another option to resolve that without using full path?
Perhaps you can use getDocumentBase instead. Depends on the structure of your setup, whether there is a close relation between the code base and the documents. No permanent solution: getDocumentBase was modified in the same way in 7u40, according to bug #8019177.
If not, then you can try using getResource to obtain a URL from your JAR, e.g. the class file of the applet, and then disassemble that URL to get at the location of the JAR and hence the code base. This is untested, so feel free to edit this post if you tried this.
Last but not least, since that change only affects local applets, you could run a (local or public) web server to serve that applet.
If you want a more official statement on this, I'll quote the #8017250 bug report:
If applet need to load resource:
if the resource is in applet JAR(s), they should be able to load it with ClassLoader.getResoruceAsStream directly, without needing the codebase information.
if the resource is in arbitary location, not inside applet JAR, they should have other ways to get to that location, since it's not part of the applet resource anyway. (e.g. user.home java system property, provided that their applet has all-permissions)
http://www.duckware.com/tech/java-security-clusterfuck.html (thanks to this post) mentions some other alternatives. The least likely one to be affected by future Oracle modifications apprers to be the use of location.href in the containing HTML page, e.g. writing the <applet> tag from JavaScript.

Referencing a file in Eclipse without hard-coding the path?

I'm creating a dynamic web project in Eclipse where I frequently have write and read to and from an XML file. The file is in my project workspace in a folder called xml. I was wondering if Java provided some way to access the file without hard coding the file path. I've been looking around for a while for a solution but I haven't really founding anything that's really clear. Thanks!
You could just drop it in the classpath as suggested by others, but you won't be able to write to it.
Rather supply the absolute path as a VM argument or environment variable so that you don't need to hardcode it.
E.g.
-Dconfig.location=/path/to/config/file
with
File xmlFile = new File(System.getProperty("config.location"), "some.xml");
// ...
As a completely different alternative, you could consider a database.
You can get the proper path using the following from your Servlet:
String filename = getServletContext().getRealPath("/xml/config.xml");
NOTE:
getRealPath may return null if the file is inside a WAR file. In that case, if your file is in WEB_INF/classes, then you could use ServletContext.getResourceAsStream("/config.xml").
See this link:
I don't think the Servlet API gives you anything that would result in a reliable, writable, path to put work files in all containers. If your container runs the WebApp right out of the WAR, getRealPath() couldn't possibly point to something you can actually write to. I think that your only option here that is supported regardless of container is to hard code some path in the web.xml. Do it as a Context Parameter and you may be able to change it at deployment time. At the end of the day, you must declare a fully qualified path in either code or configuration to get the effect you seek.
Alternatively, do you really need to know the name of the file? In some Servlet apps I've managed to get the effect of dynamically writable storage through plain-jane java.io.file.createTempFile: http://docs.oracle.com/javase/1.4.2/docs/api/java/io/File.html#createTempFile(java.lang.String, java.lang.String)

Getting an EL in a Javascript file, loaded by #ResourceDependency

I'm using #ResourceDependency annotation in a JSF component to add Javascript and CSS files into my JSF page.
In my Javascript file, I need to reference another resource file (a .swf file, which located in META-INF/resources, as JSF requires). I tried to put a #{resource['swf:file.swf']} EL expression in my javascript code, but it won't get resolved.
For exapmle, for the following JS file in the server:
var instance = new JSClass();
instance.setResourceUrl("#{resource['swf:file.swf']}");
The browser gets:
var instance = new JSClass();
instance.setResourceUrl("#{resource['swf:file.swf']}");
which is wrong.
While when I put the same EL in the CSS file, it get resolved properly. For the following CSS file in the server:
.instance-css-class {
background: url("#{resource['swf:file.swf']}")
}
The browser gets:
.instance-css-class {
background: url("/webapp/javax.faces.resource/file.swf.jsf?ln=swf")
}
Which is exactly what I need, but in the JS file.
Obviously, I can use the CSS as a workaround for the issue (Create a DOM element, attach the CSS class to it, and then read and parse the required style property). But, is there a more elegant way to achive it? Is it a bug in the JSF library (I'm using Mojarra 2.0.3, with Jboss 6.1), or there is a reason for that behavior?
Please mind that the code above is part of a tag library, so workarounds such as those can't be used.
Edit - Seems that the CSS workaround is not feasible, since I can't see a way to get CSS attribute from a CSS file. So any (working) workaround would be gladly accepted as well.
BalusC has answered a similar question in detail here. Though the first solution is the easiest to implement, I would recommend you to go with the third, which in my opinion, is the correct way.

How to preview a file on the server in JBoss

I need some ideas on how I can best solve this problem.
I have a JBoss Seam application running on JBoss 4.3.3
What a small portion of this application does is generate an html and a pdf document based on an Open Office template.
The files that are generated I put inside /tmp/ on the filesystem.
I have tried with System.getProperties("tmp.dir") and some other options, and they always return $JBOSS_HOME/bin
I would like to choose the path $JBOSS_HOME/$DEPLOY/myEAR.ear/myWAR.war/WhateverLocationHere/
However, I don't know how I can programatically choose path without giving an absolute path, or setting $JBOSS_HOME and $DEPLOY.
Anybody know how I can do this?
The second question;
I want to easily preview these generated files. Either through JavaScript, or whatever is the easiest way. However, JavaScript cannot access the filesystem on the server, so I cannot open the file through JavaScript.
Any easy solutions out there?
Not sure how you are generating your PDFs, but if possible, skip the disk IO all together, stash the PDF content in a byte[] and flush it out to the user in a servlet setting the mime type to application/pdf* that responds to a URL which is specified by a link in your client or dynamically set in a <div> by javascript. You're probably taking the memory hit anyways, and in addition to skipping the IO, you don't have to worry about deleting the tmp files when you're done with the preview.
*****I think this is right. Need to look it up.
Not sure I have a complete grasp of what you are trying to achieve, but I'll give it a try anyway:
My assumption is that your final goal is to make some files (PDF, HTML) available to end users via a web application.
In that case, why not have Apache serve those file to the end users, so you only need your JBOSS application to know the path of a directory that is mapped to an Apache virtual host.
So basically, create a file and save it as /var/www/html/myappfiles/tempfile.pdf (the folder your application knows), and then provide http://mydomain.com/myappfiles (an Apache virtual host) to your users. The rest will be done by the web server.
You will have to set an environment variable or system property to let your application know where your folder resides (/var/www/html/myappfiles/ in this example).
Hopefully I was not way off :)
I agree with Peter (yo Pete!). Put the directory outside of your WAR and setup an environment variable pointing to this. Have a read of this post by Jacob Orshalick about how to configure environment variables in Seam :
As for previewing PDFs, have a look at how Google Docs handles previewing PDFs - it displays them as an image. To do this with Java check out the Sun PDF Renderer.
I'm not sure if this works in JBoss, given that you want a path inside a WAR archive, but you could try using ServletContext.getRealPath(String).
However, I personally would not want generated files to be inside my deployed application; instead I would configure an external data directory somewhere like $JBOSS_HOME/server/default/data/myapp
First, most platforms use java.io.tmpdir to set a temporary directory. Some servlet containers redefine this property to be something underneath their tree. Why do you care where the file gets written?
Second, I agree with Nicholas: After generating the PDF on the server side, you can generate a URL that, when clicked, sends the file to the browser. If you use MIME type application/pdf, the browser should do the right thing with it.

Categories