|
AjaxSwing provides support interfaces that allow Swing
components to provide additional information to AjaxSwing renderers.
This information is used to take advantage of additional functionality that goes beyond standard Swing components. Integration typically requires implementing one of
the optional support interfaces from com.creamtec.ajaxswing.support package.
Enhanced JTable rendering
information is provided through
com.creamtec.ajaxswing.support.TableSupport
interface.
It allows specifying a row-level context menu that is displayed in the browser
when a user clicks right mouse button on a table row. The row is
selected and if a menu is provided it is displayed to the
user. When the user clicks on a menu item a request is sent to the server where the actions
are emulated on JTable.
Tree Support
Enhanced JTree rendering
information is provided through com.creamtec.ajaxswing.support.TreeSupport
interface. It allows specifying node-level context menus and custom node images. Context menu is displayed in the browser
when a user clicks right mouse button on a tree node. The node is
selected and if a menu is provided it is displayed to the
user. When the user clicks on a menu item a request is sent to the server where the actions
are emulated on JTree.
Custom node images can be specified either through a through a path to the image
resource or a custom image bundle. If the implementation
of TreeSupport.getNodeImagePath() returns a non-null string, it is used for the
rendered node. If getNodeImagePath() returned null, then the default path
is looked up in TreeSupport.DEFAULT_NODE_IMAGE_NAMES map based on
the node type (folder/item) and state (expanded/collapsed). getNodeImagePath() is useful
for nodes that do not have children because their image doesn't
change. Folders (nodes with children) use different images for expanded and
collapsed state, and these images are flipped through JavaScript in the browser.
To support custom images for folders a custom image bundle has to
instantiated and placed into ajaxSwingTreeImageBundles global object in
JavaScript under a user-defined bundle name. That bundle name should be returned for
the node from TreeSupport.getNodeImageBundleName(). The bundle name is used by JavaScript when a node image has
to be changed in the browser in response to expand/collapse user action.
The current implementation requires duplication of certain information between JavaScript and Java due to performance reasons. The following steps
describe a possible implementation:
- Create a subdirectory for tree images in the selected theme (e.g. AjaxSwing/tomcat/webapps/ajaxswing/Windows_docs/images/custom_tree) and copy your images there.
Note that you have to provide custom version of each image that AjaxSwing is using for tree (see TreeSupport.DEFAULT_NODE_IMAGE_NAMES
for a complete list)
- Create a Java class that extends JTree and implements TreeSupport interface (e.g. CustomTree)
- Implement getNodeImageBundleName() to return the name of your bundle (e.g. "custom")
- Implement getNodeImagePath() to return relative paths to your images (see com.creamtec.ajaxswing.ui.CustomTree in the src folder for an example)
- Create a JavaScript function in AjaxSwing/tomcat/webapps/ajaxswing/scripts/custom.js that creates a custom
image bundle object and registers it with AjaxSwing tree:
function createCustomTreeImageBundle() {
if (ajaxSwingTreeImageBundles['custom'] == null) {
// Initialize custom tree data only once
var bundle = new Object();
bundle['IMG_BLANK'] = getDocsURL() + '/images/custom_tree/Blank.gif'
bundle['IMG_LINE'] = getDocsURL() + '/images/custom_tree/Line.gif'
bundle['IMG_ITEM'] = getDocsURL() + '/images/custom_tree/Item.gif'
bundle['IMG_LAST_ITEM'] = getDocsURL() + '/images/custom_tree/LastItem.gif'
bundle['IMG_FOLDER_EXPANDED'] = getDocsURL() + '/images/custom_tree/FolderOpen.gif'
bundle['IMG_FOLDER_COLLAPSED'] = getDocsURL() + '/images/custom_tree/FolderClosed.gif'
bundle['IMG_LAST_FOLDER_EXPANDED'] = getDocsURL() + '/images/custom_tree/FolderLastOpen.gif'
bundle['IMG_LAST_FOLDER_COLLAPSED'] = getDocsURL() + '/images/custom_tree/FolderLastClosed.gif'
bundle['IMG_ROOT_FOLDER_EXPANDED'] = getDocsURL() + '/images/custom_tree/RootFolderOpen.gif'
bundle['IMG_ROOT_FOLDER_COLLAPSED'] = getDocsURL() + '/images/custom_tree/RootFolderClosed.gif'
bundle['IMG_ROOT_LAST_FOLDER_EXPANDED'] = getDocsURL() + '/images/custom_tree/RootLastFolderOpen.gif'
bundle['IMG_ROOT_LAST_FOLDER_COLLAPSED'] = getDocsURL() + '/images/custom_tree/RootLastFolderClosed.gif'
ajaxSwingTreeImageBundles['custom'] = bundle;
}
}
- Call createCustomTreeImageBundle() from customOnLoad()
in custom.js
You are done!
Context menu is displayed in response to right mouse click. In JDK 1.5 Swing has introduced JComponent.setComponentPopupMenu() method
that allows to set the context menu for a component. Prior to JDK 1.5 there is no standard support for context menu, and AjaxSwing
provides a convenience wrapper method to set and get component popup menu in JDK-independent way. See
com.creamtec.ajaxswing.gui.ComponentUtils for details.
Sometimes one needs to add a custom HTML attribute for a component, for instance to specify tab order in HTML form.
Rather then writing a custom renderer for each component type on the form, one can use ComponentUtils.getHtmlAttributes() methods.
HTML attributes specified for Swing component are automatically appended by AjaxSwing to the rendered HTML
element that represents the component. For instance, calling
ComponentUtils.getHtmlAttributes(myButton).put("tabindex", "1") for a button that is
represented with <input> HTML element will result in the following HTML
<input type="button" tabIndex="1"...>
Swing and HTML have different algorithms for determining component tab order. Swing applications by default rely on LayoutFocusTraversalPolicy
to determine what component should receive focus after the user pressed TAB key. The order is determined by component overall location in the window,
not the natural order that it appears in the container. On the contrary, HTML browsers rely on the natural order of appearance of input fields in the
form. This means that the tabulation works different in Swing application running as a standalone GUI and running under AjaxSwing. To remedy
the problem one can set the natural order of Swing components to the desired navigation order. If finer control is desired, AjaxSwing provides
com.creamtec.ajaxswing.gui.ComponentUtils for details.
CSS Class and Style Attributes
AjaxSwing automatically assigned CSS classes to all Swing components based on their type. For example, JLabel is rendered with CSS class of "label".
The list of all CSS classes can be found in styles_common.css of AjaxSwing theme. In-line style is also appended automatically based on the
Swing component properties such as bounds, colors and font. It is possible however to assign additional classes and attributes to a Swing component
and have AjaxSwing append it to automatically generated HTML.
Custom CSS classes can be specified as follows:
jTextDesc.putClientProperty(AjaxSwingProperties.COMPONENT_CSS_CLASS, "customClass1 customClass2");
Custom CSS style attributes can be specified as follows:
jTextDesc.putClientProperty(AjaxSwingProperties.COMPONENT_CSS_STYLE, "font-style:italic; background-color:white");
See AjaxSwing/src/com/creamtec/ajaxswing/ui/LoginDialog.java for an example
|