001 /* 002 Copyright (C) 2001-2003 Laurent Martelli <laurent@aopsys.com> 003 004 This program is free software; you can redistribute it and/or modify 005 it under the terms of the GNU Lesser General Public License as 006 published by the Free Software Foundation; either version 2 of the 007 License, or (at your option) any later version. 008 009 This program is distributed in the hope that it will be useful, 010 but WITHOUT ANY WARRANTY; without even the implied warranty of 011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 GNU Lesser General Public License for more details. 013 014 You should have received a copy of the GNU Lesser General Public License 015 along with this program; if not, write to the Free Software 016 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 017 018 package org.objectweb.jac.aspects.gui.swing; 019 020 import java.awt.event.FocusEvent; 021 import java.awt.event.FocusListener; 022 import java.lang.IllegalAccessException; 023 import org.apache.log4j.Logger; 024 import org.objectweb.jac.aspects.gui.CommitException; 025 import org.objectweb.jac.aspects.gui.FieldEditor; 026 import org.objectweb.jac.aspects.gui.FieldUpdate; 027 import org.objectweb.jac.aspects.gui.GuiAC; 028 import org.objectweb.jac.aspects.gui.Utils; 029 import org.objectweb.jac.core.Collaboration; 030 import org.objectweb.jac.core.rtti.ClassItem; 031 import org.objectweb.jac.core.rtti.FieldItem; 032 import org.objectweb.jac.core.rtti.MethodItem; 033 034 public abstract class AbstractFieldEditor extends AbstractView 035 implements FocusListener, FieldEditor, FieldUpdate 036 { 037 static Logger logger = Logger.getLogger("gui.editor"); 038 static Logger loggerFocus = Logger.getLogger("gui.focus"); 039 040 // substance and field are required so that we can register and 041 // unregister ourself from fieldUpdated events on close() 042 Object substance; 043 FieldItem field; 044 MethodItem setter; 045 Object value; 046 boolean isEmbedded; 047 ClassItem type; 048 049 public AbstractFieldEditor(Object substance, FieldItem field) { 050 this.substance = substance; 051 setField(field); 052 addFocusListener(this); 053 } 054 055 public void fieldUpdated(Object object, FieldItem field, 056 Object value, Object param) { 057 setValue(value); 058 } 059 060 public abstract Object getValue(); 061 062 public void setValue(Object value) { 063 this.value = value; 064 } 065 066 public void setField(FieldItem field) { 067 Utils.unregisterField(substance,this.field,this); 068 this.field = field; 069 Utils.registerField(substance,this.field,this); 070 if (field!=null) 071 this.setter = field.getSetter(); 072 } 073 074 public FieldItem getField() { 075 return field; 076 } 077 078 public void setSubstance(Object substance) { 079 logger.debug("setSubstance("+substance+")"); 080 this.substance = substance; 081 } 082 083 /** 084 * Returns the object that holds the field, if any 085 */ 086 public Object getSubstance() { 087 return substance; 088 } 089 090 public void setEditedType(ClassItem type) { 091 this.type = type; 092 } 093 094 public void setEmbedded(boolean isEmbedded) { 095 this.isEmbedded = isEmbedded; 096 if (isEmbedded) 097 Utils.registerField(substance,field,this); 098 else 099 Utils.unregisterField(substance,field,this); 100 } 101 102 public void setAutoUpdate(boolean autoUpdate) { 103 // TODO 104 } 105 106 public void close(boolean validate) { 107 Utils.unregisterField(substance,field,this); 108 if (validate) 109 commit(); 110 substance = null; 111 super.close(validate); 112 } 113 114 public void onSetFocus(Object extraOption) {} 115 116 /** 117 * Commit editing by calling the setter method. 118 */ 119 public void commit() { 120 if (setter!=null && valueHasChanged()) { 121 logger.debug("value changed for "+substance+"."+field.getName()); 122 try { 123 field.setThroughWriter(substance,getValue()); 124 } catch (IllegalAccessException e) { 125 logger.error("Failed to commit value "+getValue()+ 126 " for field "+substance+"."+field,e); 127 } catch (Exception e) { 128 throw new CommitException(e,substance,field); 129 } 130 value = getValue(); 131 } 132 } 133 134 /** 135 * Tells wether the value in the editor was changed 136 */ 137 boolean valueHasChanged() { 138 Object newValue = getValue(); 139 boolean ret; 140 if (value == null && newValue != null) { 141 ret = true; 142 } else if (value == null) { 143 ret = false; 144 } else { 145 ret = ! value.equals(newValue); 146 } 147 logger.debug("valueHasChanged("+field.getName()+") "+ 148 value+" / "+newValue+" -> "+ret); 149 return ret; 150 } 151 152 // FocusListener interface 153 154 public void focusGained(FocusEvent e) { 155 /** do nothing */ 156 loggerFocus.debug("focus gained on "+getClass().getName()); 157 } 158 159 public void focusLost(FocusEvent e) { 160 /** Update the object's field if needed. */ 161 loggerFocus.debug("focus lost on "+getClass().getName()); 162 // We must ignore the event if closed==true because susbtance 163 // is set to null 164 if (field!=null && isEmbedded && !closed) { 165 invokeInContext(this,"commit", new Object[]{}); 166 } else { 167 loggerFocus.debug("ignoring focusLost event"); 168 } 169 } 170 171 }