Flying Saucer is an XHTML renderer written in Java. It's 100% Java, not a native wrapper, and it only handles valid XHTML + CSS. It is intended for embedding web-based user interfaces into Java applications (ex. web photo album generator, help viewer, iTunes Music Store clone). It cannot be used as a general purpose webbrowser since it does not support the malformed legacy HTML found on the web, though recent work on compatibility libraries may be enough to do what you need. See JTidy integration
Flying Saucer is not an HTML component. It is a rendering component for XHTML content, but it cannot handle the malformed HTML 4.0 of general webpages, and it has no support for purely stylistic markup like FONT and CENTER. You have to use valid XHTML and CSS. For most embedded uses this is fine since the application author usually has control over the documents to be loaded. If you really need full IE/Mozilla/Safari like fidelity for general purpose webpages you should look into a webbrowser wrapper like JDIC's Browser component.
The core renderer just handles XHTML and CSS. It doesn't know anything about form submission, managing cookies, or tracking the browsing history. It just renders XHTML/CSS to the screen. However, Flying Saucer does include a Browser application which provides these features and more. You can use this as a good starting point for your own applications.
Flying Saucer can be used for any Java application that requires some sort of styled text. This can be as simple as a chat program or as complicated as a complete ebook reader with dynamic stylesheets. Flying Saucer is very forward thinking and is designed to be a part of the next generation of applications that combine rich desktop clients with web content. Some examples of application types are:
With our third release it supports most of the common XHTML and CSS features. This includes:
The only major feature missing as of R5 is the automatic table model (the old Netscape style of tables where the size of the content determined the size of the cells.) Fixed layout tables are supported. Other than that it's just a matter of squashing more bugs and getting more speed.
There is also no support for things outside the scope of XHTML/CSS such as Javascript, printing, Flash, SVG, or legacy HTML (though there is interest in all of those).
You need a mouse listener that detects link clicks and does the HTTP request. The XHTMLPanel includes a built in mouse listener to do this, but you can override it if you wish.
You can use the form accessor methods on the context. See
Form Field Access in the
Getting Started Guide.
You only need the core-renderer.jar
and the ss_css2.jar
. That is all you need for your own programs. You also need an XML parser to be in your classpath, but this already included in recent versions of the JRE. To run the browser or use any of it's support classes you will need the browser.jar
file.
Our Ant build.xml
file includes all JAR files in the /lib
directory, plus the /resources
directory tree in the classpath. The
compile target also copies CSS and properties resources from /src/css
and
src/conf
to /build/resources
. If running from an IDE, you
will need to synchronize this yourself.
The renderer works with a simple, java.util.Properties
-based
configuration system--no XML! Our org.xhtmlrenderer.util.Confuration
class
loads properties on first access and makes them available at runtime.
When you are using the renderer, Configuration
needs to know where
to find the properties file. If you are running from the renderer JAR file, our
default properties will be read from there. If you have unpacked, or re-packed,
the JAR, the location of the file is currently hard-coded as
/resources/conf/xhtmlrenderer.conf
. This path must be on the CLASSPATH
as it is loaded as a system resource using a ClassLoader. You need to add the parent
directory for /resources
to your classpath, or include
/resources
in your JAR with no parent directory.
You can change the default properties for the application right in the .conf
file. However, this is not a good idea, as you will have to merge your changes back on
new releases. Plus, it will make reporting bugs more complicated. Instead, you can use
one of two override mechanisms for changing the value of individual properties.
Override with Second Conf File: Your override file should just re-assign
values for properties originally given in
$user.home/.flyingsaucer/local.xhtmlrenderer.confThe
user.home
variable is a system property. If you call the
System.getProperty("user.home")
from within any Java program on your
machine, you will find out where this is. The location is usually
c:\Documents And Settings\{username}
and under the /usr
directory on UNIX systems. Try that method call to see where it is on your machine.
Override with System Properties: You can also override properties one-by-one on the command line, using System properties. To override a property using the System properties, just re-define the property on the command line. e.g.
java -Dxr.property-name=new_value org.xhtmlrenderer.HTMLPanel
You can override as many properties as you like. Note that overrides are driven by the property names in the default configuration file. Specifying a property name not in that file will have no effect--the property will not be loaded or available for lookup. Logging output is also controlled in this Configuration file.
If you think an override is not taking, you can change the logging behavior
of the Configuration class. Because of inter-dependencies between Configuration
and the logging system, this is a special-case key, using the System property
show-config
. The allowed values are from the
java.util.logging.Level
class. Use ALL to show a lot of detail about
Configuration startup, OFF for none, and INFO for regular output, like this
java -Dshow-config=ALL org.xhtmlrenderer.HTMLPanelThis will output messages to the console as Configuration is loading and looking for overrides to the default property values for the renderer.
We have just started using the Configuration system late in preparing release R4. Some runtime behavior that should be configurable (like XHTML parser) is not. If you would like to see some behavior made configurable, shoot us an email.
To access a parameter from Configuration at runtime, just use on of the many static methods on the Configuration class. All of these just take the full name of the property:
String Configuration.valueFor(String)
String Configuration.valueFor(String key, String default)
byte Configuration.valueAsByte(String key, byte default)
double Configuration.valueAsDouble(String key, double default)
float Configuration.valueAsFloat(String key, float default)
int Configuration.valueAsInt(String key, int default)
long Configuration.valueAsLong(String key, long default)
short Configuration.valueAsShort(String key, short default)
boolean Configuration.isTrue(String key, boolean default)
boolean Configuration.isFalse(String key, boolean default)
The renderer uses the java.util.logging
package for logging information and
exceptions at runtime. Logging behavior (output) is controlled via the main
configuration file. The defaults may be overridden just like
any other configuration properties.
Please review the java.util.logging
package docs before proceeding.
We log to a set of hierarchies. The internal code--everything between a request to load a page and the page rendering--is logged to a subhierarchy of "plumbing", e.g. plumbing.load. Our convention is that WARNING and SEVERE levels are very important and should always be logged. INFO messages are useful and but can be excluded if you want a quiet ride. Anything below INFO (FINE, FINER, FINEST) is generally only interesting for core renderer developers. We don't guarrantee that anything below INFO will be useful, correct, practical or informative. You can usually leave log levels at INFO for most purposes.
If you are modifying the renderer core code and want to add log messages, we recommend
you always use the org.xhtmlrenderer.XRLog
class. Using this class ensures that
our log configuration is read properly before we write anything out to the log system.
The class is pretty self-explanatory, and all logging methods in it are static. If for some
reason you need to use the java.util.logging.Logger
class directly, please
use XRLog.getLogger()
to retrieve the instance to use.