All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.zkoss.zk.ui.event.Events Maven / Gradle / Ivy

There is a newer version: 10.0.0-jakarta
Show newest version
/* Events.java

	Purpose:
		
	Description:
		
	History:
		Fri Jul 22 15:49:51     2005, Created by tomyeh

Copyright (C) 2005 Potix Corporation. All Rights Reserved.

{{IS_RIGHT
	This program is distributed under LGPL Version 2.1 in the hope that
	it will be useful, but WITHOUT ANY WARRANTY.
}}IS_RIGHT
*/
package org.zkoss.zk.ui.event;

import org.zkoss.zk.ui.Desktop;
import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Execution;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.UiException;
import org.zkoss.zk.ui.sys.ExecutionCtrl;
import org.zkoss.zk.ui.sys.DesktopCtrl;
import org.zkoss.zk.ui.sys.ComponentCtrl;
import org.zkoss.zk.ui.sys.ComponentsCtrl;
import org.zkoss.zk.ui.sys.EventProcessingThread;
import org.zkoss.zk.ui.impl.EventProcessor;
import org.zkoss.zk.au.out.AuEcho;
import org.zkoss.zk.ui.util.Clients;

/**
 * Utilities to handle events.
 *
 * @author tomyeh
 */
public class Events {
	private Events() {} //prevent from creation

