/***************************************************
*
* cismet GmbH, Saarbruecken, Germany
*
* ... and it just works.
*
****************************************************/
/*
* AbstractSimpleEditor.java
*
* Created on 18. August 2004, 11:46
*/
package Sirius.navigator.ui.attributes.editor;
import org.apache.log4j.Logger;
import java.awt.*;
import java.awt.event.*;
import java.io.Serializable;
import java.util.*;
import java.util.EventObject;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import de.cismet.tools.gui.StaticSwingTools;
/**
* Die abstrakte Implementierung eines einfachen Editors.
*
* @author pascal
* @version $Revision$, $Date$
*/
public abstract class AbstractSimpleEditor extends JPanel implements SimpleEditor {
//~ Instance fields --------------------------------------------------------
/** Der Logger des Editors. */
protected Logger logger;
/** implementiert add- und removeComplexEditor Methoden. */
protected AbstractEditorActivationDelegate editorActivationDelegate = null;
/** implementiert show- und hideEditorUI Methoden. */
protected EditorUIDelegate editorUIDelegate = null;
/** true, wenn sich der Wert neu ist. */
protected boolean valueNew = false;
/** Lister der children des Editors. */
protected java.util.Map childrenMap;
/** parent Container dieses Editors. */
protected BasicContainer parentContainer = null;
/** Der Editor darf nur einmal initialisiert werden. */
protected boolean init = false;
/** Gibt an, ob seit dem Erzeugen dieses Editors sich ein Wert ge\u00E4ndert hat. */
// protected boolean changedSinceCreation = false;
// EditorEvent Kram ........................................................
protected transient ChangeEvent changeEvent = null;
protected EventListenerList listenerList;
// Properties ..............................................................
/** Eigenschaft f\u00FCr den Klassenenamen eines komplexen Editors. */
protected Class complexEditorClass = null;
/**
* Gibt an, ob dieser Editor nur zum Anzeigen verwendet werden soll, bzw. nur um einen komplexen Editor aufzurufen
*/
protected boolean readOnly = false;
/** Die eindeutige id des Editors. */
private Object id = null;
/** Der aktuelle Wert des Editors. */
private Object value = null;
/** true, wenn sich der Wert ge\u00E4ndert hat. */
private boolean valueChanged = false;
//~ Constructors -----------------------------------------------------------
/**
* Creates a new AbstractSimpleEditor object.
*/
public AbstractSimpleEditor() {
this.logger = Logger.getLogger(AbstractSimpleEditor.class);
this.childrenMap = new LinkedHashMap();
this.listenerList = new EventListenerList();
}
//~ Methods ----------------------------------------------------------------
// Basic Editor Methoden ....................................................
@Override
public Object getId() {
return this.id;
}
/**
* DOCUMENT ME!
*
* @param id DOCUMENT ME!
*/
protected void setId(final Object id) {
if (logger.isDebugEnabled()) {
logger.debug("setId(" + this + "): setting id of editor '" + id + "'"); // NOI18N
}
this.id = id;
}
// changed Methoden ........................................................
@Override
public boolean isValueChanged() {
return this.valueChanged;
}
@Override
public void setValueChanged(final boolean valueChanged) {
if (logger.isDebugEnabled()) {
logger.debug("setValueChanged(" + this.getId() + ") " + valueChanged); // NOI18N
}
this.valueChanged = valueChanged;
}
@Override
public boolean isValueNew() {
return this.valueNew;
}
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
/**
* Gibt das bearbeitete Objekt zur\u00FCck, das eine Kopie (falls m\u00F6glich / n\u00F6tig) des urspr\u00FCglichen
* Objekts ist.
*
* <p>Diese Methode wird normalerweise von einem Listener des Parent Containers dieses Editors aufgerufen, nachdem
* dieser Editor stopEditing() aufgerufen hat.</p>
*
* @return der ver\u00E4nderte Wert
*
* @see setValue()
*/
@Override
public Object getValue() {
return this.value;
}
/**
* Setzt den Wert, den der Editor darstellen soll.
*
* <p>Es ist wird dringend empfohlen, den Wert zu kopieren, da sonst ein undo mit cancelEditing nicht m\u00F6glich
* ist.</p>
*
* @param value der neue Wert
*
* @see CloneHelper
*/
protected void setValue(final Object value) {
this.value = value;
}
// UI Methoden .............................................................
/**
* Initialisiert das UI dieses Editors.
*
* <p>Hier wird z.B. die initComponents() Methode des NetBeans FormsEditors aufgerufen.</p>
*/
protected abstract void initUI();
/*{
* this.initComponents();}*/
/**
* Setzt den Wert im Editor UI.
*
* @param value der Wert, der im Editor UI gesetzt wird.
*/
protected abstract void setComponentValue(Object value);
/*{
* this.textField.setText(value.toString();}*/
/**
* Liefert den Wert, der im Editor UI gesetzt wurde.
*
* @return der Wert, der im Editor UI gesetzt wurde.
*/
protected abstract Object getComponentValue();
/*{
* if(((JTextField)this.componentDelegate).getText() != null) { return this.textField.getText(); }}*/
// EditorComponent Methoden ................................................
/**
* Das wird vom editorUIDelegate erledigt.
*
* @return DOCUMENT ME!
*/
@Override
public Component getComponent() {
return this.editorUIDelegate.getComponent();
}
@Override
public Component getEditorComponent(final BasicContainer parentContainer,
final ComplexEditor complexChildEditor,
final Object id,
final Object value) {
if (logger.isDebugEnabled()) {
if (complexChildEditor != null) {
if (logger.isDebugEnabled()) {
logger.debug("getEditorComponent(" + this + "): initializing simple editor component for value '"
+ id + "' with complex child editor support"); // NOI18N
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("getEditorComponent(" + this + "): initializing simple editor component for value '"
+ id + "' without complex child editor support"); // NOI18N
}
}
}
// neuen Wert kopieren!
if (value != null) {
try {
if (logger.isDebugEnabled()) {
logger.debug("getEditorComponent(" + this + "): cloning & setting new value: '"
+ ((value != null) ? value.toString() : "null") + "'"); // NOI18N
}
this.setValue(Sirius.navigator.tools.CloneHelper.clone(value));
} catch (Throwable t) {
if (logger.isDebugEnabled()) {
logger.warn("getEditorComponent(" + this + "): cloning not sucessfull", t); // NOI18N
}
this.setValue(value);
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("getEditorComponent(" + this + "): value is null"); // NOI18N
}
this.setValue(null);
}
// assing new id
this.setId(id);
// parent container zuweisen
this.parentContainer = parentContainer;
// init user interface
this.initUI();
// prepare complex child editor
if (complexChildEditor != null) {
this.addComplexEditor(complexChildEditor);
}
// show new value in UI
this.setValueChanged(false);
this.setComponentValue(this.getValue());
this.init = true;
return this;
}
@Override
public Component getEditorComponent(final BasicContainer parentContainer, final Object id, final Object value) {
return this.getEditorComponent(parentContainer, null, id, value);
}
/**
* Gibt an, ob dieser Editor bereit ist, ein Objekt zu bearbeiten.
*
* <p>Die Methode getSimpleEditorComponent() sollte vom Container dieses Editors nur dann aufgerufen werden, wenn
* diese MEtohde true zur\u00FCckliefert.</p>
*
* @param anEvent Anhand dieses events kann die Bereitschaft definiert werden (MouseEvent: Doppelclick, etc.)
*
* @return true, falls dieser Editor bereit ist
*
* @see getSimpleEditorComponent()
*/
@Override
public abstract boolean isEditable(java.util.EventObject anEvent);
@Override
public void uiChanged() {
if (this.getParentContainer() != null) {
this.parentContainer.uiChanged();
} else {
if (logger.isDebugEnabled()) {
logger.debug("isEditable(" + this + "): this is the root container, fire uiChanged()"); // NOI18N
}
this.fireUIChanged();
}
}
// Edit Methoden ..........................................................
/**
* Bricht den Bearbeitungsvorgang ab.
*/
@Override
public void cancelEditing() {
if (logger.isDebugEnabled()) {
logger.debug("cancelEditing(" + this.getId() + ")"); // NOI18N
}
if (this.getChildEditors().size() != 0) {
if (logger.isDebugEnabled()) {
logger.debug("cancelEditing(" + this.getId() + "): calling cancelEditing() on children of this editor ("
+ this.getId() + ")"); // NOI18N
}
final Iterator iterator = this.getChildEditors().values().iterator();
while (iterator.hasNext()) {
((BasicEditor)iterator.next()).cancelEditing();
}
}
if ((this.editorActivationDelegate != null) && this.editorActivationDelegate.isChildEditorVisible()) {
logger.warn("cancelEditing(" + this.getId() + "): child editor still visible"); // NOI18N
this.editorActivationDelegate.hideComplexEditorChildComponentUI();
}
this.fireEditingCanceled();
}
/**
* Diese Methode *mu\u00DF* \u00FCberschrieben werden, um den neuen Wert im Editor UI dem alten Wert im Editor
* zuzuweisen.<pd> Der R\u00FCckgabewert dieser Methode kann durchaus false sein, obwohl sich der Wert eines child
* Editos ge\u00E4ndert hat. Das h\u00E4ngt mit der synchronen Event- Verarbeitung zusammen.
*
* @return true, wenn die Zuweisung erfolgreich war (hinweis beachten).
*/
@Override
public boolean stopEditing() {
if (logger.isDebugEnabled()) {
logger.debug("stopEditing(" + this.getId() + ")"); // NOI18N
}
if (this.getChildEditors().size() != 0) {
if (logger.isDebugEnabled()) {
logger.debug("stopEditing(" + this.getId() + "): calling stopEditing() on children of this editor ("
+ this.getId() + ")"); // NOI18N
}
final Iterator iterator = this.getChildEditors().values().iterator();
while (iterator.hasNext()) {
// hier wird nur ein Event ausgel\u00F6st, alles weitere l\u00E4uft dann
// im EditorListener ab, der an diesem Objekt registriert ist.
((BasicEditor)iterator.next()).stopEditing();
}
}
if ((this.editorActivationDelegate != null) && this.editorActivationDelegate.isChildEditorVisible()) {
if (logger.isDebugEnabled()) {
logger.warn("stopEditing(" + this.getId() + "): child editor still visible, hiding child editor"); // NOI18N
}
this.editorActivationDelegate.hideComplexEditorChildComponentUI();
}
// Der Wert wurde nicht durch einen child editor ver\u00E4ndert
// XXX was ist, wenn der komplexe Editor nicht modal ist?
/*if(this.valueChanged && this.getChildEditors().size() == 0)
* { if(logger.isDebugEnabled())logger.debug("stopEditing(" + this.getId() + "): value changed, setting new
* value"); Object newValue = this.getComponentValue(); this.setValue(newValue); this.valueChanged = true; }
* else if(logger.isDebugEnabled()) { logger.debug("stopEditing(" + this.getId() + "): this object value not
* changed directly, ignoring new value");}*/
if (this.valueChanged) {
if (logger.isDebugEnabled()) {
logger.debug("stopEditing(" + this.getId() + "): value changed, setting new value"); // NOI18N
}
final Object newValue = this.getComponentValue();
this.setValue(newValue);
} else if (logger.isDebugEnabled()) {
logger.debug("stopEditing(" + this.getId() + "): object value not changed"); // NOI18N
}
this.fireEditingStopped();
//
return this.valueChanged;
}
// Properties ..............................................................
/**
* Diese Implementierung gibt nur die Eigenschaft 'PROPERTY_LOCALE' und 'PROPERTY_COMLPEX_EDTIOR' zur\u00FCck.
*
* @param key PROPERTY_LOCALE
*
* @return Ein locale Objekt, oder null
*/
@Override
public Object getProperty(final String key) {
/*if(key.equalsIgnoreCase(PROPERTY_LOCALE) && this.resources != null)
* { return this.resources.getLocale();}*/
if (key.equalsIgnoreCase(PROPERTY_COMLPEX_EDTIOR)) {
return this.complexEditorClass;
} else if (key.equalsIgnoreCase(PROPERTY_READ_ONLY)) {
return new Boolean(this.readOnly);
} else {
return null;
}
}
/**
* Diese Implementierung setzt nur die Eigenschaften 'PROPERTY_LOCALE', 'PROPERTY_COMLPEX_EDTIOR' und
* 'PROPERTY_READ_ONLY'.
*
* <p>value mu\u00DF ein Objekt vom Type java.util.Locale oder jaca.langClass sein. Es wird ein entsprechendes
* ResourceBundle f\u00FCr internationalisierte Strings dieses Editors gesucht.</p>
*
* @param key PROPERTY_LOCALE, PROPERTY_COMLPEX_EDTIOR, PROPERTY_READ_ONLY
* @param value Ein entsprechndes Objekt
*
* @return DOCUMENT ME!
*/
@Override
public boolean setProperty(final String key, final Object value) {
/*if(key.equalsIgnoreCase(PROPERTY_LOCALE) && value instanceof Locale)
* { try { this.resources = ResourceBundle.getBundle(this.getClass().getName(), (Locale)value); return
* true; } catch(Throwable t) { logger.error("setProperty(" + this.getId() + "): could not load resource
* bundle for locale '" + value.toString() + "'", t); }}*/
if (key.equalsIgnoreCase(PROPERTY_COMLPEX_EDTIOR) && (value instanceof Class)) {
this.complexEditorClass = (Class)value;
return true;
} else if (key.equalsIgnoreCase(PROPERTY_READ_ONLY) && (value instanceof Boolean)) {
this.readOnly = ((Boolean)value).booleanValue();
return true;
}
return false;
}
// Editor Listener Methods .................................................
/**
* Adds a <code>CellEditorListener</code> to the listener list.
*
* @param l the new listener to be added
*/
@Override
public void addEditorListener(final EditorListener l) {
if (logger.isDebugEnabled()) {
logger.debug("addEditorListener(" + this + ") called"); // NOI18N
}
listenerList.add(EditorListener.class, l);
}
/**
* Removes a <code>EditorListener</code> from the listener list.
*
* @param l the listener to be removed
*/
@Override
public void removeEditorListener(final EditorListener l) {
if (logger.isDebugEnabled()) {
logger.debug("removeEditorListener(" + this + ") called"); // NOI18N
}
listenerList.remove(EditorListener.class, l);
}
/**
* Returns an array of all the <code>EditorListener</code>s added to this AbstractEditor with addEditorListener().
*
* @return all of the <code>EditorListener</code>s added or an empty array if no listeners have been added
*
* @since 1.4
*/
public EditorListener[] getEditorListeners() {
return (EditorListener[])listenerList.getListeners(
EditorListener.class);
}
/**
* Notifies all listeners that have registered interest for notification on this event type. The event instance is
* created lazily.
*
* @see EventListenerList
*/
protected void fireEditingStopped() {
// Guaranteed to return a non-null array
final Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == EditorListener.class) {
// Lazily create the event:
if (changeEvent == null) {
changeEvent = new ChangeEvent(this);
}
((EditorListener)listeners[i + 1]).editingStopped(changeEvent);
}
}
}
/**
* Notifies all listeners that have registered interest for notification on this event type. The event instance is
* created lazily.
*
* @see EventListenerList
*/
protected void fireUIChanged() {
// Guaranteed to return a non-null array
final Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == EditorListener.class) {
// Lazily create the event:
if (changeEvent == null) {
changeEvent = new ChangeEvent(this);
}
((EditorListener)listeners[i + 1]).uiChanged(changeEvent);
}
}
}
/**
* Notifies all listeners that have registered interest for notification on this event type. The event instance is
* created lazily.
*
* @see EventListenerList
*/
protected void fireEditingCanceled() {
// Guaranteed to return a non-null array
final Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == EditorListener.class) {
// Lazily create the event:
if (changeEvent == null) {
changeEvent = new ChangeEvent(this);
}
((EditorListener)listeners[i + 1]).editingCanceled(changeEvent);
}
}
}
// BasicContainer Methoden ................................................
@Override
public boolean addComplexEditor(final ComplexEditor complexEditor) {
if (this.editorActivationDelegate.isChildEditorVisible()) {
logger.warn("addComplexEditor(" + this.getId() + "): complex child editor still visible"); // NOI18N
this.editorActivationDelegate.getChildEditor().cancelEditing();
this.editorActivationDelegate.hideComplexEditorChildComponentUI();
}
if (this.editorActivationDelegate.isChildEditorRegistered()) {
if (this.editorActivationDelegate.getChildEditor() != complexEditor) {
this.editorActivationDelegate.getChildEditor().cancelEditing();
logger.warn("addComplexEditor(" + this.getId() + "): another complex child editor is still registered"); // NOI18N
this.editorActivationDelegate.removeComplexEditor();
return this.editorActivationDelegate.addComplexEditor(complexEditor);
} else if (logger.isDebugEnabled()) {
logger.warn("addComplexEditor(" + this.getId() + "): this complex child editor is already registered"); // NOI18N
return false;
}
} else {
return this.editorActivationDelegate.addComplexEditor(complexEditor);
}
return false;
}
@Override
public boolean removeComplexEditor(final ComplexEditor complexEditor) {
if (this.editorActivationDelegate != null) {
if (this.editorActivationDelegate.isChildEditorVisible()) {
logger.warn("removeComplexEditor(" + this.getId() + "): complex child editor still visible"); // NOI18N
this.editorActivationDelegate.hideComplexEditorChildComponentUI();
}
return this.editorActivationDelegate.removeComplexEditor(complexEditor);
} else {
logger.error("removeComplexEditor(" + this.getId() + "): this.editorActivationDelegate not initialized"); // NOI18N
return false;
}
}
@Override
public boolean showComplexEditorComponentUI(final Component complexChildEditorComponent,
final Object complexChildEditorId) {
if (this.editorUIDelegate != null) {
return this.editorUIDelegate.showComplexEditorComponentUI(
complexChildEditorComponent,
complexChildEditorId);
} else {
logger.error("showComplexEditorComponentUI(" + this.getId() + "): this.editorUIDelegate not initialized"); // NOI18N
return false;
}
}
@Override
public boolean hideComplexEditorComponentUI(final Component complexChildEditorComponent,
final Object complexChildEditorId) {
if (this.editorUIDelegate != null) {
return this.editorUIDelegate.hideComplexEditorComponentUI(
complexChildEditorComponent,
complexChildEditorId);
} else {
logger.error("hideComplexEditorComponentUI(" + this.getId() + "): this.editorUIDelegate not initialized"); // NOI18N
return false;
}
}
@Override
public BasicContainer getParentContainer() {
return this.parentContainer;
}
@Override
public java.util.Map getChildEditors() {
return this.childrenMap;
}
// child editor Methoden ...................................................
@Override
public java.util.LinkedList getActiveChildEditorTree(java.util.LinkedList activeChildEditorTree) {
if (activeChildEditorTree == null) {
if (this.getParentContainer() != null) {
logger.error("getActiveChildEditorTree(" + this.getId()
+ "): activeChildEditorTree should not be null this parent container is not null)"); // NOI18N
}
activeChildEditorTree = new LinkedList();
}
// nur bei komplexen Editoren!
// activeChildEditorTree.addLast(this.getId());
final Object activeChildEditorId = this.getActiveChildEditorId();
if (activeChildEditorId != null) {
if (logger.isDebugEnabled()) {
logger.debug("getActiveChildEditorTree(" + this.getId() + "): no child editor in this editor'"
+ this.getId() + "' found"); // NOI18N
}
if (this.getChildEditors().containsKey(activeChildEditorId)) {
if (logger.isDebugEnabled()) {
logger.debug("getActiveChildEditorTree(" + this.getId() + "): child editor '" + activeChildEditorId
+ "' found in this editor '" + this.getId() + "'"); // NOI18N
}
final BasicContainer activeChildEditor = (BasicContainer)this.getChildEditors()
.get(activeChildEditorId);
return activeChildEditor.getActiveChildEditorTree(activeChildEditorTree);
} else {
logger.error("getActiveChildEditorTree(" + this.getId()
+ "): active child editor not found in list of this child editors"); // NOI18N
}
} else if (logger.isDebugEnabled()) {
logger.debug("getActiveChildEditorTree(" + this.getId() + "): no active child editor in '" + this.getId()
+ "'"); // NOI18N
}
return activeChildEditorTree;
}
@Override
public boolean setActiveChildEditorTree(final java.util.LinkedList activeChildEditorTree) {
if (activeChildEditorTree.size() > 0) {
final Object newActiveChildEditorId = activeChildEditorTree.getFirst();
if (this.getChildEditors().containsKey(newActiveChildEditorId)) {
if (logger.isDebugEnabled()) {
logger.debug("setActiveChildEditorTree(" + this + "): new active child editor '"
+ newActiveChildEditorId + "' is a registered child of this editor"); // NOI18N
}
final Object oldActiveChildEditorId = this.getActiveChildEditorId();
if (oldActiveChildEditorId != null) {
if (logger.isDebugEnabled()) {
logger.debug("setActiveChildEditorTree(" + this
+ "): there is still an old active child editor '" + oldActiveChildEditorId
+ " registered"); // NOI18N
}
if (this.getChildEditors().containsKey(oldActiveChildEditorId)) {
if (logger.isDebugEnabled()) {
logger.debug("setActiveChildEditorTree(" + this + "): old active (visible) child editor '"
+ oldActiveChildEditorId + "' is a registered child of this editor"); // NOI18N
}
final BasicEditor oldActiveChildEditor = (BasicEditor)this.getChildEditors()
.get(oldActiveChildEditorId);
if (oldActiveChildEditorId.equals(newActiveChildEditorId)) {
if (logger.isDebugEnabled()) {
logger.debug("setActiveChildEditorTree(" + this + "): new active child editor '"
+ newActiveChildEditorId
+ " is the active (visible) child of this editor!"); // NOI18N
}
return oldActiveChildEditor.setActiveChildEditorTree(activeChildEditorTree);
} else {
// oder cancel?
if (logger.isDebugEnabled()) {
logger.debug("setActiveChildEditorTree(" + this + "): new active child editor '"
+ newActiveChildEditorId
+ " is NOT the active (visible) child of this editor, removing old editor ("
+ oldActiveChildEditorId + ")"); // NOI18N
}
oldActiveChildEditor.stopEditing();
}
} else {
logger.error("setActiveChildEditorTree(" + this + "): old active child editor '"
+ oldActiveChildEditorId + "' not found in list of this child editors"); // NOI18N
}
} else if (logger.isDebugEnabled()) {
logger.debug("setActiveChildEditorTree(" + this
+ "): there is NO old active child editor registered"); // NOI18N
}
final BasicEditor newActiveChildEditor = (BasicEditor)this.getChildEditors()
.get(newActiveChildEditorId);
if (ComplexEditor.class.isAssignableFrom(newActiveChildEditor.getClass())) {
if (logger.isDebugEnabled()) {
logger.debug("setActiveChildEditorTree(" + this + "): adding new active child editor '"
+ newActiveChildEditorId + "' to this container"); // NOI18N
}
this.addComplexEditor((ComplexEditor)newActiveChildEditor);
} else if (logger.isDebugEnabled()) {
logger.debug("setActiveChildEditorTree(" + this + "): new active child editor '"
+ newActiveChildEditorId + "' is no complex editor"); // NOI18N
}
if (activeChildEditorTree.size() > 0) {
return newActiveChildEditor.setActiveChildEditorTree(activeChildEditorTree);
} else {
if (logger.isDebugEnabled()) {
logger.debug("setActiveChildEditorTree(" + this + "): this editor(" + this
+ ") is the leaf editor"); // NOI18N
}
return true;
}
} else if (this.editorActivationDelegate.lazyChildEditor != null) {
if (logger.isDebugEnabled()) {
logger.debug("setActiveChildEditorTree(" + this + "): new active child editor '"
+ newActiveChildEditorId
+ "' is not yet registered with this editor, but is a lazy editor. Showing the UI now"); // NOI18N
}
this.editorActivationDelegate.showComplexEditorChildComponentUI();
if (this.editorActivationDelegate.getChildEditor().getId().equals(newActiveChildEditorId)) {
if (logger.isDebugEnabled()) {
logger.debug("setActiveChildEditorTree(" + this + "): new active child editor '"
+ newActiveChildEditorId + " is NOW the active (visible) child of this editor!"); // NOI18N
}
if (activeChildEditorTree.size() > 0) {
return this.editorActivationDelegate.getChildEditor()
.setActiveChildEditorTree(activeChildEditorTree);
} else {
if (logger.isDebugEnabled()) {
logger.debug("setActiveChildEditorTree(" + this + "): this editor(" + this
+ ") is the leaf editor"); // NOI18N
}
return true;
}
} else {
logger.fatal("setActiveChildEditorTree(" + this + "): what a mess: lazy child editor id '"
+ this.editorActivationDelegate.getChildEditor().getId()
+ " does not match new child editor id '" + newActiveChildEditorId + "'"); // NOI18N
}
} else {
logger.error("setActiveChildEditorTree(" + this + "): new active child editor '"
+ newActiveChildEditorId + "' not found in this editor (" + this + ")"); // NOI18N
/*if(logger.isDebugEnabled())
* { Iterator iterator = this.getChildEditors().keySet().iterator(); while(iterator.hasNext()) {
* logger.debug("setActiveChildEditorTree(" + this + "): " + iterator.next()); }}*/
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("setActiveChildEditorTree(" + this + "): this editor (" + this
+ ") must be the is the leaf editor"); // NOI18N
}
final Object oldActiveChildEditorId = this.getActiveChildEditorId();
if (oldActiveChildEditorId != null) {
if (logger.isDebugEnabled()) {
logger.debug("setActiveChildEditorTree(" + this + "): there is still an old active child editor '"
+ oldActiveChildEditorId + " registered"); // NOI18N
}
if (this.getChildEditors().containsKey(oldActiveChildEditorId)) {
if (logger.isDebugEnabled()) {
logger.debug("setActiveChildEditorTree(" + this + "): old active (visible) child editor '"
+ oldActiveChildEditorId
+ "' is a registered child of this editor, removing old editor"); // NOI18N
}
final BasicEditor oldActiveChildEditor = (BasicEditor)this.getChildEditors()
.get(oldActiveChildEditorId);
// XXX oder cancel?
oldActiveChildEditor.stopEditing();
return true;
} else {
logger.error("setActiveChildEditorTree(" + this + "): old active child editor '"
+ oldActiveChildEditorId + "' not found in list of this child editors"); // NOI18N
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("setActiveChildEditorTree(" + this + "): this editor (" + this
+ ") IS the is the leaf editor!"); // NOI18N
}
return true;
}
}
return false;
}
@Override
public Object getActiveChildEditorId() {
return this.editorUIDelegate.getActiveChildEditorId();
}
// TableEditor Methoden ....................................................
@Override
public java.awt.Component getTableCellEditorComponent(final JTable table,
final Object value,
final boolean isSelected,
final int row,
final int column) {
logger.error("getTableCellEditorComponent(" + this.getId()
+ "): getTableCellEditorComponent should never be called"); // NOI18N
return new JLabel(org.openide.util.NbBundle.getMessage(
AbstractSimpleEditor.class,
"AbstractSimpleEditor.getTableCellEditorComponent.JLabel.text")); // NOI18N
}
@Override
public boolean stopCellEditing() {
return this.stopEditing();
}
@Override
public void cancelCellEditing() {
this.cancelEditing();
}
@Override
public void addCellEditorListener(final javax.swing.event.CellEditorListener l) {
if (l instanceof EditorListener) {
this.addEditorListener((EditorListener)l);
} else {
logger.warn("addCellEditorListener(" + this.getId() + "): listener not of type 'EditorListener'"); // NOI18N
}
}
@Override
public void removeCellEditorListener(final javax.swing.event.CellEditorListener l) {
if (l instanceof EditorListener) {
this.removeEditorListener((EditorListener)l);
} else {
logger.warn("removeCellEditorListener(" + this.getId() + "): listener not of type 'EditorListener'"); // NOI18N
}
}
@Override
public boolean shouldSelectCell(final java.util.EventObject anEvent) {
return true;
}
@Override
public boolean isCellEditable(final java.util.EventObject anEvent) {
return this.isEditable(anEvent);
}
@Override
public Object getCellEditorValue() {
return this.getValue();
}
// Hilfsklassen ============================================================
/**
* Adds a PropertyChangeListener to the listener list.
*
* @param l The listener to add.
*/
@Override
public void addPropertyChangeListener(final java.beans.PropertyChangeListener l) {
this.editorActivationDelegate.addPropertyChangeListener(l);
}
/**
* Removes a PropertyChangeListener from the listener list.
*
* @param l The listener to remove.
*/
@Override
public void removePropertyChangeListener(final java.beans.PropertyChangeListener l) {
this.editorActivationDelegate.removePropertyChangeListener(l);
}
// -------------------------------------------------------------------------
@Override
public String toString() {
return (this.getId() != null) ? this.getId().toString() : null;
}
//~ Inner Classes ----------------------------------------------------------
/**
* Standardimplementierung eines.
*
* @version $Revision$, $Date$
*/
protected class SimpleEditorActivationDelegate extends AbstractEditorActivationDelegate {
//~ Constructors -------------------------------------------------------
/**
* Creates a new instance of ComplexEditorActivator.
*/
public SimpleEditorActivationDelegate() {
this.logger = Logger.getLogger(this.getClass());
this.thisEditor = AbstractSimpleEditor.this;
this.thisContainer = AbstractSimpleEditor.this;
this.propertyChangeSupport = new SwingPropertyChangeSupport(AbstractSimpleEditor.this);
}
//~ Methods ------------------------------------------------------------
@Override
protected EditorListener createEditorListener() {
return new SimpleEditorHandler();
}
/**
* einfacher Editor -> parent container.
*
* @return DOCUMENT ME!
*/
@Override
protected BasicContainer getParentContainerForUI() {
return this.thisContainer.getParentContainer();
}
}
// -------------------------------------------------------------------------
/**
* Rudiment\u00E4re Dialogbox zum Anzeigen eines komplexen Editors (child) in einem simplen Editor (this).
*
* <p>Normalerweise sollte das UI eines komplexen Editors, der aus einem einfachen Editor heraus aufgerufen wird, im
* UI des parent Containers des simplen Editors angezeigt werden.<br>
* Diese Hilfsklasse erm\u00F6glicht es, das UI eines komplexen Editor mit Hilfe einer Dialogbox 'im' simplen Editor
* anzuzeigen.</p>
*
* @version $Revision$, $Date$
*/
protected class SimpleEditorUIDelegate extends JDialog implements EditorUIDelegate {
//~ Instance fields ----------------------------------------------------
protected Object complexChildEditorId = null;
Logger logger = Logger.getLogger(SimpleEditorUIDelegate.class);
//~ Constructors -------------------------------------------------------
/**
* Creates a new SimpleEditorUIDelegate object.
*/
public SimpleEditorUIDelegate() {
}
//~ Methods ------------------------------------------------------------
@Override
public boolean showComplexEditorComponentUI(final Component complexChildEditorComponent,
final Object complexChildEditorId) {
if ((this.complexChildEditorId == null) && (this.getContentPane() == null)) {
if ((complexChildEditorComponent != null) && (complexChildEditorId != null)) {
if ((AbstractSimpleEditor.this.editorActivationDelegate != null)
&& (AbstractSimpleEditor.this.editorActivationDelegate.getChildEditor() != null)) {
if (logger.isDebugEnabled()) {
logger.debug("showComplexEditorComponentUI(" + AbstractSimpleEditor.this.getId()
+ "): showing complex editor UI '"
+ complexChildEditorComponent.getClass().getName() + "' ("
+ complexChildEditorId + ") in simple editor UI"); // NOI18N
}
this.setModal(true);
this.setName(AbstractSimpleEditor.this.editorActivationDelegate.getChildEditor().getId()
.toString());
this.complexChildEditorId = complexChildEditorId;
// XXX \u00DCberpr\u00FCfung ...
this.setContentPane((JComponent)complexChildEditorComponent);
this.pack();
StaticSwingTools.showDialog(this);
this.uiChanged();
return true;
} else {
logger.error("showComplexEditorComponentUI(" + AbstractSimpleEditor.this.getId()
+ "): no corresponding editor for component registered"); // NOI18N
}
} else {
logger.warn("showComplexEditorComponentUI(" + AbstractSimpleEditor.this.getId()
+ "): showComplexEditorComponentUI(): child component or id is null"); // NOI18N
}
} else {
logger.error("showComplexEditorComponentUI(" + AbstractSimpleEditor.this.getId()
+ "): unexpected call to showComplexEditorComponentUI(): A Container can show only one complex editor at the same time ("
+ this.complexChildEditorId + ")"); // NOI18N
}
return false;
}
@Override
public boolean hideComplexEditorComponentUI(final Component complexChildEditorComponent,
final Object complexChildEditorId) {
if ((this.complexChildEditorId != null) && (this.getContentPane() != null)) {
if ((complexChildEditorComponent != null) && (complexChildEditorId != null)) {
if (this.complexChildEditorId.equals(complexChildEditorId)) {
if ((AbstractSimpleEditor.this.editorActivationDelegate != null)
&& (AbstractSimpleEditor.this.editorActivationDelegate.getChildEditor() != null)) {
if (logger.isDebugEnabled()) {
logger.debug("hideComplexEditorComponentUI(" + AbstractSimpleEditor.this.getId()
+ "): hiding complex editor UI"); // NOI18N
}
this.hide();
this.dispose();
this.setContentPane(null);
this.complexChildEditorId = null;
this.uiChanged();
return true;
} else {
logger.error("hideComplexEditorComponentUI(" + AbstractSimpleEditor.this.getId()
+ "): no corresponfing editor for component registered"); // NOI18N
}
} else {
logger.error("hideComplexEditorComponentUI(" + AbstractSimpleEditor.this.getId()
+ "): removed id '" + complexChildEditorId
+ "' does not match current active child editor id '" + this.complexChildEditorId
+ "'"); // NOI18N
}
} else {
logger.warn("hideComplexEditorComponentUI(" + AbstractSimpleEditor.this.getId()
+ "): child component or id is null"); // NOI18N
}
} else {
logger.error("hideComplexEditorComponentUI(" + AbstractSimpleEditor.this.getId()
+ "): unexpected call to hideComplexEditorComponentUIr(): no complex editor shown ("
+ complexChildEditorId + ")"); // NOI18N
}
return false;
}
@Override
public java.awt.Component getComponent() {
return this;
}
@Override
public Object getActiveChildEditorId() {
if ((this.complexChildEditorId == null)
&& AbstractSimpleEditor.this.editorActivationDelegate.isChildEditorRegistered()) {
return AbstractSimpleEditor.this.editorActivationDelegate.getChildEditor().getId();
}
return this.complexChildEditorId;
}
/**
* wird nicht delegiert!!!!
*/
@Override
public void uiChanged() {
AbstractSimpleEditor.this.uiChanged();
}
}
// PropertyChange Events ---------------------------------------------------
/**
* Rudiment\u00E4rer EditorListener, der den Wert des komplexen (child) Editors dem simplen Editor zuweist, von dem
* aus er aufgerufen wurde (this).
*
* <p>Der Event wird ausgel\u00F6st, wenn auf dem komplexen (child) Editor cancel- oder stopEditing() aufgerufen
* wird.</p>
*
* @version $Revision$, $Date$
*/
protected class SimpleEditorHandler implements EditorListener {
//~ Instance fields ----------------------------------------------------
protected Logger logger;
//~ Constructors -------------------------------------------------------
/**
* Creates a new SimpleEditorHandler object.
*/
public SimpleEditorHandler() {
this.logger = Logger.getLogger(SimpleEditorHandler.class);
}
//~ Methods ------------------------------------------------------------
@Override
public void editingCanceled(final ChangeEvent e) {
final BasicEditor basicEditor = (BasicEditor)e.getSource();
if (logger.isDebugEnabled()) {
logger.debug("editingCanceled(" + AbstractSimpleEditor.this.getId()
+ "): cancelEditing() on child editor '" + basicEditor.getId()
+ "' called, ignoring input"); // NOI18N
}
this.checkComplexChildVisibility(basicEditor);
this.checkComplexChildRegistration(basicEditor);
}
@Override
public void editingStopped(final ChangeEvent e) {
final BasicEditor basicEditor = (BasicEditor)e.getSource();
if (logger.isDebugEnabled()) {
logger.debug("editingStopped(" + AbstractSimpleEditor.this.getId()
+ "): stopEditing() on child editor '" + basicEditor.getId() + "' called, saving input"); // NOI18N
}
this.checkComplexChildVisibility(basicEditor);
this.checkComplexChildRegistration(basicEditor);
if (basicEditor.isValueChanged()) {
if (logger.isDebugEnabled()) {
logger.debug("editingStopped(" + AbstractSimpleEditor.this.getId()
+ "): changes in complex child editor '" + basicEditor.getId()
+ "', setting new value"); // NOI18N
}
// der neue Wert aus dem komplexen Editor ...
final Object value = basicEditor.getValue();
// den Wert diesem Editor UI zuweisen, damit er angezeigt wird (z.B. als String)
AbstractSimpleEditor.this.setValue(value);
// \u00C4nderung anzeigen!
AbstractSimpleEditor.this.valueChanged = true;
// den Wert diesem Editor zuweisen
AbstractSimpleEditor.this.setComponentValue(value);
fireEditingStopped();
} else if (logger.isDebugEnabled()) {
logger.debug("editingStopped(" + AbstractSimpleEditor.this.getId()
+ "): no changes in complex child editor '" + basicEditor.getId() + "'"); // NOI18N
}
}
/**
* Wenn der komplexe Child Editor noch an diesem komplexen Editor registriert ist, wird er nun entfernt.
*
* @param basicEditor DOCUMENT ME!
*/
protected void checkComplexChildRegistration(final BasicEditor basicEditor) {
if (ComplexEditor.class.isAssignableFrom(basicEditor.getClass())) {
if (AbstractSimpleEditor.this.editorActivationDelegate.isChildEditorRegistered()
&& AbstractSimpleEditor.this.editorActivationDelegate.getChildEditor().getId().equals(
basicEditor.getId())) {
if (logger.isDebugEnabled()) {
logger.debug("checkComplexChildRegistration(" + AbstractSimpleEditor.this.getId()
+ "): unregistering complex child editor '" + basicEditor.getId() + "'"); // NOI18N
}
AbstractSimpleEditor.this.removeComplexEditor((ComplexEditor)basicEditor);
} else if (logger.isDebugEnabled()) {
logger.debug("checkComplexChildRegistration(" + AbstractSimpleEditor.this.getId()
+ "): complex child editor '" + basicEditor.getId()
+ "' not unregistered, possibly registered a simple child editor"); // NOI18N
}
}
}
/**
* Wenn das komplexe Child Editor UI noch in diesem komplexen Editor angezeigt wird, wird es nun versteckt.
*
* @param basicEditor DOCUMENT ME!
*/
protected void checkComplexChildVisibility(final BasicEditor basicEditor) {
if (ComplexEditor.class.isAssignableFrom(basicEditor.getClass())) {
if (AbstractSimpleEditor.this.editorActivationDelegate.isChildEditorVisible()
&& (AbstractSimpleEditor.this.editorActivationDelegate.getChildEditorComponent()
== ((EditorUIDelegate)basicEditor).getComponent())) {
if (logger.isDebugEnabled()) {
logger.debug("checkComplexChildVisibility(" + AbstractSimpleEditor.this.getId()
+ "): hiding complex child editor ui '" + basicEditor.getId() + "' ("
+ AbstractSimpleEditor.this.editorActivationDelegate.getChildEditorComponent()
.getClass().getName() + ")"); // NOI18N
}
AbstractSimpleEditor.this.editorActivationDelegate.hideComplexEditorChildComponentUI();
} else if (logger.isDebugEnabled()) {
logger.debug("checkComplexChildVisibility(" + AbstractSimpleEditor.this.getId()
+ "): complex child editor '" + basicEditor.getId()
+ "' not hidden, possibly shown in complex parent editor"); // NOI18N
}
}
}
@Override
public void uiChanged(final ChangeEvent e) {
// ignore
}
}
}