|
|
||
Overview . Tag Reference . Cheat Sheet . CSS Reference . API Reference . FAQ . History . Upcoming . Gallery . Notes . Powered By Luxor . Contribute . Mailing Lists & Forums . Premium Support . Credits . Glossary . Site Search . The Memphis Sun . Download . Download Luxilla . Download Plugins . Download Contrib . Source . Javadoc . Team . Who's Who . Donate . Luxor @ Sourceforge |
This page holds notes about various topics to help you get started with Luxor and to collect footage for upcoming articles, tutorials, books, trilogies or road shows.
You are more than welcome to contribute your own short stories or novellas. Please post your opus to Luxor's mailinglist where we will pick it up to publish it here along with proper credit. If you prefer you can mail your oeuvre directly to a Luxor team member.
You can package your app's chrome in its own jar separate from
the app's jar holding all .class
files.
To make it work, you need to honor two rules:
startup
directory or in
subdirectories of startup
.
Luxor loads all XUL files in the startup
directory tree
once you call XulManager.load()
.
Luxor queries the jar to get all files in the startup
directory tree automatically and, therefore, spares you from
worring about having forgotten to register your latest XUL file addition.
All you need to do is store your XUL files in the startup
directory
tree and Luxor will automatically pick them up and load them on startup;
no registration required.
ChromeAnchor.class
)
to your chrome jar so Luxor can find your chrome jar
and extract all XUL files, icons, templates, XML documents, etc.
without bothering about its file name or storage site.
As long as the chrome jar is in your classpath or
in Web Start's JNLP startup file, Luxor will find it, no matter what name
it boasts and no matter in what directory it hides.
try { Class chromeAnchorClazz = Class.forName( "ChromeAnchor" ); XulResourceLoader xulResourceLoader = new XulJarResourceLoader( chromeAnchorClazz ); XulManager.getXulManager().setResourceLoader( xulResourceLoader ); } catch( ClassNotFoundException cex ) { System.err.println( "chrome anchor class '" + chrome + "' not found: " + cex.toString() ); }
A resource anchor is nothing more than an empty class that you bundle up in a jar along with your resources (that is, icons, XUL files, XML data, HTML pages, etc.). For a more detailed expose of the resource anchor technique check out the Web Start Resource Loading Tutorial at http://www.vamphq.com/tutorial.html . Finally, here are two uncut, full-length, real-world resource anchors:
public class ChromeAnchor { public ChromeAnchor() { } } public class CrossRefAnchor { public CrossRefAnchor() { } }
Lastly, here is a peek into Venus Application Publisher's
real-world chrome.jar
revealing its directory structure:
Luxor is designed from the ground up for Web Start and, therefore, works out-of-the-box without the need for patches or dirty tricks. If Web Start doesn't ring a bell, check the links below to find out more:
Luxor XUL builds on proven technology such as XML, HTML, CSS, Velocity, HTTP, XSL/T, Python, XPath, JNLP and more. To learn more about Luxor XUL start by brushing up on the proven open standard technolgies leveraged by Luxor.
Mozilla XUL. Although Luxor XUL isn't a 100 % Mozilla XUL clone, it only breaks compatibility if there's a better way.
XUL Planent. More Mozilla XUL resources.
Apache Velocity. Resources about Luxor's template engine of choice.
Python/Jython. Resource about Luxor's scripting engine of choice.
Guido van Rossum, Fred L. Drake, Jr., Python Reference Manual - http://www.python.org/doc/current/ref/ref.html
Python is an interpreted, object-oriented, high-level programming language with dynamic semantics. Its high-level built in data structures, combined with dynamic typing and dynamic binding, make it very attractive for rapid application development, as well as for use as a scripting or glue language to connect existing components together. Python's simple, easy to learn syntax emphasizes readability and therefore reduces the cost of program maintenance. Python supports modules and packages, which encourages program modularity and code reuse. The Python interpreter and the extensive standard library are available in source or binary form without charge for all major platforms, and can be freely distributed.
Guido van Rossum, Comparing Python to Other Languages (Java, Javascript, Perl, Tcl, Smalltalk, C++, Lisp) - http://www.python.org/doc/essays/comparisons.html
Luxor XUL ships with built-in support for portlets and includes a light-weight portal engine.
What is a portlet? Portlets (also known as HTML pagelets or HTML controls) are basically like servlets, but return HTML snippets instead of complete HTML pages. Multiple portlets plus some sprinkled static XHTML fragments make up a complete web page also known as portal. Example:
<portal id="SYSTEM_INFO"> <div align="center"> <table border="0" width="90%" cellspacing="0" cellpadding="0"> <tr> <td> <portlet id="USER_BANNER" /> <portlet id="SYSTEM_INFO" /> <portlet id="SYSTEM_PROPERTIES" /> </td> </tr> </table> </div> </portal>
To create your own portlet,
you need to implement the luxor.spi.XulPortlet
interface.
XulPortlet
's only method getContent()
gets passed in
a hashtable of name/value pairs and returns the HTML snippet as a string.
public interface XulPortlet { public String getContent( Map args ); }
As most portlets return dynamic content, you can use Luxor's built-in Velocity template engine to help you create the portlets HTML snippet on-the-fly.
The SystemPropertiesPortlet
example below
creates a HTML table that lists all Java system properties alphabethicly
using a Velocity template.
(For the complete source code, download the Ramses example suite
and look at the Hello Ramses example app.)
public class SystemPropertiesPortlet implements XulPortlet { ... public String getContent( Map args ) { // no required arguments List sysProps = createPropertyList( System.getProperties() ); HashMap data = new HashMap(); data.put( "sysProps", sysProps ); XulManager xul = XulManager.getXulManager(); String html = xul.getTemplate( data, "portlet/system-properties.html" ); return html; } }
The Velocity template loops over the portlet-supplied sorted system property list to contribute a HTML table to the portal (aka web page).
<h2> $sysProps.size() System Properties</h2> <table border="1"> #foreach( $prop in $sysProps ) <tr> <td>$prop.key</td> <td>$prop.value</td> </tr> #end </table>
To display the portal (aka web page) in your embedded web browser
(e.g. JEditorPane
) you can
use Luxor's XulMangager.getPortal()
method
that returns the portal's HTML in a string that you pass on to
JEditorPane
. Example:
XulManager xul = XulManager.getXulManager(); String html = xul.getPortal( "SYSTEM_INFO" ); JEditorPane browser = new JEditorPane(); browser.setEditable( false ); browser.setContentType( "text/html" ); browser.setText( html );
A better method is to create a XulServlet
.
A XulServlet
uses Luxor's built-in, ultra light-weight,
multi-threaded web server to serve up the portals HTML to your embedded browser or
the machine's household browser (e.g. Netscape, Opera, etc.).
Example:
public class CmdSystemInfo extends XulAction implements XulServlet { private AppShell _shell; public CmdSystemInfo(AppShell shell) { super( Chrome.Action.SYSTEM_INFO ); _shell = shell; XulManager.getXulManager().addServlet( getId(), this ); } public void execute() { onSystemInfo(); } public String getContent( Map args ) { XulManager xul = XulManager.getXulManager(); String html = xul.getPortal( Chrome.Portal.SYSTEM_INFO ); return html; } public void onSystemInfo() { UrlQueryString query = new UrlQueryString(); query.add( "action", getId() ); _shell.showDocument( query ); } }
The URL to display the portal in your household browser
in the example above is: http://localhost:5454/ramses?action=system-info
.
The URL breaks down as follows: The Hello Ramses example app starts the web server (aka http service) on port 5454.
static public final int PORT = 5454; ... WebServer webServer = new WebServer( PORT, webResourceManager ); webServer.start();
Next, all Luxor XulServlet
s are made available through
XulServletResourceLoader
that takes in a context in its constructor.
A context is the industry jargon for a part of an URL path.
In this case, the context is simply ramses
. Example:
WebResourceManager webResourceManager = WebResourceManager.getWebResourceManager(); // make xul servlets available through built-in web server webResourceManager.addResourceLoader( new XulServletResourceLoader( "ramses" ) );
Lastly, Luxor's web server uses the query argument action
to dispatch
incoming requests. Therefore, the URL query convention is:
action=<Xul Action Id>
(e.g. action=sys-info
).
You can pass in additional parameters by appending them to the URL query string.
Portlet Links
To retrieve icons, menus, toolbars, templates and more you need to
get a hand onto a XulManager
reference. Example:
XulManager xul = XulManager.getXulManager(); JMenuBar menuBar = xul.createMenuBar( Chrome.MenuBar.MAIN ); JToolBar toolBar = xul.createToolBar( Chrome.ToolBar.MAIN ); ImageIcon icon = xul.lookupIcon( Chrome.Icon.RAMSES );
This is perfectly fine as long as you use the xul
reference repeatedly.
If all you want is retrieve an icon, box or template, for example,
you can use Xul
s static convenience methods
that won't require a XulManager
reference as a shortcut.
Example:
Use
Xul.lookupIcon( Icon.JNLP_INFORMATION_ICON );
instead of
XulManager.getXulManager().lookupIcon( Icon.JNLP_INFORMATION_ICON );
Luxor includes a status (aka error reporting and logging) toolkit that you can use for GUI as well as GUI-less (aka command-line) apps. Luxor itself reports all errors, warnings and infos through its toolkit and ships with a couple of pre-built status handlers that you can reuse in your apps as well.
Architecture. Luxor's status toolkit uses the publish/subscribe model. Luxor sends reported errors, warnings, infos, hints, etc. to subscribed status handler. Status handler for command-line apps usually display incoming messages in plain text on the console, while GUI apps display incoming messages in the status bar or in a message box using styled text in various colors (e.g red for errors, orange for warnings, etc) with icons and other visual gimmicks.
To report errors, warnings, infos, hints, etc. use one of the static
methods in luxor.status.Status
. Example:
Status.info( "downloading " + _source.toExternalForm() + "..." ); Status.info( 3, carFile + " successfully created" ); Status.warning( "*** skipping unsupported file type:" + internalPath ); Status.error( "*** failed to startup web service: " + ioex.toString() ); Status.error( "*** source path for jar " + jar.getHref() + " required" );
To make sure that your reported messages get noticed and end up on
the user's screen, you need to register status handlers.
Use luxor.status.Status.addListener( StatusListener )
to
tell Luxor who's in the loop and gets the latest updates. Example:
Status.addListener( new StatusConsole() ); Status.addListener( _statusPanel ); Status.addListener( _statusBarPanel );
Luxor ships with three pre-built status handlers.
luxor.status.StatusConsole
-
sends messages to console using System.out
as well as to Apache's
log4j toolkit
demo.common.status.StatusBarPanel
-
displays messages in the status bar using color coding;
the latest message overwrites the previous one
demo.common.status.StatusPanel
-
displays messages in a text box using color coding; no messages get purged
Roll Your Own Status Handler.
To create your own status handler, implement
the interface luxor.event.StatusListener
. Example:
public class StatusConsole implements StatusListener { public void hint(String msg) { System.out.println( msg ); } public void info(String msg) { System.out.println( msg ); } public void warning(String msg) { System.out.println( msg ); } public void fatal(String msg) { System.out.println( msg ); } public void error(String msg) { System.out.println( msg ); } public void info( int level, String msg ) { System.out.println( "[" + level +"] " + msg ); } }
Luxor includes a form validation framework to let you check the user's input and report wrong formats, missing fields, and more.
To validate a input control's data register
a luxor.event.XulInputValidationHandler
. Example:
public class UserRegistrationForm extends XulForm implements XulInputValidationHandler { XulInput _name; XulInput _address; XulInput _city; XulInput _zip; ... public void init() { _name = new XulInput( this, "name" ); _address = new XulInput( this, "address" ); _city = new XulInput( this, "city" ); _zip = new XulInput( this, "zip" ); ... _name.addValidationHandler( this ); _address.addValidationHandler( this ); _city.addValidationHandler( this ); _state.addValidationHandler( this ); ... } public void validate( XulInput input ) { if( input == _name ) { InputValidator.checkRequired( _name ); } else if( input == _address ) { InputValidator.checkRequired( _address ); } else if( input == _state ) { InputValidator.checkRequired( _state ); } else if( input == _zip ) { if( InputValidator.checkRequired( _zip ) ) InputValidator.checkZip( _zip ); } ... } }
How does the magic work? Every input control owns a list of validation errors and, therefore, knows if it is valid or not. As a form knows all it's input controls, it can loop over all input controls and check if the form is valid (that is, if there are no validation errors attached to any of its input controls). Every time an input control looses the focus (blurs) Luxor clears the input control's validation error list and calls all registered input control validators. It's the validator's task to add validation errors to the input control if no data is present, the zip format is wrong, etc. Example:
public static boolean checkRequired( XulInput input ) { String value = input.getText().trim(); if( value.equals( "" ) ) { input.getValidator().addError( new InputValidationError( input.getName() + " is required" ) ); return false; } return true; } public static boolean checkAge( XulInput input ) { String value = input.getText().trim(); if( !isInteger( value ) || !inRange( value, 1, 150 ) ) { input.getValidator().addError( new InputValidationError( "number between 1 and 150 expected for " + input.getName() )); return false; } return true; }
Display form validation summary in HTML.
To display a form's validation errors create a luxor.event.XulFormListener
that updates the form's validation errors on the user's screen every time an input control blurs (looses focus).
Retrieve the form's validation error list using XulForm.getValidationErrors()
and render it in HTML or plain-text using a Velocity template
to create a form validation summary. Example:
private String getContent() { // don't print anything if form is valid if( _form.isValid() ) return ""; HashMap data = new HashMap(); data.put( "errors", _form.getValidationErrors() ); String html = Xul.getTemplate( data, "template/validation-status.html" ); return html; }
And here is the validation-status.html
Velocity template:
#if ($errors.size() == 1 ) $errors.size() validation error #else $errors.size() validation errors #end <ul> #foreach( $error in $errors ) <li> $error.getErrorMessage() #end </ul>
For a complete example that you can kick start at your very own desktop with full-source code, check out the validation example in Luxor's Ramses example suite.
Future additions. More to come. Note, that Luxor's validation framework is experimental, meaning that it isn't full-featured yet and that I will add more goodies in upcoming Betas based on real-world experience and examples including:
required
attribute for input controls
to make checking for required fields easier requiring no more Java code.
validate
attribute that is turned on by default
and lets you exclude a field from validation if you desire.
Luxor ships with an example suite called Hello Ramses. Ramses includes the following apps:
Title | Description |
---|---|
batik | (work-in-progress) Batik SVG Viewer |
box | Shows Off Box Layout System |
calc | (work-in-progress) Calculator App |
datagrid | Shows Off Data Grid Filled With XML Data |
form | Shows Off Luxor XUL Forms |
hello | Shows Off Portlets; Portals; Menus; Toolbars; Embedded, Ultra Light-Weight, Multi-Threaded Web Server |
image | Shows Off Image Tag |
mini | Bare-minimum Luxor App |
misc | Shows Off Miscellaneous Luxor Goodies (e.g. Browser Target) |
notepad | (work-in-progress)Text Editor |
transform | Demos XSL/T Usage Inside XUL Documents To Build a Bookmark Menu |
tree | Shows Off Tree Tag |
validate | Demos XUL Form Validation Using HTML Validation Summaries |
Luxor's has built-in support for configuration data loaded automatically
on startup.
Luxor supports two formats: Java's type-less, anything-goes, name-value-pair property format
and a strongly-typed XML format
supporting strings, ints, booleans, arrays, base64 and more.
Luxor picks up all config data files stored in the locale
chrome directory tree. Example:
locale +--en-us +--test.properties +--test.xml
Java's type-less, anything-goes, name-value-pair property format example:
app.vendor=Gerald Bauer app.title=Misc Example App app.descr=Tests Misc Luxor Services
Strongly-typed XML config data format example:
<config> <string id="about.title" value="About" /> <string id="messages.title" value="Messages" /> <int id="httpd.port" value="7272" /> <array id="celia.banner"> <string value="Vamp - Venus Application Publisher - (C)opyright Gerald Bauer 2001, 2002" /> <string value=" Visit www.vamphq.com for more info" /> <string value="" /> </array> </config>
Luxor supports the following XML config data types:
Type | Value | Examples |
---|---|---|
int
|
32-bit integers between -2,147,483,648 and 2,147,483,647 |
<int id="proxy.port" value="5151"/>
<int id="proxy.port">5151</int>
|
double
|
64-bit floating-point numbers | |
boolean
|
true(1) or false(0) | |
string
|
Unicode text | |
date
|
Date | |
base64
|
Binary information encoded as Base 64 as defined in RFC 2045 | |
array
|
Single-type array |
To retrieve config data such as strings, ints, or doubles use
the following XulManager
methods:
Method | Comments |
---|---|
String getString( String key )
String getString( String key, String defaultValue )
|
|
String[] getStringArray( String key )
|
|
int getInt( String key, int defaultValue )
|
Luxor's built-in Velocity template engine is not limited to HTML. You can create plain-vanilla ASCII text, XML documents, SQL scripts and more.
Predefined Data Objects
Luxor's lets you access all Java System properties in Velocity templates.
Note, however, that you need to replace all dots with dashes
(e.g user.name
becomes user-name
).
Luxor loads Velocity templates always on demand (that is, never on startup). Therefore, don't store them in the chrome's startup directory tree.
Velocity Logger
Luxor redirects Velocity log messages to its own class luxor.template.LuxorVelocityLogger
.
To see Velocity log messages either turn on Java's built-in logging using properties
(e.g. java.util.logging.*
)
or add Luxor status handlers. Example:
// make sure we don't miss any errors, warnings, hints. Status.addListener( new StatusConsole() );
Links/Resources
Luxor uses a thin wrapper around Java's 1.4
built-in java.util.logging.Logger
class.
By default Java's runtime spits out
all log messages on the console
ranking as INFO or higher.
To let the runtime spit out
more or less log messages or
to let it send log messages to a
file or to a socket
use Java's standard java.util.logging.*
properties.
Why bother wrapping Java's built-in logging toolkit?
T.debug()
, T.error()
, T.fatal()
, etc.)
Luxor uses the log message types below,
ranked from highest to lowest.
Luxor's types differ slightly from
Java's built-in logging types:
Instead of SEVERE
for all errors Luxor uses FATAL
and ERROR
.
Luxor adds DEBUG
as an alias for FINE
and adds the new message type
HINT
one notch below INFO
and one above CONFIG/DEBUG
.
Luxor | java.util.logging | Audience | Comment |
---|---|---|---|
FATAL | SEVERE | Grandma (*) | |
ERROR | SEVERE | Grandma | |
WARNING | WARNING | Grandma | |
INFO | INFO | Grandma | |
HINT | INFO | Grandma | |
CONFIG | CONFIG | Sys Admin | |
DEBUG/FINE | FINE | Developer | |
FINER | FINER | Developer | |
FINEST | FINEST | Developer |
(*) also known as end-user
Configuring Loggers.
By default the Java runtime picks up the logging settings
from the logging.properties
config file in
its lib directory (e.g. jre/v14/lib
).
Note, that if you installed a dev kit (aka JDK) you
likely have two copies of the Java runtime on your machine.
To find out which Java runtime Web Start picks up
to fire off your app peek into
javaws.cfg
, Web Start's config file residing
in its home directory (e.g. java/jws/v1.01-2
).
The snippet below reveals my box'es settings:
javaws.cfg.jre.1.product=1.4.0 javaws.cfg.jre.1.platform=1.4 javaws.cfg.jre.1.location=http\://java.sun.com/products/autodl/j2se javaws.cfg.jre.1.path=c\:\\java\\jre\\v14\\bin\\javaw.exe
As an alternative you can kick start the Hello Ramses Luxor Example
app (that is, hello.jnlp
)
and switch over to the system info page.
Under the directories heading you'll find the nugget
you are looking for.
Example:
User Home: c:\windows Temp Directory: c:\windows\temp Java Home: c:\java\jre\v14 Web Start Home: c:\java\jws\v1.01-2
By default the Java runtime uses the settings below to spit out all log message ranked as INFO and above to the console (aka command line shell, dos box):
# "handlers" specifies a comma separated list of log Handler classes. handlers= java.util.logging.ConsoleHandler # Default global logging level. .level= INFO # Limit the message that are printed on the console to INFO and above. java.util.logging.ConsoleHandler.level = INFO java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
To dump the log messages to a file in the user's home directory
as well as to the console
append a FileHandler
and configure it.
Example:
handlers= java.util.logging.ConsoleHandler, java.util.logging.FileHandler # default file output is in user's home directory. java.util.logging.FileHandler.pattern = %h/java%u.log java.util.logging.FileHandler.level = FINE java.util.logging.FileHandler.limit = 10000 java.util.logging.FileHandler.count = 1 java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
Note, refrain from using the prelisted
java.util.logging.XMLFormatter
unless you have time to kill (as your app won't pop up in an instant).
As an alternative you can sidestep the factory-shipped
jre/v1.4/lib/logging.properties
logging config file
and preserve it untouched and direct the Java Runtime to use your
very own config file instead.
Add a property tag for java.util.logging.config.file
pointing to your config file to your app's JNLP startup file.
Example:
<property name="java.util.logging.config.file" value="c:/sandbox/etc/logging.properties" />
Why not embed Apache Tomcat? Luxor's built-in web server is ultra-light weight in contrast to Tomcat so that every Luxor app can startup, configure and use it's own web server (though they can share a caching proxy server). Luxor's web server is not designed to serve up mission critical, 24x7x365, always-up, high performance web sites hit by thousands of customers at the same time instead it is designed to serve Grandma playing with a Luxor app on a desktop computer.
Web Server Comparison Chart:
Web Server | Domain | Audience | Simultaneous Users |
---|---|---|---|
Apache | Galaxy | Million Internet Surfers | 1000+ |
Tomcat | Family Home Network, Low-Traffic Web Site, Power User Workstation | A Handful Users and/or Apps | 10+ |
Luxor | Luxor Desktop App | Grandma Emma | 1+ |
Start Me Up.
To start Luxor's built-in, ultra light-weight, multi-threaded
web service use the luxor.http.WebServer
class.
Pass in the socket port (e.g. 7272)
plus a reference to a web resource manager and off you go.
Example:
try { WebServer webServer = new WebServer( 7272, webResourceManager ); webServer.start(); } catch( IOException ioex ) { Status.error( "*** failed to start http service (built-in web server): " + ioex.toString() ); }
Web Resource Manager. Use web resource managers to tell Luxor's built-in web server what you want to serve up. Luxor ships with the built-in, ready-to-use web resource mangers below:
Class | Usage |
---|---|
luxor.http.loader.WebResourceManager
|
|
luxor.http.loader.ClassResourceLoader
|
|
luxor.http.loader.XulServletResourceLoader
|
|
luxor.http.loader.CacheResourceLoader
|
|
luxor.http.loader.FileResourceLoader
|
|
luxor.http.loader.FileContextResourceLoader
|
Scenario I: How to serve up web pages, graphics, and more packaged in jars stashed away in Web Start's cache.
// make content of selected jars availabe through built-in web server try { Class webResourceAnchorClazz = Class.forName( "WebResourceAnchor" ); webResourceManager.addResourceLoader( new ClassResourceLoader( webResourceAnchorClazz ) ); Class crossRefAnchorClazz = Class.forName( "CrossRefAnchor" ); webResourceManager.addResourceLoader( new ClassResourceLoader( crossRefAnchorClazz ) ); } catch( ClassNotFoundException cex ) { Status.error( "*** failed to locate built-in web resources: " + cex.toString() ); }
Scenario II: How to serve up portals, that is, web pages made up of portlets and static HTML snippets.
// make xul servlets available through built-in web server webResourceManager.addResourceLoader( new XulServletResourceLoader( "ramses" ) );
Scenario III: How to create wizards for your app with web pages and plain-vanilla hyperlinks.
To help you figure out your layout when
arranging your furniture using Luxor's
horizontal (left-to-right) and vertical (top-to-bottom) boxes,
turn on the xul.debug.layout
property
by adding it to your app's JNLP startup file.
Example:
<property name="xul.debug.layout" value="true" />
Once you turned xul.debug.layout
on,
Luxor will draw a four-line-thick red border around vertical boxes
and a four-line-thick blue border around horizontal boxes.
Avoid sprinkling your chrome keys all over your sources or even worse hard-wiring them in place without using constants. Instead collect all your chrome keys in constant holder classes. Once you have all your chrome keys lined up in a constant holder class you can, for example, use a code editor's auto-completion to speed up coding. Using constants also strengthens your apps as the compiler enforces at compile-time that you only use chrome keys defined as constants. If you feel ambitous you can even create your own chrome key checker that reads in constant holder classes and checks all your xul files if the keys match at compile-time.
public class Chrome { public static class MenuBar { public static final String MAIN = "MAIN"; } public static class Icon { public static final String CALC = "CALC"; } public static class Box { public static final String DISPLAY = "display"; } }
or put your keys in interfaces
to spare you from typing public static final
for each and every constant. Example:
public class Chrome { public interface MenuBar { String MAIN = "MAIN"; } public interface Icon { String CALC = "CALC"; } public interface Box { String DISPLAY = "display"; } }
Class | Description |
---|---|
luxor.core.loader.XulFileResourceLoader
|
|
luxor.core.loader.XulJarResourceLoader
|
|
luxor.core.loader.XulResourceLoaderManager
|
The long-winded, type-intensive way to get internationalized string
is using XulManager.getXulManager().getString()
or Xul.getString()
.
The Better Way.
To safe on typing and simplify your code, cut and paste
the static str
method below to every class
where you use internationalized strings.
private static String str( String key ) { return XulManager.getXulManager().getString( key, "string " + key + " not found" ); }
Now you can type
setTitle( str( "app.title" ) );
instead of clumsy
setTitle( Xul.getString( "app.title" ) ); setTitle( XulManager.getXulManager().getString( "app.title" ) );
You can divide up you app's chrome in three kingdoms: Startup, Locale and The Works.
Startup The startup directory tree holds
all resources that Luxor loads at once
when you call XulManager.load()
.
Do's
Don'ts
Locale
Do's
The Works (aka The Rest)
Luxor adds the custom chrome:// URL protcol handler that lets use easily reference resources within your apps chrome no matter if packed up in jars or spread out in loose files.
Example chrome:// URLs.
Usage Example: Display Pre-packaged HTML page in built-in web browser window.
Usage Example: Use DisplayURL Tag to Display pre-packaged HTML page in built-in web browser window target.
Luxor builts on proven open standards.
World Wide Web Consortium (W3C)
Web Standard | Date | Link |
---|---|---|
HTML - Hyper Text Markup Language 4.01 | December 1999 | http://www.w3.org/TR/html401 |
XHTML - Extensible Hyper Text Markup Language 1.0 | January 2000 | http://www.w3.org/TR/xhtml1 |
CSS1 - Cascading Style Sheets Level 1 (Revision) | January 1999 | http://www.w3.org/TR/REC-CSS1 |
CSS2 - Cascading Style Sheets Level 2 | May 1998 | http://www.w3.org/TR/REC-CSS2 |
XML - Extensible Markup Language 1.0 (Second Edition) | October 2000 | http://www.w3.org/TR/REC-xml |
XSL - Extensible Stylesheet Language 1.0 | October 2001 | http://www.w3.org/TR/xsl/ |
XSLT - XSL Transformations 1.0 | November 1999 | http://www.w3.org/TR/xslt |
XPath - XML Path Language 1.0 | November 1999 | http://www.w3.org/TR/xpath |
SVG - Scalable Vector Graphics 1.0 | September 2001 | http://www.w3.org/TR/SVG/ |
Internet Engineering Task Force (IETF)
Mozilla.org
Apache Jakarta
Sun Microsystems
Guido van Rossum
|
Hosted by SourceForge |
For questions related to the use of Luxor,
please consult our web pages.
If that fails, the luxor-xul-user mailinglist
might help.
Please send comments on our web pages and the development of Luxor to our public luxor-xul-develop mailinglist. |
Maintained by Luxor Team
Copyright © 2001, 2002, 2003, 2004, 2005 Luxor Foundation |