Java tutorial
/* * Copyright 2000,2005 wingS development team. * * This file is part of wingS (http://wingsframework.org). * * wingS is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 * of the License, or (at your option) any later version. * * Please see COPYING for the complete licence. */ package org.wings.plaf.css; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wings.plaf.Update; import org.wings.*; import org.wings.style.CSSProperty; import org.wings.sdnd.SDragAndDropManager; import org.wings.event.SRequestListener; import org.wings.event.SRequestEvent; import org.wings.dnd.DragAndDropManager; import org.wings.header.*; import org.wings.io.Device; import org.wings.plaf.CGManager; import org.wings.plaf.css.script.*; import org.wings.resource.ClassPathResource; import org.wings.resource.ReloadResource; import org.wings.resource.ResourceManager; import org.wings.resource.UpdateResource; import org.wings.resource.ResourceNotFoundException; import org.wings.script.*; import org.wings.session.*; import javax.swing.*; import java.io.IOException; import java.util.*; import java.awt.event.KeyEvent; import java.awt.event.InputEvent; /** * PLAF renderer for SFrames. * Does quite many abritriray things i.e. registering diverse service scripts, etc. */ public class FrameCG implements org.wings.plaf.FrameCG { private static final long serialVersionUID = 1L; private final static Log log = LogFactory.getLog(FrameCG.class); /** * The default DOCTYPE enforcing standard (non-quirks mode) in all current browsers. Please be aware, that * changing the DOCTYPE may change the way how browser renders the generate document i.e. esp. the CSS * attribute inheritance does not work correctly on <code>table</code> elements. * See i.e. http://www.ericmeyeroncss.com/bonus/render-mode.html */ public final static String STRICT_DOCTYPE = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" " + "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"; /** * The HTML DOCTYPE setting all browsers to Quirks mode. We need this to force IE to use the correct box * rendering model. It's the only browser you cannot reconfigure via a CSS tag. */ public final static String QUIRKS_DOCTYPE = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" " + "\"http://www.w3.org/TR/2002/REC-xhtml1-20020801/DTD/xhtml1-transitional.dtd\">"; // EmulateIE7 means 5 in quirks mode and 7 in standard mode .. this is what 7 actually did public final static String IE_COMPATIBILITY_MODE = "<meta http-equiv=\"X-UA-Compatible\" content=\"IE=EmulateIE7\" />"; /** * Lookup for a property Stylesheet.BROWSERNAME to know fitting stylesheets */ private static final String PROPERTY_STYLESHEET = "Stylesheet."; private static final String BROWSER_DEFAULT = "default"; private String documentType = STRICT_DOCTYPE; /** * Should the returned HTML page start with the <?xml version="1.0" encoding="...">. * This has effects which rendering mode the browsers will choose (quirks/strict) */ private Boolean renderXmlDeclaration = Boolean.FALSE; protected final List<Header> headers = new ArrayList<Header>(); protected final List<Script> defaultHeaders = new ArrayList<Script>(); /** * Initialize properties from config */ public FrameCG() { final CGManager manager = SessionManager.getSession().getCGManager(); final String userDocType = (String) manager.getObject("FrameCG.userDocType", String.class); final Boolean userRenderXmlDecl = (Boolean) manager.getObject("FrameCG.renderXmlDeclaration", Boolean.class); if (userDocType != null) { setDocumentType(userDocType); } if (userRenderXmlDecl != null) { setRenderXmlDeclaration(userRenderXmlDecl); } addHeaders(); } public void addHeaders() { // Add JS headers which should be included in every frames by default // (JS_YUI_UTILITIES = aggregate: yahoo, dom, event, connection, animation, dragdrop, element) defaultHeaders.add(Utils.createExternalizedJSHeaderFromProperty(Utils.JS_YUI_UTILITIES)); defaultHeaders.add(Utils.createExternalizedJSHeaderFromProperty(Utils.JS_YUI_CONTAINER)); defaultHeaders.add(Utils.createExternalizedJSHeaderFromProperty(Utils.JS_YUI_EDITOR)); defaultHeaders.add(Utils.createExternalizedJSHeaderFromProperty(Utils.JS_YUI_EDITOR_SIMPLE)); defaultHeaders.add(Utils.createExternalizedJSHeaderFromProperty(Utils.JS_WINGS_ALL)); // Add CSS headers which should be included in every frames by default // (DO use files under "yui/assets" and DO NOT use those under "yui/<component>/assets") headers.add(Utils.createExternalizedCSSHeaderFromProperty(Utils.CSS_YUI_ASSETS_CONTAINER)); headers.add(Utils.createExternalizedCSSHeaderFromProperty(Utils.CSS_YUI_ASSETS_EDITOR)); headers.add(Utils.createExternalizedCSSHeaderFromProperty(Utils.CSS_YUI_ASSETS_SIMPLE_EDITOR)); // Externalize images needed for default skin new SResourceIcon((String) ResourceManager.getObject(Utils.IMG_YUI_ASSETS_SPRITE, String.class)).getId(); new SResourceIcon((String) ResourceManager.getObject(Utils.IMG_YUI_ASSETS_EDITOR_SPRITE, String.class)) .getId(); new SResourceIcon( (String) ResourceManager.getObject(Utils.IMG_YUI_ASSETS_EDITOR_SPRITE_ACTIVE, String.class)) .getId(); // Common hack to externalize the ugly .htc-file for dealing with form buttons in IE new ClassPathResource("org/wings/plaf/css/formbutton.htc", "text/x-component").getId(); } public void installCG(final SComponent comp) { final SFrame component = (SFrame) comp; // Add dynamic resources to the frame ReloadResource reloadResource = new ReloadResource(component); component.addDynamicResource(reloadResource); UpdateResource updateResource = new UpdateResource(component); component.addDynamicResource(updateResource); // Externalize update resource component.getDynamicResource(UpdateResource.class).getId(); final JavaScriptDOMListener handleClicks = new JavaScriptDOMListener(JavaScriptEvent.ON_CLICK, "wingS.util.handleBodyClick", comp); final JavaScriptDOMListener storeFocusFF = new JavaScriptDOMListener(JavaScriptEvent.ON_FOCUS, "wingS.util.storeFocus", comp); final JavaScriptDOMListener storeFocusIE = new JavaScriptDOMListener(JavaScriptEvent.ON_ACTIVATE, "wingS.util.storeFocus", comp); // Add script listeners to the frame component.addScriptListener(handleClicks); component.addScriptListener(Utils.isMSIE(component) ? storeFocusIE : storeFocusFF); SessionHeaders.getInstance().registerHeaders(0, headers); SessionHeaders.getInstance().registerHeaders(1, defaultHeaders); SessionHeaders.getInstance().registerHeaders(getBrowserStylesheets()); new InputMapRequestListener(component); } class InputMapRequestListener { SFrame frame; public InputMapRequestListener(SFrame frame) { this.frame = frame; frame.putClientProperty("InputMapRequestListener", this); frame.getSession().addRequestListener(new SRequestListener() { public void processRequest(SRequestEvent e) { if (e.getType() == SRequestEvent.DELIVER_START && InputMapRequestListener.this.frame .getDynamicResources().contains(e.getRequestedResource().getObject())) { boolean changeDetected = false; Set<SComponent> components = InputMapRequestListener.this.frame .getGlobalInputMapComponents(); for (SComponent component : components) { boolean visible = component.isRecursivelyVisible(); if (!Boolean.valueOf(visible).equals(component.getClientProperty("visible"))) { component.putClientProperty("visible", visible); changeDetected |= true; } } for (SComponent component : components) { if (checkForChange(component, SComponent.WHEN_FOCUSED_OR_ANCESTOR_OF_FOCUSED_COMPONENT)) { changeDetected |= true; } if (checkForChange(component, SComponent.WHEN_IN_FOCUSED_FRAME)) { changeDetected |= true; } } if (changeDetected) { String script = strokes(components); InputMapRequestListener.this.frame.getSession().getScriptManager() .addScriptListener(new JavaScriptListener(null, null, script)); } } } }); } private boolean checkForChange(SComponent component, int condition) { InputMap inputMap = component.getInputMap(condition); if (inputMap != null && inputMap.size() > 0) { if (!(inputMap instanceof VersionedInputMap)) { inputMap = new VersionedInputMap(inputMap); component.setInputMap(condition, inputMap); component.putClientProperty("inputMapVersion" + condition, -1); } final VersionedInputMap versionedInputMap = (VersionedInputMap) inputMap; final Integer inputMapVersion = (Integer) component .getClientProperty("inputMapVersion" + condition); if (inputMapVersion == null || versionedInputMap.getVersion() != inputMapVersion) { component.putClientProperty("inputMapVersion" + condition, versionedInputMap.getVersion()); return true; } } return false; } } protected String strokes(Set<SComponent> components) { if (components == null) return null; StringBuilder builder = new StringBuilder(); builder.append("var wk = wingS.keyboard;"); builder.append("var kss = wk.keyStrokes = [];"); builder.append("var ks = wingS.keyboard.KeyStroke;\n"); for (SComponent component : components) { if (component.isRecursivelyVisible()) { appendStrokes(builder, component, SComponent.WHEN_FOCUSED_OR_ANCESTOR_OF_FOCUSED_COMPONENT, component.getInputMap(SComponent.WHEN_FOCUSED_OR_ANCESTOR_OF_FOCUSED_COMPONENT)); appendStrokes(builder, component, SComponent.WHEN_IN_FOCUSED_FRAME, component.getInputMap(SComponent.WHEN_IN_FOCUSED_FRAME)); } } return builder.toString(); } private void appendStrokes(StringBuilder builder, SComponent component, int condition, InputMap inputMap) { KeyStroke[] keyStrokes = inputMap.keys(); if (keyStrokes != null) { for (int i = 0; i < keyStrokes.length; i++) { KeyStroke keyStroke = keyStrokes[i]; Object binding = inputMap.get(keyStroke); switch (keyStroke.getKeyEventType()) { case KeyEvent.KEY_PRESSED: builder.append("kss.push(new ks('"); builder.append(component.getName()); builder.append("',"); builder.append( condition == SComponent.WHEN_FOCUSED_OR_ANCESTOR_OF_FOCUSED_COMPONENT ? "!0" : "!1"); builder.append(",'"); builder.append(binding); builder.append("',"); builder.append(keyStroke.getKeyCode()); builder.append(','); builder.append((keyStroke.getModifiers() & InputEvent.SHIFT_DOWN_MASK) != 0 ? "!0" : "!1"); builder.append(','); builder.append((keyStroke.getModifiers() & InputEvent.CTRL_DOWN_MASK) != 0 ? "!0" : "!1"); builder.append(','); builder.append((keyStroke.getModifiers() & InputEvent.ALT_DOWN_MASK) != 0 ? "!0" : "!1"); builder.append("));\n"); break; case KeyEvent.KEY_TYPED: break; case KeyEvent.KEY_RELEASED: break; } } } } /** * Externalizes the style sheet(s) for this session. Look up according style sheet file name in * org.wings.plaf.css.properties file under Stylesheet.BROWSERNAME. The style sheet is loaded from * the class path. * * @return a list of externalized browser specific stylesheet headers */ protected List<Header> getBrowserStylesheets() { Session session = SessionManager.getSession(); final CGManager cgManager = session.getCGManager(); final String browserName = session.getUserAgent().getBrowserType().getName().toLowerCase(); String cssClassPaths = (String) cgManager.getObject(PROPERTY_STYLESHEET + browserName, String.class); if (cssClassPaths == null) cssClassPaths = (String) cgManager.getObject(PROPERTY_STYLESHEET + BROWSER_DEFAULT, String.class); List<Header> browserStylesheets = new ArrayList<Header>(); StringTokenizer tokenizer = new StringTokenizer(cssClassPaths, ","); while (tokenizer.hasMoreTokens()) { browserStylesheets.add(Utils.createExternalizedCSSHeader(tokenizer.nextToken())); } return browserStylesheets; } /** * Uninstall renderer (i.e. other to apply other renderer). */ public void uninstallCG(final SComponent comp) { final SFrame component = (SFrame) comp; component.removeDynamicResource(ReloadResource.class); component.removeDynamicResource(UpdateResource.class); SessionHeaders.getInstance().deregisterHeaders(headers); } public void write(final Device device, final SComponent component) throws IOException { final SFrame frame = (SFrame) component; fullScreenAttributes(frame); String strokes = strokes(frame.getGlobalInputMapComponents()); if (strokes != null) component.getSession().getScriptManager() .addScriptListener(new JavaScriptListener(null, null, strokes)); if (!frame.isVisible()) return; else frame.fireRenderEvent(SComponent.START_RENDERING); Session session = SessionManager.getSession(); final String language = session.getLocale().getLanguage(); final String title = frame.getTitle(); final String encoding = session.getCharacterEncoding(); // <?xml version="1.0" encoding="..."> if (renderXmlDeclaration == null || renderXmlDeclaration) { device.print("<?xml version=\"1.0\" encoding=\""); Utils.write(device, encoding); device.print("\"?>\n"); } // <!DOCTYPE HTML PUBLIC ... > Utils.writeRaw(device, documentType); device.print("\n"); // <html> tag device.print( "<html onselectstart=\"if(window.event && window.event.ctrlKey == true) return false; else return true;\" xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\""); Utils.write(device, language); device.print("\" lang=\""); Utils.write(device, language); device.print("\">\n"); // <head> tag device.print("<head>"); if (title != null) { device.print("<title>"); Utils.write(device, title); device.print("</title>\n"); } // Character set encoding, the default is typically utf-8. device.print("<meta http-equiv=\"Content-type\" content=\"text/html; charset="); Utils.write(device, encoding); device.print("\"/>\n"); /* Insert version and compile time. Since the Version Class is generated on compile time, * build errors in SDK's are quite normal. Just run the Version.java ant task. */ device.print("<meta http-equiv=\"Generator\" content=\"wingS v"); device.print(Version.getVersion()); device.print(" (http://wingsframework.org) - built on: "); device.print(Version.getCompileTime()); device.print("\" />\n"); // Render all headers boolean isDebug = frame.isDebugJs(); for (Object next : frame.getHeaders()) { if (next instanceof Renderable) { try { Script[] debugHeaders; if (isDebug && (debugHeaders = Utils.getDebugHeaders(next)) != null) { // Render uncompressed headers for (Script debugHeader : debugHeaders) { if (debugHeader instanceof Renderable) { ((Renderable) debugHeader).write(device); } else { Utils.write(device, debugHeader.toString()); } } } else { // Render compressed headers ((Renderable) next).write(device); } } catch (ResourceNotFoundException e) { log.error("Unable to deliver inlined renderable", e); } } else { Utils.write(device, next.toString()); } device.print("\n"); } if (isDebug) { for (Renderable consoleHeader : Utils.getConsoleHeaders()) { consoleHeader.write(device); device.print("\n"); } } // Focus management. Put focus in selected object. if (frame.getFocus() != null) { String script = "wingS.util.requestFocus('" + frame.getFocus().getName() + "');"; ScriptManager.getInstance().addScriptListener(new OnPageRenderedScript(script)); } writeHeadExtension(device, frame); device.print("</head>\n"); device.print("<body"); Utils.writeEvents(device, frame, null); Utils.writeAllAttributes(device, frame); device.print(">\n"); // Write contents of the frame if (frame.isVisible()) { Utils.createExternalizedJSHeaderFromProperty(Utils.JS_ETC_WZ_TOOLTIP).write(device); device.print("\n"); // Write components frame.getLayout().write(device); // Write menus device.print("\n\n<div id=\"wings_menues\">\n"); Set<SComponent> menues = frame.getSession().getMenuManager().getMenues(frame); for (Iterator<SComponent> i = menues.iterator(); i.hasNext();) { SComponent menuItem = i.next(); menuItem.putClientProperty("popup", Boolean.TRUE); menuItem.write(device); menuItem.putClientProperty("popup", null); } device.print("\n</div>\n\n"); DragAndDropManager dndManager = frame.getSession().getDragAndDropManager(); dndManager.getCG().write(device, dndManager); if (frame.getSession().hasSDragAndDropManager()) { SDragAndDropManager sDndManager = frame.getSession().getSDragAndDropManager(); sDndManager.getCG().write(device, sDndManager); } SCursor cursor = frame.getSession().getCursor(); if (cursor != null) { CursorCG cg = (CursorCG) cursor.getCG(); if (cg == null) { System.out.println("cg is null!!"); } else { cg.write(device, cursor); } } handleScripts(device, frame); } wirteBodyExtension(device, frame); device.print("</body>\n</html>\n"); component.fireRenderEvent(SComponent.DONE_RENDERING); } private void fullScreenAttributes(SFrame frame) { Boolean fullScreenAttributesApplied = (Boolean) frame.getClientProperty("fullScreenAttributesApplied"); if (frame.isFullScreen() && !Boolean.TRUE.equals(fullScreenAttributesApplied)) { if (!Utils.isMSIE(frame)) { frame.getContentPane().setAttribute(CSSProperty.POSITION, "absolute"); frame.getContentPane().setAttribute(CSSProperty.HEIGHT, "100%"); frame.getContentPane().setAttribute(CSSProperty.WIDTH, "100%"); } frame.setAttribute(CSSProperty.POSITION, "absolute"); frame.setAttribute(CSSProperty.HEIGHT, "100%"); frame.setAttribute(CSSProperty.WIDTH, "100%"); frame.putClientProperty("fullScreenAttributesApplied", Boolean.TRUE); } else if (!frame.isFullScreen() && Boolean.TRUE.equals(fullScreenAttributesApplied)) { if (!Utils.isMSIE(frame)) { frame.getContentPane().setAttribute(CSSProperty.POSITION, null); frame.getContentPane().setAttribute(CSSProperty.HEIGHT, null); frame.getContentPane().setAttribute(CSSProperty.WIDTH, null); } frame.setAttribute(CSSProperty.POSITION, null); frame.setAttribute(CSSProperty.HEIGHT, null); frame.setAttribute(CSSProperty.WIDTH, null); frame.putClientProperty("fullScreenAttributesApplied", Boolean.FALSE); } } protected void handleScripts(Device device, SComponent component) throws IOException { final SFrame frame = (SFrame) component; final ScriptManager scriptManager = frame.getSession().getScriptManager(); final SToolTipManager tooltipManager = SToolTipManager.sharedInstance(); // hand script listeners of frame to script manager scriptManager.addScriptListeners(frame.getScriptListeners()); device.print("<script type=\"text/javascript\">\n"); // print all scripts writeGlobalInitScript(device, frame); device.print("\n"); writeTooltipInitScript(device, tooltipManager); device.print("\n"); ScriptListener[] scriptListeners = scriptManager.getScriptListeners(); for (int i = 0; i < scriptListeners.length; ++i) { if (scriptListeners[i].getScript() != null) { device.print(scriptListeners[i].getScript()).print("\n"); } } scriptManager.clearScriptListeners(); device.print("</script>\n"); } protected void writeHeadExtension(Device out, SFrame frame) throws IOException { // Hook for subclasses } protected void wirteBodyExtension(Device out, SFrame frame) throws IOException { // Hook for subclasses } private void writeGlobalInitScript(Device out, SFrame frame) throws IOException { Map<String, Object> initConfig = new HashMap<String, Object>(); initConfig.put("eventEpoch", frame.getEventEpoch()); initConfig.put("reloadResource", frame.getDynamicResource(ReloadResource.class).getURL().toString()); initConfig.put("updateResource", frame.getDynamicResource(UpdateResource.class).getURL().toString()); initConfig.put("updateEnabled", frame.isUpdateEnabled()); initConfig.put("updateCursor", Utils.mapToJsObject(frame.getUpdateCursor())); initConfig.put("autoAdjustLayout", Utils.mapToJsObject(frame.getAutoAdjustLayout())); initConfig.put("cometEnabled", frame.getSession().getComet() != null && frame.getSession().getComet().isCometEnabled()); final String logLevel = frame.getLogLevel(); if (logLevel != null && !"".equals(logLevel)) { initConfig.put("loglevel", logLevel); } out.print("wingS.global.init("); Utils.mapToJsObject(initConfig).write(out); out.print(");"); } private void writeTooltipInitScript(Device out, SToolTipManager tooltipManager) throws IOException { out.print("wingS.tooltip.init("); out.print(tooltipManager.getInitialDelay()).print(","); out.print(tooltipManager.getDismissDelay()).print(","); out.print(tooltipManager.isFollowMouse()).print(");"); } public String getDocumentType() { return documentType; } public void setDocumentType(String documentType) { this.documentType = documentType; } /** * @return The current rendered DOCTYPE of this document. {@link #STRICT_DOCTYPE} */ public Boolean getRenderXmlDeclaration() { return renderXmlDeclaration; } /** * Sets should the returned HTML page start with the <?xml version="1.0" encoding="...">. * This has effects which rendering mode the browsers will choose (quirks/strict) * * @param renderXmlDeclaration should the returned HTML page start with the <?xml version="1.0" encoding="...">. */ public void setRenderXmlDeclaration(Boolean renderXmlDeclaration) { this.renderXmlDeclaration = renderXmlDeclaration; } public Update getComponentUpdate(SComponent component) { return null; } public Update getAddHeaderUpdate(SFrame frame, int index, Object header) { if (header instanceof Script) return new HeaderScriptUpdate(frame, true, (Script) header, index); else if (header instanceof Link) return new HeaderLinkUpdate(frame, true, (Link) header, index); else return null; } public Update getAddHeaderUpdate(SFrame frame, Object header) { if (header instanceof Script) return new HeaderScriptUpdate(frame, true, (Script) header); else if (header instanceof Link) return new HeaderLinkUpdate(frame, true, (Link) header); else return null; } public Update getRemoveHeaderUpdate(SFrame frame, Object header) { if (header instanceof Script) // Removing script headers asynchronously would indeed // detach the according header, however, the functions // contained in the according files are not unloaded. // If unloading functions is desired, it might be a good // idea to RETURN 'NULL' here. This would create a // component update of the frame which in turn would // force a complete page reload and function unloading. return new HeaderScriptUpdate(frame, false, (Script) header); else if (header instanceof Link) return new HeaderLinkUpdate(frame, false, (Link) header); else return null; } public Update getEpochUpdate(SFrame frame, String epoch) { return new EpochUpdate(frame, epoch); } public Update getFocusUpdate(SFrame frame, SComponent focus) { return new FocusUpdate(frame, focus); } public Update getUpdateEnabledUpdate(SFrame frame, boolean enabled) { return new UpdateEnabledUpdate(frame, enabled); } public Update getAddWindowUpdate(SContainer container, SWindow window) { return new AddWindowUpdate(container, window); } public Update getRemoveWindowUpdate(SContainer container, SWindow window) { return new RemoveWindowUpdate(container, window); } protected class HeaderScriptUpdate extends AbstractUpdate<SFrame> { private Boolean add; private Script script; private Integer index; public HeaderScriptUpdate(SFrame frame, boolean add, Script script) { super(frame); this.add = add; this.script = script; } public HeaderScriptUpdate(SFrame frame, boolean add, Script script, int index) { this(frame, add, script); this.index = index; } public int getPriority() { return 5; } public Handler getHandler() { UpdateHandler handler = new UpdateHandler("headerScript"); handler.addParameter(add); handler.addParameter(script.getURL().toString()); handler.addParameter(script.getType()); if (index != null) handler.addParameter(index); return handler; } public boolean equals(Object object) { if (this == object) return true; if (!super.equals(object)) return false; if (!script.equals(((HeaderScriptUpdate) object).script)) return false; return true; } } protected class HeaderLinkUpdate extends AbstractUpdate<SFrame> { private Boolean add; private Link link; private Integer index; public HeaderLinkUpdate(SFrame frame, boolean add, Link link) { super(frame); this.add = add; this.link = link; } public HeaderLinkUpdate(SFrame frame, boolean add, Link link, int index) { this(frame, add, link); this.index = index; } public int getPriority() { return 5; } public Handler getHandler() { UpdateHandler handler = new UpdateHandler("headerLink"); handler.addParameter(add); handler.addParameter(link.getURL().toString()); handler.addParameter(link.getType()); if (link.getRel() != null || link.getRev() != null || link.getTarget() != null || index != null) handler.addParameter(link.getRel()); if (link.getRev() != null || link.getTarget() != null || index != null) handler.addParameter(link.getRev()); if (link.getTarget() != null || index != null) handler.addParameter(link.getTarget()); if (index != null) handler.addParameter(index); return handler; } public boolean equals(Object object) { if (this == object) return true; if (!super.equals(object)) return false; if (!link.equals(((HeaderLinkUpdate) object).link)) return false; return true; } } protected class EpochUpdate extends AbstractUpdate<SFrame> { private String epoch; public EpochUpdate(SFrame frame, String epoch) { super(frame); this.epoch = epoch; } public int getPriority() { return 0; } public Handler getHandler() { UpdateHandler handler = new UpdateHandler("epoch"); handler.addParameter(epoch); return handler; } } protected class FocusUpdate extends AbstractUpdate<SFrame> { private SComponent focus; public FocusUpdate(SFrame frame, SComponent focus) { super(frame); this.focus = focus; } public int getPriority() { return 0; } public Handler getHandler() { UpdateHandler handler = new UpdateHandler("focus"); handler.addParameter(focus.getName()); return handler; } } protected class UpdateEnabledUpdate extends AbstractUpdate<SFrame> { private Boolean enabled; public UpdateEnabledUpdate(SFrame frame, boolean enabled) { super(frame); this.enabled = Boolean.valueOf(enabled); } public Handler getHandler() { UpdateHandler handler = new UpdateHandler("updateEnabled"); handler.addParameter(enabled); return handler; } } protected class AddWindowUpdate extends AbstractUpdate<SContainer> { private SWindow window; public AddWindowUpdate(SContainer container, SWindow window) { super(container); this.window = window; } @Override public int getPriority() { return Integer.MAX_VALUE; } public Handler getHandler() { UpdateHandler handler = new UpdateHandler("addWindow"); handler.addParameter(component.getName()); handler.addParameter("<div id=\"" + window.getName() + "\"/>"); return handler; } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final AddWindowUpdate other = (AddWindowUpdate) obj; if (this.window != other.window && (this.window == null || !this.window.equals(other.window))) { return false; } return true; } @Override public int hashCode() { int hash = 7; hash = 19 * hash + (this.window != null ? this.window.hashCode() : 0); return hash; } } protected class RemoveWindowUpdate extends AbstractUpdate<SContainer> { private SWindow window; public RemoveWindowUpdate(final SContainer container, final SWindow window) { super(container); this.window = window; } public Handler getHandler() { UpdateHandler handler = new UpdateHandler("removeWindow"); handler.addParameter(window.getName()); return handler; } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final RemoveWindowUpdate other = (RemoveWindowUpdate) obj; if (this.window != other.window && (this.window == null || !this.window.equals(other.window))) { return false; } return true; } @Override public int hashCode() { int hash = 7; hash = 19 * hash + (this.window != null ? this.window.hashCode() : 0); return hash; } } }