001: /*
002: ItsNat Java Web Application Framework
003: Copyright (C) 2007 Innowhere Software Services S.L., Spanish Company
004: Author: Jose Maria Arranz Santamaria
005:
006: This program is free software: you can redistribute it and/or modify
007: it under the terms of the GNU Affero General Public License as published by
008: the Free Software Foundation, either version 3 of the License, or
009: (at your option) any later version. See the GNU Affero General Public
010: License for more details. See the copy of the GNU Affero General Public License
011: included in this program. If not, see <http://www.gnu.org/licenses/>.
012: */
013:
014: package org.itsnat.impl.comp;
015:
016: import org.itsnat.core.domutil.ItsNatDOMUtil;
017: import java.util.EventObject;
018: import javax.swing.CellEditor;
019: import javax.swing.event.CellEditorListener;
020: import javax.swing.event.ChangeEvent;
021: import org.itsnat.comp.ItsNatComponent;
022: import org.w3c.dom.Element;
023: import org.w3c.dom.Node;
024: import org.w3c.dom.events.Event;
025: import org.w3c.dom.events.EventListener;
026:
027: /**
028: *
029: * @author jmarranz
030: */
031: public abstract class EditorProcessorBase implements
032: CellEditorListener, EventListener {
033: protected CellEditor cellEditor;
034: protected Element cellElem;
035: protected Node children; // Si son varios es un DocumentFragment, puede ser null si no hay hijos
036: protected ItsNatElementComponentImpl compParent;
037: protected String editorActivatorEvent = "dblclick";
038: protected boolean editing = false;
039: protected boolean registeredActivatorEvent = false;
040:
041: /** Creates a new instance of EditorProcessorBase */
042: public EditorProcessorBase(ItsNatElementComponentImpl compParent) {
043: this .compParent = compParent;
044: }
045:
046: public void dispose() {
047: setCellEditor(null);
048: }
049:
050: public CellEditor getCellEditor() {
051: return cellEditor;
052: }
053:
054: public void setCellEditor(CellEditor cellEditor) {
055: if (this .cellEditor != null) {
056: this .cellEditor.removeCellEditorListener(this );
057: this .cellEditor = null;
058: }
059:
060: if (cellEditor != null) {
061: registerActivatorEvent();
062: cellEditor.addCellEditorListener(this );
063: } else
064: unregisterActivatorEvent();
065:
066: this .cellEditor = cellEditor;
067: }
068:
069: public void registerActivatorEvent() {
070: if (registeredActivatorEvent)
071: return; // ya registrado
072:
073: compParent.addEventListener(getEditorActivatorEvent(), this );
074:
075: this .registeredActivatorEvent = true;
076: }
077:
078: public void unregisterActivatorEvent() {
079: if (!registeredActivatorEvent)
080: return; // ya desregistrado
081:
082: compParent.removeEventListener(getEditorActivatorEvent(), this );
083:
084: this .registeredActivatorEvent = false;
085: }
086:
087: public void handleEvent(Event evt) {
088: startEdition(evt);
089: }
090:
091: public String getEditorActivatorEvent() {
092: return editorActivatorEvent;
093: }
094:
095: public void setEditorActivatorEvent(String editorActivatorEvent) {
096: CellEditor cellEditor = getCellEditor();
097:
098: setCellEditor(null);
099:
100: this .editorActivatorEvent = editorActivatorEvent;
101:
102: if (cellEditor != null)
103: setCellEditor(cellEditor); // restauramos para que se active con el nuevo tipo de evento
104: }
105:
106: public void editingStopped(ChangeEvent e) {
107: if (isEditing())
108: finalizeEdition(true);
109: }
110:
111: public void editingCanceled(ChangeEvent e) {
112: if (isEditing())
113: finalizeEdition(false);
114: }
115:
116: public boolean isEditing() {
117: //return (cellElem != null); // Si true hay una sesión activa
118: return editing;
119: }
120:
121: public void finalizeEdition(boolean acceptNewValue) {
122: // Reactivamos lo que desactivamos en afterShow()
123: registerActivatorEvent();
124:
125: ItsNatDOMUtil.removeAllChildren(cellElem); // Se quita el/los elemento/s editor/es, en teoría se detectará y automáticamente los demás listeners se quitan en el cliente
126: if (children != null)
127: cellElem.appendChild(children); // Restauramos el markup original antes de editar
128:
129: if (acceptNewValue) {
130: CellEditor cellEditor = getCellEditor();
131: Object value = cellEditor.getCellEditorValue();
132: try {
133: acceptNewValue(value);
134: } finally {
135: clearCurrentContext(); // para que quede bien se acepte o no el nuevo valor (podría ser vetado)
136: }
137: } else
138: clearCurrentContext();
139:
140: this .children = null;
141: this .cellElem = null;
142:
143: this .editing = false;
144: }
145:
146: public abstract void acceptNewValue(Object value);
147:
148: public abstract void clearCurrentContext();
149:
150: public void startEdition(Event evt) {
151: if (prepareEdition(evt))
152: openEditor(evt);
153: }
154:
155: public boolean prepareEdition(Event evt) {
156: // Finalizamos antes cualquier sesión pendiente
157: // Esto es necesario pues se ha comprobado que algunas
158: // veces no se genera el blur y se puede empezar a editar otro
159: // dejando a medias el uno. Esto ocurre sobre todo en el Internet Explorer
160: if (isEditing())
161: finalizeEdition(false);
162:
163: CellEditor cellEditor = getCellEditor();
164: return ((cellEditor != null) && cellEditor
165: .isCellEditable((EventObject) evt));
166: }
167:
168: public boolean prepareEdition() {
169: if (isEditing())
170: finalizeEdition(false);
171:
172: CellEditor cellEditor = getCellEditor();
173: return (cellEditor != null);
174: }
175:
176: public boolean isEditable() {
177: return (getCellEditor() != null);
178: }
179:
180: public void beforeShow(Element cellElem) {
181: this .cellElem = cellElem;
182: this .children = ItsNatDOMUtil.extractChildren(cellElem); // Devuelve un DocumentFragment si hay varios hijos , puede ser null (vacío)
183: }
184:
185: public void afterShow(ItsNatComponent compEditor) {
186: // Quitamos el evento para que al hacer doble click sobre el componente
187: // editor no suponga que al recibirlo el componente padre abra otro editor
188: unregisterActivatorEvent();
189:
190: //this.compEditor = compEditor;
191: this .editing = true;
192: }
193:
194: protected abstract void openEditor(Event evt);
195:
196: }
|