001    /*
002      Copyright (C) 2001-2003 Renaud Pawlak <renaud@aopsys.com>, 
003                              Laurent Martelli <laurent@aopsys.com>
004      
005      This program is free software; you can redistribute it and/or modify
006      it under the terms of the GNU Lesser General Public License as
007      published by the Free Software Foundation; either version 2 of the
008      License, or (at your option) any later version.
009    
010      This program is distributed in the hope that it will be useful, but
011      WITHOUT ANY WARRANTY; without even the implied warranty of
012      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013      Lesser General Public License for more details.
014    
015      You should have received a copy of the GNU Lesser General Public
016      License along with this program; if not, write to the Free Software
017      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
018      USA */
019    
020    package org.objectweb.jac.aspects.gui.swing;
021    
022    import java.awt.Dimension;
023    import java.awt.Insets;
024    import java.awt.event.ActionEvent;
025    import java.awt.event.ActionListener;
026    import java.awt.event.ItemEvent;
027    import java.awt.event.ItemListener;
028    import javax.swing.JButton;
029    import javax.swing.JComboBox;
030    import org.apache.log4j.Logger;
031    import org.objectweb.jac.aspects.gui.*;
032    import org.objectweb.jac.core.Collaboration;
033    import org.objectweb.jac.core.Wrappee;
034    import org.objectweb.jac.core.rtti.FieldItem;
035    
036    /**
037     * This is a special value editor that allows the user to choose a
038     * value within a set of object of a given type. */
039    
040    public class ObjectChooser extends AbstractFieldEditor
041        implements ActionListener, ItemListener, ReferenceEditor
042    {
043        static Logger logger = Logger.getLogger("gui.chooser");
044    
045        JComboBox choice;
046        ComboBoxModel model;
047        JButton viewButton;
048        JButton newButton;
049    
050        /**
051         * Constructs a new object chooser.
052         */
053    
054        public ObjectChooser(Object substance, FieldItem reference, 
055                             ComboBoxModel model, boolean isEditable) 
056        {
057            super(substance,reference);
058    
059            this.model = model;
060            this.isEditable = isEditable;
061            choice = new JComboBox(model);
062    
063            boolean isWrappee = model.getType()!=null &&
064                Wrappee.class.isAssignableFrom(model.getType().getActualClass());
065            choice.setEditable(isEditable && !isWrappee);
066    
067            // This is a very dirty hack to get the real data component since
068            // JComboBox does not fire the focus events (certainly a bug in 
069            // JDK 1.3
070    
071            /*
072              if(isEditable) {
073              choice.getComponent(2).addFocusListener(this);
074              choice.addFocusListener(this);
075              } else {
076            */
077          
078            choice.getComponent(0).addFocusListener(this);
079            choice.addFocusListener(this);
080          
081            /*
082              }
083            */
084    
085            add(choice);
086            //choice.addActionListener(this);
087            choice.addItemListener(this);
088          
089            // Fill stupid height
090            Dimension minSize = choice.getPreferredSize();
091            Dimension maxSize = choice.getMaximumSize();
092            choice.setMaximumSize(new Dimension(maxSize.width,minSize.height));
093    
094            Boolean small_view = (Boolean) Collaboration.get().
095                getAttribute(GuiAC.SMALL_VIEW);
096    
097            if ((small_view == null) || (!small_view.booleanValue())) {
098                if (isWrappee) {
099                    viewButton = new JButton (ResourceManager.getIconResource("view_icon"));
100                    viewButton.setToolTipText("View");
101                    viewButton.setActionCommand("open");
102                    viewButton.addActionListener(this);
103                    viewButton.setMargin(new Insets(1,1,1,1));
104                    add(viewButton);
105                }
106    
107                if (isWrappee && isEditable && model.getType()!=null && 
108                    GuiAC.isCreatable(model.getType())) {
109                    newButton = new JButton(ResourceManager.getIconResource("new_icon"));
110                    newButton.setToolTipText("New");
111                    newButton.setActionCommand("new");
112                    newButton.addActionListener(this);
113                    newButton.setMargin(new Insets(1,1,1,1));
114                    add(newButton);
115                }
116            }
117        }
118    
119        public void setFocus(FieldItem field, Object extraOption) {}
120    
121    
122        // FieldEditor interface
123    
124        public void setValue(Object value) {
125            super.setValue(value);
126            model.setSelectedObject(value);
127          
128            if (value==null && viewButton!=null) 
129                viewButton.setEnabled(false);
130        }
131    
132        public Object getValue() {
133            logger.debug("selectedItem = "+model.getSelectedObject());
134            return model.getSelectedObject();
135        }
136    
137        public void setWidth(int width) {
138            /*      Dimension dim = choice.getSize();
139                    Dimension newDim = new Dimension(width,(int)dim.getHeight());
140                    choice.setSize(newDim);*/
141            choice.setMaximumRowCount(width);
142        }
143    
144        public void setHeight(int height) {
145            Dimension dim = choice.getSize();
146            Dimension newDim = new Dimension((int)dim.getWidth(),height);
147            choice.setSize(newDim);
148        }
149       
150        public void close(boolean validate) {
151            super.close(validate);
152            model.close();
153        }
154    
155        /**
156         * Handles the actions performed by the users on this view.
157         *
158         * <p>On an object chooser, a "new" action can be performed to
159         * allow the user to add a new object to the choices it not present
160         * yet.
161         *
162         * @param event the performed action 
163         */
164        public void actionPerformed(ActionEvent event) {
165            loggerEvents.debug("actionPerformed: "+event.getActionCommand());
166            setContext();
167            if (event.getActionCommand().equals("new")) {
168                Object instance = 
169                    EventHandler.get().onCreateObject(
170                        context,model.getType(),substance,field);
171                if (instance!=null) {
172                    requestFocus();
173                    model.addObject(instance);
174                    model.setSelectedObject(instance);
175                }
176            } else if (event.getActionCommand().equals("open")) {
177                Object object = model.getSelectedObject();
178                if (object == null) 
179                    return;
180                if (object!=null) {
181                    EventHandler.get().onView(context,field,object,null,null);
182                }
183            }
184        }
185    
186        /**
187         * Set the focus on the JComboBox
188         */
189        public void requestFocus() {
190            choice.requestFocus();
191            loggerFocus.debug("focusing "+choice.getClass().getName());
192        }
193    
194        boolean isEditable = false;
195        public boolean isEditable() {
196            return isEditable;
197        }
198        public void setEditable(boolean editable) {
199            this.isEditable = editable;
200        }
201    
202        public ComboBoxModel getModel() {
203            return model;
204        }
205       
206        // ItemListener interface
207    
208        public void itemStateChanged(ItemEvent event) {
209            loggerEvents.debug("itemStateChanged on "+this);
210            if (field!=null && isEmbedded) {
211                invokeInContext(this,"commit", new Object[]{});
212            } else {
213                loggerEvents.debug("ignoring item event");
214            }      
215        }
216    }