/***************************************************
*
* cismet GmbH, Saarbruecken, Germany
*
* ... and it just works.
*
****************************************************/
package Sirius.navigator.ui.attributes.editor;
import org.apache.log4j.Logger;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
/**
* Abstrakte Implementierung zum Aktivieren / Deaktivieren eines komplexen Editors innerhalb eines simplen / komplexen
* Editors.
*
* <p>Diese Klasse mu\u00DF von keinem konkreten simplen / komplexen Editor implementiert werden.</p>
*
* @author Pascal
* @version $Revision$, $Date$
* @see AbstractSimpleEditor
* @see SimpleEditorActivationDelegate
* @see AbstractComplexEditor
* @see ComplexEditorActivationDelegate
*/
public abstract class AbstractEditorActivationDelegate implements EditorActivationDelegate, ActionListener {
//~ Static fields/initializers ---------------------------------------------
public static final String START_EDIT_COMMAND = "startEdit"; // NOI18N
public static final String STOP_EDIT_COMMAND = "stopEdit"; // NOI18N
public static final String CANCEL_EDIT_COMMAND = "cancelEdit"; // NOI18N
public static final String SHOW_UI_COMMAND = "showUI"; // NOI18N
public static final String HIDE_UI_COMMAND = "hideUI"; // NOI18N
//~ Instance fields --------------------------------------------------------
protected Logger logger = null;
protected BasicEditor thisEditor = null;
protected BasicContainer thisContainer = null;
// protected BasicContainer parentContainer = null;
/** Der egistrierte Child Editor. */
protected ComplexEditor childEditor = null;
/** Der zur Pegistrierung vorgesehene Child Editor. */
protected ComplexEditor lazyChildEditor = null;
protected Component editorComponent = null;
protected EditorListener editorListener = null;
/** Utility field used by bound properties. */
protected SwingPropertyChangeSupport propertyChangeSupport;
/** Holds value of property propertyChangeEnabled. */
private boolean propertyChangeEnabled = false;
//~ Methods ----------------------------------------------------------------
/**
* Kann \u00FCberschrieben werden, um eine interne Implementierung eines EditorListeners zu erzeugen.
*
* @return DOCUMENT ME!
*/
protected abstract EditorListener createEditorListener();
/**
* Liefert den parent Container, in dem das UI des komplexen child Editors angezeigt werden soll.
*
* <p>Bei einem komplexen Editor, ist dies normalerweise das UI des komplexen Editors selbst (also this), bei einem
* simplen Editor ist dies normalerweise das UI in dem der simple Editor angezeigt wird (also this.parent), es sei
* denn, das UI des komplexen child Editors soll in einem *modalen* Dialog angezeigt werden.</p>
*
* @return der parent Container, in dem das UI des komplexen child Editors angezeigt werden soll
*/
protected abstract BasicContainer getParentContainerForUI();
/*{
* // komplexer Editor -> this container return this.thisContainer; // einfacher Editor -> parent container return
* this.thisContainer.getParent();}*/
/**
* DOCUMENT ME!
*
* @param child DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
protected BasicContainer getRoot(final BasicContainer child) {
final BasicContainer parent = child.getParentContainer();
if (parent != null) {
return this.getRoot(parent);
} else {
return child;
}
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
protected boolean addLazyComplexEditor() {
final boolean ret = this.addComplexEditor(this.lazyChildEditor);
// hm ...
return ret;
}
@Override
public boolean addComplexEditor(final ComplexEditor childEditor) {
if (childEditor != null) {
if (!this.isChildEditorAvailable() && !this.isChildEditorRegistered()) {
if (childEditor.getId() != null) {
LinkedList oldActiveChildEditorTree = null;
BasicContainer rootContainer = null;
if (this.isPropertyChangeEnabled()
&& (this.propertyChangeSupport.getPropertyChangeListeners().length > 0)) {
// System.exit(1);
if (logger.isDebugEnabled()) {
logger.debug("addComplexEditor(" + thisEditor + "): fire property change event"); // NOI18N
}
rootContainer = this.getRoot(this.thisContainer);
oldActiveChildEditorTree = rootContainer.getActiveChildEditorTree(new LinkedList());
}
this.setChildEditor(childEditor);
this.thisContainer.getChildEditors().put(childEditor.getId(), childEditor);
if (logger.isDebugEnabled()) {
logger.debug("addComplexEditor(" + thisEditor
+ "): preparing editor for complex edit action of complex editor '"
+ childEditor.getId() + "'"); // NOI18N
}
// neue Listener erzeugen
this.editorListener = this.createEditorListener();
// \u00C4nderungen implements komplexen Editor (child) -> \u00C4nderungen implements simplen
// Editor (this)
childEditor.addEditorListener(this.editorListener);
if ((oldActiveChildEditorTree != null) && (rootContainer != null)) {
final LinkedList newActiveChildEditorTree = rootContainer.getActiveChildEditorTree(
new LinkedList());
this.propertyChangeSupport.firePropertyChange(
ACTIVE_CHILD_EDITOR_TREE,
newActiveChildEditorTree,
oldActiveChildEditorTree);
}
return true;
} else {
if (logger.isDebugEnabled()) {
logger.debug("addComplexEditor(" + thisEditor + "): id of complex child editor '"
+ childEditor.getClass().getName() + "' is null -> adding editor lazily"); // NOI18N
}
this.lazyChildEditor = childEditor;
}
} else {
logger.error("addComplexEditor(" + thisEditor
+ "): unexpected call to addComplexEditor(): A Container can hold only one complex editor at the same time"); // NOI18N
}
} else {
logger.warn("addComplexEditor(" + thisEditor + "): addComplexEditor(): child editor is null"); // NOI18N
}
return false;
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
protected boolean removeComplexEditor() {
return this.removeComplexEditor(this.childEditor);
}
@Override
public boolean removeComplexEditor(final ComplexEditor childEditor) {
if (childEditor != null) {
if (this.isChildEditorAvailable()
&& (this.thisContainer.getChildEditors().remove(childEditor.getId()) != null)
&& (this.editorListener != null)) {
if (logger.isDebugEnabled()) {
logger.debug("removeComplexEditor(" + thisEditor
+ "): stopping complex edit action of complex editor '" + childEditor.getId() + "'"); // NOI18N
}
LinkedList oldActiveChildEditorTree = null;
BasicContainer rootContainer = null;
if (this.isPropertyChangeEnabled()
&& (this.propertyChangeSupport.getPropertyChangeListeners().length > 0)) {
if (logger.isDebugEnabled()) {
logger.debug("removeComplexEditor(" + thisEditor + "): fire property change event"); // NOI18N
}
rootContainer = this.getRoot(this.thisContainer);
oldActiveChildEditorTree = rootContainer.getActiveChildEditorTree(new LinkedList());
}
childEditor.removeEditorListener(this.editorListener);
this.editorListener = null;
this.editorComponent = null;
this.setChildEditor(null);
if ((oldActiveChildEditorTree != null) && (rootContainer != null)) {
final LinkedList newActiveChildEditorTree = rootContainer.getActiveChildEditorTree(new LinkedList());
this.propertyChangeSupport.firePropertyChange(
ACTIVE_CHILD_EDITOR_TREE,
newActiveChildEditorTree,
oldActiveChildEditorTree);
}
return true;
} else if (logger.isDebugEnabled()) {
logger.error("removeComplexEditor(" + thisEditor
+ "): unexpected call to removeComplexEditor(): no complex editor registered: "
+ childEditor.getId()); // NOI18N
}
} else {
logger.warn("removeComplexEditor(" + thisEditor + "): child editor is null"); // NOI18N
}
return false;
}
/**
* Ruft showComplexEditorComponentUI auf dem parent Container auf.
*
* <p>UI des komplexen Editors anzeigen im komplexen Container -> intern (CardLayout)<br>
* UI des komplexen Editors anzeigen im simplen Container -> Dialogbox</p>
*
* @return DOCUMENT ME!
*/
public boolean showComplexEditorChildComponentUI() {
if (logger.isDebugEnabled()) {
logger.debug("showComplexEditorChildComponentUI(" + thisEditor + "): called"); // NOI18N
}
if ((this.childEditor != null) || (this.lazyChildEditor != null)) {
if (this.isChildEditorVisible()) {
logger.warn("showComplexEditorChildComponentUI(" + thisEditor + "): child editor still visible"); // NOI18N
if (!this.hideComplexEditorChildComponentUI()) {
return false;
}
}
if (this.childEditor == null) {
// child editor UI erzeugen
// thisContainer wird als parent container \u00FCbergeben
this.editorComponent = this.lazyChildEditor.getEditorComponent(
this.thisContainer,
this.thisEditor.getId(),
this.thisEditor.getValue());
if (logger.isDebugEnabled()) {
logger.debug("showComplexEditorChildComponentUI(" + thisEditor
+ "): adding now lazily added child editor"); // NOI18N
}
this.addLazyComplexEditor();
} else {
// child editor UI erzeugen
// thisContainer wird als parent container \u00FCbergeben
this.editorComponent = this.childEditor.getEditorComponent(
this.thisContainer,
this.thisEditor.getId(),
this.thisEditor.getValue());
}
return this.getParentContainerForUI()
.showComplexEditorComponentUI(this.editorComponent, this.childEditor.getId());
} else {
logger.warn("showComplexEditorChildComponentUI(" + thisEditor
+ "): child editor and lazy cild editor are null"); // NOI18N
}
return false;
}
/**
* Ruft hideComplexEditorComponentUI auf dem parent Container auf.
*
* <p>UI des komplexen Editors entfernen aus komplexem Container -> intern (CardLayout)<br>
* UI des komplexen Editors entfernen aus simplen Container -> Dialogbox</p>
*
* @return DOCUMENT ME!
*/
public boolean hideComplexEditorChildComponentUI() {
if (logger.isDebugEnabled()) {
logger.debug("hideComplexEditorChildComponentUI(" + thisEditor + "): called"); // NOI18N
}
if (this.editorComponent != null) {
if (this.getParentContainerForUI().hideComplexEditorComponentUI(
this.editorComponent,
this.childEditor.getId())) {
this.editorComponent = null;
return true;
}
} else {
logger.warn("hideComplexEditorChildComponentUI(" + thisEditor + "): editorComponent is null"); // NOI18N
}
return false;
}
@Override
public void actionPerformed(final ActionEvent e) {
if (e.getActionCommand().equals(START_EDIT_COMMAND)) {
this.addLazyComplexEditor();
} else if (e.getActionCommand().equals(STOP_EDIT_COMMAND)) {
this.removeComplexEditor();
} else if (e.getActionCommand().equals(SHOW_UI_COMMAND)) {
this.showComplexEditorChildComponentUI();
} else if (e.getActionCommand().equals(HIDE_UI_COMMAND)) {
this.hideComplexEditorChildComponentUI();
} else if (logger.isDebugEnabled()) {
logger.warn("actionPerformed(" + thisEditor + "): unrecognized action command '" + e.getActionCommand()
+ "'"); // NOI18N
}
}
/**
* Getter for property childEditor.
*
* @return Value of property childEditor.
*/
protected ComplexEditor getChildEditor() {
return this.childEditor;
}
/**
* Setter for property childEditor.
*
* @param childEditor New value of property childEditor.
*/
protected void setChildEditor(final ComplexEditor childEditor) {
this.childEditor = childEditor;
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
protected boolean isChildEditorAvailable() {
return this.childEditor != null;
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
protected boolean isChildEditorRegistered() {
if (this.isChildEditorAvailable()) {
return this.thisContainer.getChildEditors().containsKey(this.getChildEditor().getId());
}
return false;
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public boolean isChildEditorVisible() {
return this.getChildEditorComponent() != null;
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
protected Component getChildEditorComponent() {
return this.editorComponent;
}
@Override
public void addPropertyChangeListener(final java.beans.PropertyChangeListener l) {
this.propertyChangeSupport.addPropertyChangeListener(l);
}
@Override
public void removePropertyChangeListener(final java.beans.PropertyChangeListener l) {
this.propertyChangeSupport.removePropertyChangeListener(l);
}
/**
* Getter for property propertyChangeEnabled.
*
* @return Value of property propertyChangeEnabled.
*/
public boolean isPropertyChangeEnabled() {
return this.propertyChangeEnabled;
}
/**
* Setter for property propertyChangeEnabled.
*
* @param propertyChangeEnabled New value of property propertyChangeEnabled.
*/
public void setPropertyChangeEnabled(final boolean propertyChangeEnabled) {
this.propertyChangeEnabled = propertyChangeEnabled;
}
}