	/** The onClick event (used with {@link MouseEvent}).
	 */
	public static final String ON_CLICK = "onClick";
	/** The onRightClick event (used with {@link MouseEvent}).
	 */
	public static final String ON_RIGHT_CLICK = "onRightClick";
	/** The onDoubleClick event (used with {@link MouseEvent}).
	 */
	public static final String ON_DOUBLE_CLICK = "onDoubleClick";
	/** The onMouseOver event (used with {@link MouseEvent}).
	 * 

Notice, if Internet connection is too far, the user might already move * the mouse out of a widget when the server receives onMouseOver. * @since 5.0.3 */ public static final String ON_MOUSE_OVER = "onMouseOver"; /** The onMouseOut event (used with {@link MouseEvent}). * @since 5.0.3 */ public static final String ON_MOUSE_OUT = "onMouseOut"; /** The onOK event (used with {@link KeyEvent}). */ public static final String ON_OK = "onOK"; /** The onCancel event (used with {@link KeyEvent}). */ public static final String ON_CANCEL = "onCancel"; /** The onCtrlKey event (used with {@link KeyEvent}). */ public static final String ON_CTRL_KEY = "onCtrlKey"; /** The onChange event (used with {@link InputEvent}). */ public static final String ON_CHANGE = "onChange"; /** The onChanging event (used with {@link InputEvent}). */ public static final String ON_CHANGING = "onChanging"; /** The onError event (used with {@link ErrorEvent}). */ public static final String ON_ERROR = "onError"; /** The onScroll event (used with {@link ScrollEvent}). */ public static final String ON_SCROLL = "onScroll"; /** The onScrolling event (used with {@link ScrollEvent}). */ public static final String ON_SCROLLING = "onScrolling"; /** The onSwipe event (used with {@link SwipeEvent}). * @since 6.5.0 */ public static final String ON_SWIPE = "onSwipe"; /** The onSelect event (used with {@link SelectEvent}). */ public static final String ON_SELECT = "onSelect"; /** The onSelection event (used with {@link SelectionEvent}). */ public static final String ON_SELECTION = "onSelection"; /** The onCheck event (used with {@link CheckEvent}). */ public static final String ON_CHECK = "onCheck"; /** The onMove event (used with {@link MoveEvent}). */ public static final String ON_MOVE = "onMove"; /** The onSize event (used with {@link SizeEvent}). */ public static final String ON_SIZE = "onSize"; /** The onAfterSize event (used with {@link AfterSizeEvent}). * @since 6.5.2 */ public static final String ON_AFTER_SIZE = "onAfterSize"; /** The onZIndex event (used with {@link ZIndexEvent}). */ public static final String ON_Z_INDEX = "onZIndex"; /** The onOpen event (used with {@link OpenEvent}). */ public static final String ON_OPEN = "onOpen"; /** The onClose event (used with {@link Event}) * used to denote the close button is pressed. */ public static final String ON_CLOSE = "onClose"; /** The onRender request. * There is no event associated with this AU request. */ public static final String ON_RENDER = "onRender"; /** The onTimer event (used with {@link Event}). * Sent when a timer is up. */ public static final String ON_TIMER = "onTimer"; /** The onFocus event (used with {@link Event}). * Sent when a component gets a focus. */ public static final String ON_FOCUS = "onFocus"; /** The onBlur event (used with {@link Event}). * Sent when a component loses a focus. */ public static final String ON_BLUR = "onBlur"; /** The onDrop event (used with {@link DropEvent}). * Sent when a component is dragged and drop to another. */ public static final String ON_DROP = "onDrop"; /** The onNotify event (used with {@link Event}). * It is not used by any component, but it is, rather, designed to * let users add customized events. */ public static final String ON_NOTIFY = "onNotify"; /** The onSort event (used with {@link Event}) * to notify a request for sorting. */ public static final String ON_SORT = "onSort"; /** The onGroup event (used with {@link Event}) * to notify a request for grouping. * @since 5.0.0 */ public static final String ON_GROUP = "onGroup"; /** The onUngroup event (used with {@link Event}) * to notify a request for ungrouping. * @since 6.5.0 */ public static final String ON_UNGROUP = "onUngroup"; /** The onUpload event (used with {@link UploadEvent}. */ public static final String ON_UPLOAD = "onUpload"; /** The onBookmarkChange event (used with {@link BookmarkEvent}) * to notify that user pressed BACK, FORWARD or specified URL directly * that causes the bookmark is changed (but still in the same desktop). *

All root components of all pages of the desktop will * receive this event. * @since 3.0.8 */ public static final String ON_BOOKMARK_CHANGE = "onBookmarkChange"; /** The onURIChange event (used with {@link URIEvent}) * to notify that the associated URI of a component is changed. * Currently only the iframe component supports this event. * @since 3.5.0 */ public static final String ON_URI_CHANGE = "onURIChange"; /** The onClientInfo event (used with {@link ClientInfoEvent}). */ public static final String ON_CLIENT_INFO = "onClientInfo"; /** The onVisibilityChange event (used with {@link VisibilityChangeEvent}). * Only for browsers that support HTML 5 Page Visibility API * @since 6.5.1 */ public static final String ON_VISIBILITY_CHANGE = "onVisibilityChange"; /** The onCreate event (used with {@link CreateEvent}) to notify a component * that it (and its children) has been created by ZK's evaluating a ZUML page. */ public static final String ON_CREATE = "onCreate"; /** The onModal event (used with {@link Event}) to notify a component * shall become modal. Currently, only ZUL's window components support it. *

Notice that it is not fired if the event thread is disabled (default). */ public static final String ON_MODAL = "onModal"; /** The onPiggyback event (used with {@link Event}) used to notify * a root component that the client has sent a request to the server. * It is meaningful only if it is registered to the root component. * Once registered, it is called * each time the client sends a request to the server. * The onPiggyback's event listener is processed after all other * events are processed. * *

The onPiggyback event is designed to let developers piggyback * the least-emergent UI updates to the client. * * @since 2.4.0 */ public static final String ON_PIGGYBACK = "onPiggyback"; /** The onUser event. It is a generic event that an application developer * might send from the client. ZK doesn't use this event. */ public static final String ON_USER = "onUser"; /** The onMinimize event (used with {@link MinimizeEvent}). * @since 3.5.0 */ public static final String ON_MINIMIZE = "onMinimize"; /** The onMaximize event (used with {@link MaximizeEvent}). * @since 3.5.0 */ public static final String ON_MAXIMIZE = "onMaximize"; /** The onFulfill event (used with {@link FulfillEvent}) * to denote a fulfill condition has been applied. * Developer usually listens to this event to process the * new created children. For example, you might invoke * {@link org.zkoss.zk.ui.Components#wireFellows} to process these new components. * @since 3.0.8 */ public static final String ON_FULFILL = "onFulfill"; /** The onStub event (used with {@link StubEvent}) * to denote an event sent from the peer widget of a stub component * (at the client). * @since 6.0.0 */ public static final String ON_STUB = "onStub"; /** The onDesktopRecycle event (used with {@link Event}) * to notify that a desktop has been recycled. * All top-level components will receive this event when * recycled. *

Refer to {@link org.zkoss.zk.ui.util.DesktopRecycle} for desktop * recycling. * @since 5.0.2 */ public static final String ON_DESKTOP_RECYCLE = "onDesktopRecycle"; /** Returns whether an event name is valid. * *

The event name must start with on and the third character * must be upper case. */ public static final boolean isValid(String name) { return name != null && name.length() > 2 && name.charAt(0) == 'o' && name.charAt(1) == 'n' && Character.isUpperCase(name.charAt(2)); } /** Returns whether the current thread is an event listener. */ public static final boolean inEventListener() { return EventProcessor.inEventListener(); } /** Returns whether an event handler or listener is available for * the specified component and event. * *

A event handler is either a public method named onXxx or * a ZUL attribute named onXxx, where onXxx is the event name. * A event listener is {@link EventListener} being added * by {@link Component#addEventListener} and {@link Page#addEventListener}. * *

Unlike {@link Component#isListenerAvailable}, which checks * only the event listener, this method * check both event handlers and listeners, i.e., * the onXxx members defined in ZUML, the onXxx method defined * in the implementation class, and the event listener registered. * * @param asap whether to check only non-deferrable listener, * i.e., not implementing {@link org.zkoss.zk.ui.event.Deferrable}, * or {@link org.zkoss.zk.ui.event.Deferrable#isDeferrable} is false. * @see org.zkoss.zk.ui.event.Deferrable * @see Component#isListenerAvailable */ public static boolean isListened(Component comp, String evtnm, boolean asap) { if (((ComponentCtrl)comp).getEventHandler(evtnm) != null) return true; if (ComponentsCtrl.getEventMethod(comp.getClass(), evtnm) != null || comp.isListenerAvailable(evtnm, asap)) return true; if (!asap) { final Page page = comp.getPage(); return page != null && page.isListenerAvailable(evtnm); } return false; } /** Sends the event to the specified component and process it * immediately. This method can only be called when processing an event. * It is OK to send event to component from another page as long as * they are in the same desktop. */ public static void sendEvent(Component comp, Event event) { final Execution exec = Executions.getCurrent(); final Desktop desktop = exec.getDesktop(); //note: we don't use comp.getDesktop because 1) it may be null //2) it may be different from the current desktop event = ((DesktopCtrl)desktop).beforeSendEvent(event); if (event == null) return; //done final Thread thd = Thread.currentThread(); if (!(thd instanceof EventProcessingThread)) { if (!desktop.getWebApp().getConfiguration().isEventThreadEnabled()) { final ExecutionCtrl execCtrl = (ExecutionCtrl)exec; final Page page = execCtrl.getCurrentPage(); final EventProcessor proc = new EventProcessor(desktop, comp, event); proc.setup(); try { proc.process(); } catch (Exception ex) { throw UiException.Aide.wrap(ex); } finally { execCtrl.setCurrentPage(page); } return; //done } throw new UiException("Callable only in the event listener"); } try { ((EventProcessingThread)thd).sendEvent(comp, event); } catch (Exception ex) { throw UiException.Aide.wrap(ex); } } /** Sends the event to the target specified in the event, and processes it immediately. * *

Note: {@link Event#getTarget} cannot be null. */ public static void sendEvent(Event event) { sendEvent(event.getTarget(), event); } /** Sends the event to the target, and processes it immediately. * @param target the target of the event (never null) * @since 5.0.4 */ public static void sendEvent(String name, Component target, Object data) { sendEvent(new Event(name, target, data)); } /** Posts an event to the current execution. * *

The priority of the event is assumed to be 0. Refer to * {@link #postEvent(int, Event)}. * *

On the other hand, the event sent by {@link #sendEvent} is processed * immediately without posting it to the queue. * *

Note: if the target of an event is not attached to * the page yet, the event is ignored silently. * @see #sendEvent * @see #echoEvent(String, Component, Object) * @see #postEvent(int, Event) */ public static final void postEvent(Event event) { Executions.getCurrent().postEvent(event); } /** Posts an instance of {@link Event} to the current execution. *

The priority of the event is assumed to be 0. Refer to * {@link #postEvent(int, String, Component, Object)}. * @see #postEvent(Event) * @see #postEvent(int, String, Component, Object) */ public static final void postEvent(String name, Component target, Object data) { postEvent(0, name, target, data); } /** Posts an event to the current execution with the specified priority. * *

The posted events are processed from the higher priority to the * lower one. If two events are posted with the same priority, * the earlier the event being posted is processed earlier * (first-in-first-out). * * @param priority the priority of the event. The higher the priority is, the earlier it * is handled.
* The priority posted by {@link #postEvent(Event)} is 0. * Applications shall not use the priority higher than 10,000 and * lower than -10,000 since they are reserved for component development. * @since 3.0.7 */ public static final void postEvent(int priority, Event event) { Executions.getCurrent().postEvent(priority, event); } /** Queues the give event for the specified target to this execution. * The target could be different from {@link Event#getTarget}. * @param priority the priority of the event. The default priority is 0 * and the higher value means higher priority. * @param realTarget the target component that will receive the event. * If null, it means broadcast, i.e., all root components will receive * this event. *
Notice that postEvent(n, event) is the same as postEvent(n, event.getTarget(), event), * but different from postEvent(n, 0, event). * @since 5.0.7 */ public static final void postEvent(int priority, Component realTarget, Event event) { Executions.getCurrent().postEvent(priority, realTarget, event); } /** Queues the give event for the specified target to this execution. * The target could be different from {@link Event#getTarget}. * @param realTarget the target component that will receive the event. * If null, it means broadcast, i.e., all root components will receive * this event. *
Notice that postEvent(n, event) is the same as postEvent(n, event.getTarget(), event), * but different from postEvent(n, 0, event). * @since 5.0.7 */ public static final void postEvent(Component realTarget, Event event) { Executions.getCurrent().postEvent(0, realTarget, event); } /** Posts an instance of {@link Event} to the current execution * with the specified priority. * *

The posted events are processed from the higher priority to the * lower one. If two events are posted with the same priority, * the earlier the event being posted is processed earlier * (first-in-first-out). * *

The priority posted by posted by {@link #postEvent(Event)} is * 0. * Applications shall not use the priority higher than 10,000 and * lower than -10,000 since they are reserved for component * development. * * @param priority the priority of the event. * @since 3.0.7 */ public static final void postEvent(int priority, String name, Component target, Object data) { if (name == null || name.length() == 0 || target == null) throw new IllegalArgumentException("Name is empty or target is null."); postEvent(priority, new Event(name, target, data)); } /** Echos an event. * By echo we mean the event is fired after the client receives the AU * responses and then echoes back. * In other words, the event won't be processed in the current execution. * Rather, it executes after the client receives the AU responses * and then echoes back the event back. * *

It is usually if you want to prompt the user before doing a long * operation. A typical case is to open a highlighted window to * prevent the user from clicking any button before the operation gets done. * *

It is the same as echoEvent(name, target, (Object)data). * * @since 3.0.2 * @see #sendEvent * @see #echoEvent(String, Component, Object) * @param name the event name, such as onSomething * @param target the component to receive the event (never null). * @param data the extra information, or null if not available. * It will become {@link Event#getData}. */ public static final void echoEvent(String name, Component target, String data) { echoEvent(name, target, (Object)data); } /** Echos an event. * By echo we mean the event is fired after the client receives the AU * responses and then echoes back. * In other words, the event won't be processed in the current execution. * Rather, it executes after the client receives the AU responses * and then echoes back the event back. * *

It is usually if you want to prompt the user before doing a long * operation. A typical case is to open a highlighted window to * prevent the user from clicking any button before the operation gets done. * * @since 5.0.4 * @see #sendEvent */ public static final void echoEvent(Event event) { echoEvent(event.getName(), event.getTarget(), event.getData()); } /** Echos an event. * By echo we mean the event is fired after the client receives the AU * responses and then echoes back. * In other words, the event won't be processed in the current execution. * Rather, it executes after the client receives the AU responses * and then echoes back the event back. * *

It is usually if you want to prompt the user before doing a long * operation. A typical case is to open a highlighted window to * prevent the user from clicking any button before the operation gets done. * * @since 5.0.4 * @see #sendEvent * @param name the event name, such as onSomething * @param target the component to receive the event (never null). * @param data the extra information, or null if not available. * It will become {@link Event#getData}. */ public static final void echoEvent(String name, Component target, Object data) { if (name == null || name.length() == 0 || target == null) throw new IllegalArgumentException("Name is empty or target is null."); Clients.response(new AuEcho(target, name, data)); } /**

Add onXxx event handler defined in controller object to the specified * component. * The controller is a POJO file with onXxx methods(the event handler codes). * This utility method registers these onXxx events to the specified * component so you don't have to implement and add {@link EventListener} * into the component one by one.

* *

All public methods whose names start with "on" in controller object * are considered * as event handlers and the corresponding event is listened. * For example, if the controller object has a method named onOK, * then the onOK event is listened and the onOK method is called * when the event is received. *

Since 3.0.8, this method treats ForwardEvent specially. If the * event argument going to be passed into the onXxx event listener is a * ForwardEvent and the onXxx event listener defined in the controller * specifies a specific event class as its parameter rather than generic * Event or ForwardEvent class, then this method will unwrap the * ForwardEvent automatically * (see {@link org.zkoss.zk.ui.event.ForwardEvent#getOrigin()}) * and pass the original forwarded event to the defined onXxx event listener.

*

This is a useful tool for MVC design practice. You can write * onXxx event handler codes in controller object and use this utility to * register the events to the specified component.

* * @param comp the component to be registered the events * @param controller a POJO file with onXxx methods(event handlers) * @since 3.0.6 * @see GenericEventListener */ public static final void addEventListeners(Component comp, final Object controller) { final GenericEventListener evtl = new GenericEventListener() { protected Object getController() { return controller; } }; evtl.bindComponent(comp); } /** Returns the real origin event of a forwarded event. * By real we mean the last non-forward event in the chain of * {@link ForwardEvent#getOrigin}. * Notice that a forward event might be forwarded again, so * {@link ForwardEvent#getOrigin} might not be the real origin. * @since 3.5.1 */ public static final Event getRealOrigin(ForwardEvent event) { for (;;) { Event evt = event.getOrigin(); if (!(evt instanceof ForwardEvent)) return evt; event = (ForwardEvent)evt; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy