/*************************************************** * * cismet GmbH, Saarbruecken, Germany * * ... and it just works. * ****************************************************/ /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package de.cismet.cids.editors; import Sirius.navigator.connection.Connection; import Sirius.navigator.connection.ConnectionFactory; import Sirius.navigator.connection.ConnectionInfo; import Sirius.navigator.connection.ConnectionSession; import Sirius.navigator.connection.SessionManager; import Sirius.navigator.connection.proxy.ConnectionProxy; import Sirius.server.localserver.attribute.MemberAttributeInfo; import Sirius.server.localserver.attribute.ObjectAttribute; import Sirius.server.middleware.types.MetaClass; import Sirius.server.middleware.types.MetaClassStore; import Sirius.server.middleware.types.MetaObject; import Sirius.server.newuser.User; import org.jdesktop.beansbinding.AutoBinding; import org.jdesktop.beansbinding.BeanProperty; import org.jdesktop.beansbinding.Binding; import org.jdesktop.beansbinding.BindingGroup; import org.jdesktop.beansbinding.Bindings; import org.jdesktop.beansbinding.Converter; import org.jdesktop.beansbinding.ELProperty; import org.jdesktop.beansbinding.Validator; import org.jdesktop.observablecollections.ObservableList; import org.jdesktop.observablecollections.ObservableListListener; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.FlowLayout; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.Vector; import javax.swing.DefaultListCellRenderer; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.ListCellRenderer; import javax.swing.ListModel; import de.cismet.cids.dynamics.CidsBean; import de.cismet.cids.dynamics.Disposable; import de.cismet.cids.dynamics.DisposableCidsBeanStore; import de.cismet.cids.editors.converters.BooleanToStringConverter; import de.cismet.cids.editors.converters.GeometryToStringConverter; import de.cismet.cids.editors.converters.SqlDateToStringConverter; import de.cismet.cids.navigator.utils.ClassCacheMultiple; import de.cismet.cids.utils.ClassloadingHelper; import de.cismet.commons.classloading.BlacklistClassloading; import de.cismet.tools.gui.ComponentWrapper; import de.cismet.tools.gui.DoNotWrap; import de.cismet.tools.gui.WrappedComponent; import de.cismet.tools.gui.log4jquickconfig.Log4JQuickConfig; /** * DOCUMENT ME! * * @author thorsten * @version $Revision$, $Date$ */ public class CidsObjectEditorFactory { //~ Static fields/initializers --------------------------------------------- private static CidsObjectEditorFactory editorFactory; private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(CidsObjectEditorFactory.class); public static final String NO_VALUE = org.openide.util.NbBundle.getMessage( CidsObjectEditorFactory.class, "CidsObjectEditorFactory.NO_VALUE"); // NOI18N public static final String PARENT_CIDS_EDITOR = "parentCidsEditor"; // NOI18N private static final String CMD_ADD_OBJECT = "cmdAddObject"; // NOI18N private static final String CMD_REMOVE_OBJECT = "cmdRemoveObject"; // NOI18N public static final String CIDS_BEAN = "cidsBean"; // NOI18N public static final String SOURCE_LIST = "sourceList"; // NOI18N private static Converter nullToBackgroundColorConverter = new IsNullToColorConverter(); // private boolean lazyClassFetching = true; private static final String EDITOR_PREFIX = "de.cismet.cids.custom.objecteditors."; // NOI18N private static final String EDITOR_SUFFIX = "Editor"; // NOI18N private static final String ATTRIBUTE_EDITOR_SUFFIX = "AttributeEditor"; // NOI18N //~ Instance fields -------------------------------------------------------- private HashMap<String, Converter> defaultConverter = new HashMap<String, Converter>(); private User user; private ComponentWrapper componentWrapper = null; //~ Constructors ----------------------------------------------------------- /** * Creates a new CidsObjectEditorFactory object. */ private CidsObjectEditorFactory() { // Die Klassennamen werden über class.getName() erzeugt. So checkt der Compiler ob sie korrekt referenziert // wurden defaultConverter.put(com.vividsolutions.jts.geom.Geometry.class.getName(), new GeometryToStringConverter()); defaultConverter.put(java.sql.Date.class.getName(), new SqlDateToStringConverter()); defaultConverter.put(java.lang.Boolean.class.getName(), new BooleanToStringConverter()); try { final Class<?> wrapperClass = BlacklistClassloading.forName( "de.cismet.cids.custom.objecteditors.EditorWrapper"); // NOI18N componentWrapper = (ComponentWrapper)wrapperClass.newInstance(); } catch (Exception skip) { if (log.isDebugEnabled()) { log.debug("Error while loading the EditorWrapper", skip); // NOI18N } } } //~ Methods ---------------------------------------------------------------- /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public static CidsObjectEditorFactory getInstance() { if (editorFactory == null) { editorFactory = new CidsObjectEditorFactory(); editorFactory.user = SessionManager.getSession().getUser(); } return editorFactory; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public ComponentWrapper getComponentWrapper() { return componentWrapper; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ private GridBagConstraints getCommonConstraints() { final GridBagConstraints gbc = new GridBagConstraints(); gbc.fill = GridBagConstraints.HORIZONTAL; gbc.anchor = GridBagConstraints.NORTHWEST; return gbc; } /** * DOCUMENT ME! * * @param gbc DOCUMENT ME! */ private void modifyForLabel(final GridBagConstraints gbc) { // gbc.weightx = 0.3; gbc.insets = new java.awt.Insets(4, 5, 3, 0); gbc.gridx = 0; } /** * DOCUMENT ME! * * @param gbc DOCUMENT ME! */ private void modifyForEditor(final GridBagConstraints gbc) { gbc.weightx = 0.7; gbc.insets = new java.awt.Insets(0, 5, 3, 0); gbc.gridx = 2; gbc.gridwidth = 2; } /** * DOCUMENT ME! * * @param domain DOCUMENT ME! * @param classid DOCUMENT ME! * * @return DOCUMENT ME! */ public static MetaClass getMetaClass(final String domain, final int classid) { return ClassCacheMultiple.getMetaClass(domain, classid); } /** * DOCUMENT ME! * * @param MetaObject DOCUMENT ME! * * @return DOCUMENT ME! */ public JComponent getEditor(final MetaObject MetaObject) { // Hier kann man noch mit Caching arbeiten JComponent editorComponent = getObjectEditor(MetaObject.getMetaClass()); if (editorComponent == null) { editorComponent = (JComponent)getDefaultEditor(MetaObject.getMetaClass()); } final JComponent finalEditorComponent = editorComponent; if (editorComponent instanceof DisposableCidsBeanStore) { final CidsBean bean = MetaObject.getBean(); // final Runnable setCidsBeanRunnable = new Runnable() { // // @Override // public void run() { ((DisposableCidsBeanStore)finalEditorComponent).setCidsBean(bean); if (finalEditorComponent instanceof AutoBindableCidsEditor) { bindCidsEditor((AutoBindableCidsEditor)finalEditorComponent); } // } // }; // if (EventQueue.isDispatchThread()) { // setCidsBeanRunnable.run(); // } else { // try { // EventQueue.invokeAndWait(setCidsBeanRunnable); // } catch (Throwable t) { // log.error(t, t); // } // } } // // } // else // // // { // ed.setCidsBean(MetaObject.getBean()); // } if (editorComponent != null) { if ((componentWrapper != null) && !(editorComponent instanceof DoNotWrap)) { return (JComponent)componentWrapper.wrapComponent((JComponent)editorComponent); } else { return editorComponent; } } else { // log return null; } } /** * DOCUMENT ME! * * @param metaClass DOCUMENT ME! * @param mai DOCUMENT ME! * * @return DOCUMENT ME! */ private JComponent getSimpleAttributeEditor(final MetaClass metaClass, final MemberAttributeInfo mai) { JComponent ret = null; if (ret == null) { final String attributeClassname = mai.getJavaclassname(); if (attributeClassname.equals(java.lang.String.class.getName())) { ret = new DefaultBindableJTextField(); ((DefaultBindableJTextField)ret).setConverter(defaultConverter.get(attributeClassname)); } else if (attributeClassname.equals(java.sql.Date.class.getName())) { ret = new DefaultBindableDateChooser(); } else if (attributeClassname.equals(java.sql.Timestamp.class.getName())) { ret = new DefaultBindableTimestampChooser(); } else if (attributeClassname.equals(java.lang.Boolean.class.getName())) { ret = new DefaultBindableJCheckBox(); } else if (mai.isForeignKey() && mai.isSubstitute()) { final MetaClass foreignClass = getMetaClass(metaClass.getDomain(), mai.getForeignKeyClassId()); if (foreignClass.getClassAttribute("reasonable_few") != null) { // NOI18N ret = new DefaultBindableReferenceCombo(foreignClass); } } else { if (log.isDebugEnabled()) { log.debug("no DefaultEditor for " + attributeClassname + " found. set to textbox "); // NOI18N } ret = new DefaultBindableJTextField(); ((DefaultBindableJTextField)ret).setConverter(defaultConverter.get(attributeClassname)); } } // if (ret!=null){ // ret.setOpaque(false); // } return ret; } /** * DOCUMENT ME! * * @param metaClass DOCUMENT ME! * * @return DOCUMENT ME! */ private JComponent getObjectEditor(final MetaClass metaClass) { final Class<?> editorClass = ClassloadingHelper.getDynamicClass( metaClass, ClassloadingHelper.CLASS_TYPE.EDITOR); if (editorClass != null) { try { final JComponent ed = (JComponent)editorClass.newInstance(); if (ed instanceof MetaClassStore) { ((MetaClassStore)ed).setMetaClass(metaClass); } return ed; } catch (Throwable e) { log.error("Error beim erzeugen der Editorklasse " + editorClass, e); } } return null; } /** * DOCUMENT ME! * * @param metaClass DOCUMENT ME! * * @return DOCUMENT ME! * * @throws UnsupportedOperationException DOCUMENT ME! */ private AutoBindableCidsEditor getDefaultEditor(final MetaClass metaClass) { final Vector<MemberAttributeInfo> mais = new Vector<MemberAttributeInfo>(metaClass.getMemberAttributeInfos() .values()); // final FinalReference<AutoBindableCidsEditor> result = new FinalReference<AutoBindableCidsEditor>(); // final Runnable createDefaultEditorRunnable = new Runnable() { // // @Override // public void run() { final DefaultCidsEditor cidsEditor = new DefaultCidsEditor(); // result.setObject(cidsEditor); final GridBagLayout gbl = new GridBagLayout(); GridBagConstraints gbc = null; cidsEditor.setLayout(gbl); int row = 0; for (final MemberAttributeInfo mai : mais) { if (mai.isVisible()) { // Description final JLabel lblDescription = new JLabel(); lblDescription.setText(mai.getName()); lblDescription.setHorizontalAlignment(JLabel.RIGHT); gbc = getCommonConstraints(); modifyForLabel(gbc); gbc.gridy = row; cidsEditor.add(lblDescription, gbc); // Editor JComponent cmpEditor = null; if (mai.isForeignKey()) { final int foreignKey = mai.getForeignKeyClassId(); final String domain = metaClass.getDomain(); final MetaClass foreignClass = getMetaClass(domain, foreignKey); if (mai.isArray()) { // -------------------------------------------------- // Arrays // -------------------------------------------------- MetaClass detailClass = null; // Detaileditorcomponent final Vector<MemberAttributeInfo> arrayAttrs = new Vector<MemberAttributeInfo>( foreignClass.getMemberAttributeInfos().values()); for (final MemberAttributeInfo arrayMai : arrayAttrs) { if (arrayMai.isForeignKey()) { final int detailKey = arrayMai.getForeignKeyClassId(); detailClass = getMetaClass(domain, detailKey); cmpEditor = (JComponent)getObjectEditor(detailClass); if (cmpEditor == null) { cmpEditor = (JComponent)getDefaultEditor(detailClass); } if (cmpEditor instanceof BindingInformationProvider) { final BindingInformationProvider ed = (BindingInformationProvider)cmpEditor; final Set<String> fields = ed.getAllControls().keySet(); for (final String key : fields) { final String newKey = mai.getFieldName().toLowerCase() + "[]." + key; // NOI18N cidsEditor.addControlInformation(newKey, ed.getAllControls().get(key)); } } else if (cmpEditor instanceof Bindable) { // TODO throw new UnsupportedOperationException(); } break; } } // Masterliste cidsEditor.remove(lblDescription); gbc = getCommonConstraints(); modifyForLabel(gbc); gbc.insets = new java.awt.Insets(4, 25, 3, 0); gbc.gridy = row++; gbc.fill = java.awt.GridBagConstraints.BOTH; final String field = mai.getFieldName().toLowerCase(); final BindableJList lstArrayMaster = new BindableJList(); final DefaultListCellRenderer dlcr = new DefaultListCellRenderer(); lstArrayMaster.setCellRenderer(new ListCellRenderer() { @Override public Component getListCellRendererComponent(final JList list, final Object value, final int index, final boolean isSelected, final boolean cellHasFocus) { final JLabel l = (JLabel)dlcr.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus); if ((l.getText() == null) || l.getText().trim().equals("") || l.getText().equals("null")) { // TODO Der check auf den String // "null" muss wieder raus //NOI18N final CidsBean cb = (CidsBean)value; if (cb.getMetaObject().getStatus() == MetaObject.NEW) { l.setText("neues Element"); // NOI18N if (isSelected) { l.setBackground(Color.GREEN); } } else { l.setText( cb.getMetaObject().getMetaClass().toString() + " " + cb.getProperty( cb.getMetaObject().getMetaClass().getPrimaryKey() .toLowerCase())); // NOI18N } } return l; } }); final ArrayTitleAndControls arrayTitleAndControls = new ArrayTitleAndControls( lblDescription.getText(), detailClass, field, lstArrayMaster); cidsEditor.add(arrayTitleAndControls, gbc); gbc = getCommonConstraints(); modifyForLabel(gbc); gbc.insets = new java.awt.Insets(4, 25, 0, 0); gbc.gridy = row; gbc.fill = java.awt.GridBagConstraints.BOTH; cidsEditor.addControlInformation(field + "[]", lstArrayMaster); // NOI18N cidsEditor.add(lstArrayMaster, gbc); gbc = getCommonConstraints(); modifyForEditor(gbc); gbc.gridy = row; cmpEditor.putClientProperty(PARENT_CIDS_EDITOR, cidsEditor); cidsEditor.add(cmpEditor, gbc); } else if (mai.isForeignKey()) { // -------------------------------------------------- // Normale Unterobjekte // -------------------------------------------------- // Entfernen Button gbc = getCommonConstraints(); modifyForLabel(gbc); gbc.fill = GridBagConstraints.NONE; gbc.insets = new java.awt.Insets(0, 0, 0, 3); gbc.gridx = 3; gbc.gridy = row; final JButton cmdRemove = new JButton(); cmdRemove.setBorderPainted(false); cmdRemove.setMinimumSize(new Dimension(12, 12)); cmdRemove.setPreferredSize(new Dimension(12, 12)); cmdRemove.setIcon(new javax.swing.ImageIcon( getClass().getResource("/de/cismet/cids/editors/edit_remove_mini.png"))); // NOI18N cmdRemove.setVisible(false); cidsEditor.add(cmdRemove, gbc); // Erstellen Button gbc = getCommonConstraints(); modifyForLabel(gbc); gbc.insets = new java.awt.Insets(0, 0, 0, 3); gbc.fill = GridBagConstraints.NONE; gbc.gridx = 3; gbc.gridy = row; final JButton cmdAdd = new JButton(); cmdAdd.setIcon(new javax.swing.ImageIcon( getClass().getResource("/de/cismet/cids/editors/edit_add_mini.png"))); // NOI18N cmdAdd.setBorderPainted(false); cmdAdd.setMinimumSize(new Dimension(12, 12)); cmdAdd.setPreferredSize(new Dimension(12, 12)); cmdAdd.setVisible(false); cidsEditor.add(cmdAdd, gbc); // Editor cmpEditor = getCustomAttributeEditor(metaClass, mai); if (cmpEditor == null) { cmpEditor = (JComponent)getObjectEditor(foreignClass); } if ((cmpEditor == null) && mai.isSubstitute()) { cmpEditor = getSimpleAttributeEditor(metaClass, mai); } // Sicherheithalber .... if (cmpEditor == null) { cmpEditor = (JComponent)getDefaultEditor(foreignClass); } // bindable geht vor if (cmpEditor instanceof Bindable) { cidsEditor.addControlInformation(mai.getFieldName().toLowerCase(), (Bindable)cmpEditor); } else if (cmpEditor instanceof BindingInformationProvider) { final BindingInformationProvider ed = (BindingInformationProvider)cmpEditor; final Set<String> fields = ed.getAllControls().keySet(); for (final String key : fields) { final String newKey = mai.getFieldName().toLowerCase() + "." + key; // NOI18N cidsEditor.addControlInformation(newKey, ed.getAllControls().get(key)); } } if (cmpEditor instanceof Disposable) { cidsEditor.addDisposableChild((Disposable)cmpEditor); } gbc = getCommonConstraints(); modifyForEditor(gbc); gbc.gridwidth = 1; gbc.gridy = row; if (cmpEditor != null) { cmpEditor.putClientProperty(PARENT_CIDS_EDITOR, cidsEditor); cidsEditor.add(cmpEditor, gbc); cmpEditor.putClientProperty(CMD_ADD_OBJECT, cmdAdd); cmpEditor.putClientProperty(CMD_REMOVE_OBJECT, cmdRemove); } else { log.warn("Editor was null. " + metaClass.getTableName() + "." + mai.getFieldName()); // NOI18N } } } else { // Die Editorkomponente über die Metainformations checken // -------------------------------------------------- // Einfache Attribute // -------------------------------------------------- cmpEditor = getCustomAttributeEditor(metaClass, mai); if (cmpEditor == null) { cmpEditor = getSimpleAttributeEditor(metaClass, mai); } if (log.isDebugEnabled()) { log.debug("ATTRIBUTE_CLASS_NAME:" + mai.getJavaclassname() + " --> " + cmpEditor.getClass().toString()); // NOI18N } cidsEditor.addControlInformation(mai.getFieldName().toLowerCase(), (Bindable)cmpEditor); gbc = getCommonConstraints(); modifyForEditor(gbc); gbc.gridy = row; cmpEditor.putClientProperty(PARENT_CIDS_EDITOR, cidsEditor); cidsEditor.add(cmpEditor, gbc); } } row++; } // } // }; // if (EventQueue.isDispatchThread()) { // createDefaultEditorRunnable.run(); // } else { // try { // EventQueue.invokeAndWait(createDefaultEditorRunnable); // } catch (Throwable t) { // log.error(t, t); // return null; // } // } // return result.getObject(); return cidsEditor; } /** * DOCUMENT ME! * * @param metaClass DOCUMENT ME! * @param mai DOCUMENT ME! * * @return DOCUMENT ME! */ private JComponent getCustomAttributeEditor(final MetaClass metaClass, final MemberAttributeInfo mai) { // TODO // Hier müssen auch noch die Einstellungen inder DB (ComplexEditor, Editor) berücksichtigt werden // MetaClass contains the MemberAttributeInfo try { final Class<?> attrEditorClass = ClassloadingHelper.getDynamicClass( metaClass, mai, ClassloadingHelper.CLASS_TYPE.ATTRIBUTE_EDITOR); if (attrEditorClass != null) { final MetaClass foreignClass; if (MetaClassStore.class.isAssignableFrom(attrEditorClass) && mai.isForeignKey()) { foreignClass = getMetaClass(metaClass.getDomain(), mai.getForeignKeyClassId()); } else { foreignClass = null; } // final Runnable createAttributeEditorRunnable = new Runnable() { // // @Override // public void run() { try { final Bindable editor = (Bindable)attrEditorClass.newInstance(); if (foreignClass != null) { ((MetaClassStore)editor).setMetaClass(foreignClass); } return (JComponent)editor; } catch (Throwable t) { log.error("getCustomAttributeEditor von " + metaClass.getTableName() + "." + mai.getFieldName() + " liefert einen Fehler", t); throw new RuntimeException(t); } // } // }; // if (EventQueue.isDispatchThread()) { // createAttributeEditorRunnable.run(); // } else { // EventQueue.invokeAndWait(createAttributeEditorRunnable); // } } } catch (Exception e) { log.error("Error when creating a SimpleAttributeEditor", e); // NOI18N } return null; } /** * DOCUMENT ME! * * @param ed DOCUMENT ME! */ private void bindCidsEditor(final AutoBindableCidsEditor ed) { final BindingGroup bg = ed.getBindingGroup(); // MetaObject MetaObject = ed.getCidsBean().getMetaObject(); // ObjectAttribute[] allAttrs = MetaObject.getAttribs(); Binding binding = null; final Set<String> keys = ed.getAllControls().keySet(); final HashMap<String, JList> arraylists = new HashMap<String, JList>(); final HashSet complexEditors = new HashSet(); // Prefetching all the JLists for (final String key : keys) { if (key.endsWith("[]")) { // NOI18N final JList lstList = (JList)ed.getControlByName(key); arraylists.put(key, lstList); } } for (final String key : keys) { if (key.endsWith("[]")) { // NOI18N // -------------------------------------------------- // Array // -------------------------------------------------- // -------------------------------------------------- // Zuerst die Master JLists // -------------------------------------------------- final String keyWithoutBrackets = key.substring(0, key.length() - 2); Object bindingSource = null; ELProperty elProperty = null; final JList lstList = arraylists.get(key); if (keyWithoutBrackets.contains("[]")) { // NOI18N // [] mehr als einmal vorhanden final String parentListIdentifier = keyWithoutBrackets.substring( 0, keyWithoutBrackets.lastIndexOf("[]") + 2); // NOI18N bindingSource = arraylists.get(parentListIdentifier); lstList.putClientProperty(SOURCE_LIST, bindingSource); final String subKeyWithoutBrackets = key.substring(key.indexOf(parentListIdentifier) + ".".length() + parentListIdentifier.length(), key.length() - 2); // NOI18N elProperty = ELProperty.create("${selectedElement." + subKeyWithoutBrackets + "}"); // NOI18N } else { bindingSource = ed; lstList.putClientProperty(CIDS_BEAN, ed.getCidsBean()); elProperty = ELProperty.create("${cidsBean." + keyWithoutBrackets + "}"); // NOI18N } final org.jdesktop.swingbinding.JListBinding jListBinding = org.jdesktop.swingbinding.SwingBindings .createJListBinding( AutoBinding.UpdateStrategy.READ_WRITE, bindingSource, elProperty, lstList); try { final ObservableList observableList = (ObservableList)ed.getCidsBean() .getProperty(keyWithoutBrackets); for (final Object o : observableList) { ((CidsBean)o).addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(final PropertyChangeEvent evt) { lstList.repaint(); } }); } // und jetzt noch für die zukuenftigen observableList.addObservableListListener(new ObservableListListenerAdapter() { @Override public void listElementsAdded(final ObservableList list, final int index, final int length) { for (int i = index; i < (index + length); ++i) { ((CidsBean)list.get(i)).addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(final PropertyChangeEvent evt) { lstList.repaint(); } }); } } }); } catch (Exception e) { if (log.isDebugEnabled()) { log.debug("No observableList update for Array in Array in ...", e); // NOI18N } } bg.addBinding(jListBinding); } else { // -------------------------------------------------- // keine Arrays // -------------------------------------------------- final JComponent jc = (JComponent)ed.getControlByName(key); // in jc steckt die Editorkomponente final Bindable bjc = (Bindable)jc; final BindingInformationProvider parentCidsEditor = (BindingInformationProvider)jc.getClientProperty( PARENT_CIDS_EDITOR); binding = Bindings.createAutoBinding( AutoBinding.UpdateStrategy.READ_WRITE, jc, ELProperty.create("${text==null}"), jc, BeanProperty.create("background")); // NOI18N binding.setConverter(nullToBackgroundColorConverter); bg.addBinding(binding); if (key.contains("[]")) { // NOI18N // -------------------------------------------------- // Detailattribute // -------------------------------------------------- final int whereSubKeyStarts = key.lastIndexOf("[]") + 3; // NOI18N final String arrayFieldWithBrackets = key.substring(0, whereSubKeyStarts - 1); final JList list = (JList)ed.getControlByName(arrayFieldWithBrackets); final String subkey = key.substring(whereSubKeyStarts); final String exp = "selectedElement." + subkey; // NOI18N binding = Bindings.createAutoBinding( AutoBinding.UpdateStrategy.READ_WRITE, list, ELProperty.create("${" + exp + "}"), jc, BeanProperty.create(bjc.getBindingProperty())); // NOI18N binding.setSourceUnreadableValue(null); final Converter c = bjc.getConverter(); if (c != null) { binding.setConverter(c); } final Object nullValue = bjc.getNullSourceValue(); final Object errorValue = bjc.getErrorSourceValue(); if (nullValue != null) { binding.setSourceNullValue(nullValue); } if (errorValue != null) { binding.setSourceUnreadableValue(errorValue); } bg.addBinding(binding); // Direktes Detailattribut (oder ein Subobjekt) if (subkey.contains(".")) { // NOI18N final String[] sa = subkey.split("\\."); // NOI18N final String object = subkey.substring(0, subkey.lastIndexOf(".")); // NOI18N // Check ob das Teilobjekt nicht auf null gesetzt ist final String expression = "selectedElement." + object; // NOI18N addDisablingAndNullCheckerBindings(bg, expression, list, jc); addAddRemoveControlVisibilityBinding(bg, (JComponent)parentCidsEditor, list, object, true); } } else { // -------------------------------------------------- // nicht Teil eines Arrays // -------------------------------------------------- binding = Bindings.createAutoBinding( AutoBinding.UpdateStrategy.READ_WRITE, ed, ELProperty.create("${cidsBean." + key + "}"), jc, BeanProperty.create(bjc.getBindingProperty())); // NOI18N final Converter c = bjc.getConverter(); if (c != null) { binding.setConverter(c); } final Object nullValue = bjc.getNullSourceValue(); final Object errorValue = bjc.getErrorSourceValue(); if (nullValue != null) { binding.setSourceNullValue(nullValue); } if (errorValue != null) { binding.setSourceUnreadableValue(errorValue); } bg.addBinding(binding); if (key.contains(".")) { // NOI18N // Subobjekt final String[] sa = key.split("\\."); // NOI18N final String attribute = sa[sa.length - 1]; final String object = key.substring(0, key.lastIndexOf(".")); // NOI18N // Check ob das Teilobjekt nicht auf null gesetzt ist final String expression = "cidsBean." + object; // NOI18N addDisablingAndNullCheckerBindings(bg, expression, ed, jc); addAddRemoveControlVisibilityBinding( bg, (JComponent)parentCidsEditor, (JComponent)ed, object, false); } else if (bjc instanceof DisposableCidsBeanStore) { // Subobjekt das nur durch ein Bindable editiert wird final String expression = "cidsBean." + key; // NOI18N addDisablingAndNullCheckerBindings(bg, expression, ed, jc); addAddRemoveControlVisibilityBinding(bg, jc, (JComponent)ed, key, false); } } // hier wird sichergestellt dass nur einmal für jeden komplexen editor die +/- buttons hinzugefuegt // werden if (parentCidsEditor != null) { complexEditors.add(parentCidsEditor); } } } bg.bind(); } /** * DOCUMENT ME! * * @param bg DOCUMENT ME! * @param expression DOCUMENT ME! * @param sourceObject DOCUMENT ME! * @param component DOCUMENT ME! */ private void addDisablingAndNullCheckerBindings(final BindingGroup bg, final String expression, final Object sourceObject, final JComponent component) { Binding binding = Bindings.createAutoBinding( AutoBinding.UpdateStrategy.READ_WRITE, sourceObject, ELProperty.create("${" + expression + "!=null}"), component, BeanProperty.create("enabled")); // NOI18N bg.addBinding(binding); binding = Bindings.createAutoBinding( AutoBinding.UpdateStrategy.READ_WRITE, sourceObject, ELProperty.create("${" + expression + "==null}"), component, BeanProperty.create("background")); // NOI18N binding.setConverter(nullToBackgroundColorConverter); // binding.setSourceNullValue(NO_VALUE);//Geht nicht weil ed.cidsBean nicht null ist bg.addBinding(binding); } /** * DOCUMENT ME! * * @param bg DOCUMENT ME! * @param buttonContainer DOCUMENT ME! * @param bindingSourceObject DOCUMENT ME! * @param attributeName DOCUMENT ME! * @param detailObjectOfAnArray DOCUMENT ME! */ private void addAddRemoveControlVisibilityBinding(final BindingGroup bg, final JComponent buttonContainer, final JComponent bindingSourceObject, final String attributeName, final boolean detailObjectOfAnArray) { Binding binding = null; final JButton cmdAdd = (JButton)buttonContainer.getClientProperty("cmdAddObject"); // NOI18N final JButton cmdRemove = (JButton)buttonContainer.getClientProperty("cmdRemoveObject"); // NOI18N String objectExpression; if (detailObjectOfAnArray) { objectExpression = "selectedElement." + attributeName; // NOI18N } else { objectExpression = "cidsBean." + attributeName; // NOI18N } if (cmdAdd != null) { binding = Bindings.createAutoBinding( AutoBinding.UpdateStrategy.READ_WRITE, bindingSourceObject, ELProperty.create("${" + objectExpression + "==null}"), cmdAdd, BeanProperty.create("visible")); // NOI18N bg.addBinding(binding); cmdAdd.addActionListener(new ActionListener() { @Override public void actionPerformed(final ActionEvent e) { CidsBean actionBean; if (detailObjectOfAnArray) { actionBean = (CidsBean)((JList)bindingSourceObject).getSelectedValue(); } else { actionBean = ((DisposableCidsBeanStore)bindingSourceObject).getCidsBean(); } final ObjectAttribute oa = actionBean.getMetaObject().getAttributeByFieldName(attributeName); final MetaClass mc = getMetaClass( actionBean.getMetaObject().getDomain(), oa.getMai().getForeignKeyClassId()); final CidsBean newOne = mc.getEmptyInstance().getBean(); try { actionBean.setProperty(attributeName, newOne); } catch (Exception ex) { ex.printStackTrace(); } } }); } if (cmdRemove != null) { binding = Bindings.createAutoBinding( AutoBinding.UpdateStrategy.READ_WRITE, bindingSourceObject, ELProperty.create("${" + objectExpression + "!=null}"), cmdRemove, BeanProperty.create("visible")); // NOI18N bg.addBinding(binding); cmdRemove.addActionListener(new ActionListener() { @Override public void actionPerformed(final ActionEvent e) { CidsBean actionBean; if (detailObjectOfAnArray) { actionBean = (CidsBean)((JList)bindingSourceObject).getSelectedValue(); } else { actionBean = ((DisposableCidsBeanStore)bindingSourceObject).getCidsBean(); } try { ((CidsBean)actionBean.getProperty(attributeName)).delete(); // anderer option nur null setzen actionBean.setProperty(attributeName, null); } catch (Exception ex) { ex.printStackTrace(); } } }); } } /** * DOCUMENT ME! * * @param args DOCUMENT ME! * * @throws Exception DOCUMENT ME! */ public static void main(final String[] args) throws Exception { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { final JPanel panCommand = new JPanel(); final String domain = "WUNDA_DEMO"; // NOI18N final int CLASSID = 374; final int OBJECTID = 1; // final int CLASSID = 47; //Bauvisualisierung // final int OBJECTID = 1; // final int CLASSID = 45; //POI // final int OBJECTID = 7; //botanischer Garten Log4JQuickConfig.configure4LumbermillOnLocalhost(); ConnectionSession session = null; ConnectionProxy proxy = null; final ConnectionInfo connectionInfo = new ConnectionInfo(); connectionInfo.setCallserverURL("rmi://localhost/callServer"); // NOI18N connectionInfo.setPassword("demo"); // NOI18N connectionInfo.setUsergroup("Demo"); // NOI18N connectionInfo.setUserDomain("WUNDA_DEMO"); // NOI18N connectionInfo.setUsergroupDomain("WUNDA_DEMO"); // NOI18N connectionInfo.setUsername("demo"); // NOI18N final Connection connection = ConnectionFactory.getFactory() .createConnection( "Sirius.navigator.connection.RMIConnection", connectionInfo.getCallserverURL()); // NOI18N // connection.g session = ConnectionFactory.getFactory().createSession(connection, connectionInfo, true); proxy = ConnectionFactory.getFactory() .createProxy( "Sirius.navigator.connection.proxy.DefaultConnectionProxyHandler", session); // NOI18N SessionManager.init(proxy); final MetaObject MetaObject = SessionManager.getConnection() .getMetaObject(SessionManager.getSession().getUser(), OBJECTID, CLASSID, domain); // meta.getMetaObject(u, 1, AAPERSON_CLASSID, domain); log.fatal(MetaObject.getDebugString()); final JFrame tester = new JFrame( org.openide.util.NbBundle.getMessage( CidsObjectEditorFactory.class, "CidsObjectEditorFactory.tester.title")); // NOI18N final Container cp = tester.getContentPane(); cp.setLayout(new BorderLayout()); final JComponent ed = CidsObjectEditorFactory.getInstance().getEditor(MetaObject); cp.add(ed); tester.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); final JButton cmdPersist = new JButton( org.openide.util.NbBundle.getMessage( CidsObjectEditorFactory.class, "CidsObjectEditorFactory.cmdPersist.text")); // NOI18N cmdPersist.addActionListener(new ActionListener() { @Override public void actionPerformed(final ActionEvent e) { try { if (ed instanceof WrappedComponent) { ((DisposableCidsBeanStore)((WrappedComponent)ed).getOriginalComponent()) .getCidsBean().persist(); } else { ((DisposableCidsBeanStore)ed).getCidsBean().persist(); } } catch (Exception ex) { ex.printStackTrace(); } } }); final JButton cmdLog = new JButton( org.openide.util.NbBundle.getMessage( CidsObjectEditorFactory.class, "CidsObjectEditorFactory.cmdLog.text")); // NOI18N cmdLog.addActionListener(new ActionListener() { @Override public void actionPerformed(final ActionEvent e) { CidsBean cb = null; if (ed instanceof WrappedComponent) { cb = ((DisposableCidsBeanStore)((WrappedComponent)ed).getOriginalComponent()) .getCidsBean(); } else { cb = ((DisposableCidsBeanStore)ed).getCidsBean(); } if (cb != null) { log.fatal(cb.getMOString()); } } }); final JButton cmdReload = new JButton( org.openide.util.NbBundle.getMessage( CidsObjectEditorFactory.class, "CidsObjectEditorFactory.cmdReload.text")); // NOI18N cmdReload.addActionListener(new ActionListener() { @Override public void actionPerformed(final ActionEvent e) { try { AutoBindableCidsEditor abce = null; if (ed instanceof WrappedComponent) { abce = ((AutoBindableCidsEditor)((WrappedComponent)ed) .getOriginalComponent()); } else { abce = ((AutoBindableCidsEditor)ed); } if (abce != null) { abce.setCidsBean( SessionManager.getConnection().getMetaObject( SessionManager.getSession().getUser(), OBJECTID, CLASSID, domain).getBean()); abce.getBindingGroup().unbind(); abce.getBindingGroup().bind(); } } catch (Exception ex) { ex.printStackTrace(); } } }); panCommand.setLayout(new FlowLayout(FlowLayout.CENTER)); panCommand.add(cmdPersist); panCommand.add(cmdLog); panCommand.add(cmdReload); tester.getContentPane().add(panCommand, BorderLayout.SOUTH); tester.setSize(new Dimension(800, 500)); tester.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } } /** * DOCUMENT ME! * * @version $Revision$, $Date$ */ class ObservableListListenerAdapter implements ObservableListListener { //~ Methods ---------------------------------------------------------------- @Override public void listElementPropertyChanged(final ObservableList list, final int index) { } @Override public void listElementReplaced(final ObservableList list, final int index, final Object oldElement) { } @Override public void listElementsAdded(final ObservableList list, final int index, final int length) { } @Override public void listElementsRemoved(final ObservableList list, final int index, final List oldElements) { } } /** * DOCUMENT ME! * * @version $Revision$, $Date$ */ class BindableJList extends JList implements Bindable { //~ Constructors ----------------------------------------------------------- /** * Creates a new BindableJList object. */ public BindableJList() { } /** * Creates a new BindableJList object. * * @param listData DOCUMENT ME! */ public BindableJList(final Vector<?> listData) { super(listData); } /** * Creates a new BindableJList object. * * @param listData DOCUMENT ME! */ public BindableJList(final Object[] listData) { super(listData); } /** * Creates a new BindableJList object. * * @param dataModel DOCUMENT ME! */ public BindableJList(final ListModel dataModel) { super(dataModel); } //~ Methods ---------------------------------------------------------------- @Override public String getBindingProperty() { return null; } @Override public Converter getConverter() { return null; } @Override public Validator getValidator() { return null; } @Override public Object getNullSourceValue() { return null; } @Override public Object getErrorSourceValue() { return null; } }