001    package org.springframework.richclient.form;
002    
003    import org.springframework.richclient.application.config.ApplicationObjectConfigurer;
004    import org.springframework.richclient.components.Focussable;
005    import org.springframework.richclient.widget.AbstractWidgetForm;
006    import org.springframework.richclient.util.RcpSupport;
007    import org.springframework.binding.form.FormModel;
008    import org.springframework.binding.form.HierarchicalFormModel;
009    import org.springframework.binding.value.ValueModel;
010    
011    import javax.swing.*;
012    import java.awt.*;
013    
014    /**
015     * Form implementation for the Focussable interface.
016     *
017     * @author Jan Hoskens
018     *
019     */
020    public abstract class AbstractFocussableForm extends AbstractWidgetForm implements Focussable//, SecurityControllable
021    {
022    
023        public static final String UNSAVEDCHANGES_WARNING_ID = "unsavedchanges.warning";
024    
025        public static final String UNSAVEDCHANGES_HASERRORS_WARNING_ID = "unsavedchanges.haserrors.warning";
026    
027        private JComponent focusControl;
028    
029        private final Runnable focusRequestRunnable = new Runnable()
030        {
031    
032            public void run()
033            {
034                if (focusControl != null)
035                    focusControl.requestFocusInWindow();
036            }
037        };
038    
039        /**
040         * Override to do nothing. Superclass registers a default command, but we are using a different system to
041         * define default commands.
042         */
043        @Override
044        protected void handleEnabledChange(boolean enabled)
045        {
046        }
047    
048        /**
049         * Registers the component that receives the focus when the form receives focus.
050         *
051         * @see #grabFocus
052         */
053        public void setFocusControl(JComponent field)
054        {
055            this.focusControl = field;
056        }
057    
058        public void grabFocus()
059        {
060            if (this.focusControl != null)
061                EventQueue.invokeLater(focusRequestRunnable);
062        }
063    
064        /**
065         * @inheritDoc
066         */
067        public AbstractFocussableForm()
068        {
069            super();
070        }
071    
072        /**
073         * @inheritDoc
074         */
075        public AbstractFocussableForm(FormModel formModel, String formId)
076        {
077            super(formModel, formId);
078        }
079    
080        /**
081         * @inheritDoc
082         */
083        public AbstractFocussableForm(FormModel pageFormModel)
084        {
085            super(pageFormModel);
086        }
087    
088        /**
089         * @inheritDoc
090         */
091        public AbstractFocussableForm(HierarchicalFormModel parentFormModel, String formId,
092                String childFormObjectPropertyPath)
093        {
094            super(parentFormModel, formId, childFormObjectPropertyPath);
095        }
096    
097        /**
098         * @inheritDoc
099         */
100        public AbstractFocussableForm(HierarchicalFormModel parentFormModel, String formId,
101                ValueModel childFormObjectHolder)
102        {
103            super(parentFormModel, formId, childFormObjectHolder);
104        }
105    
106        /**
107         * @inheritDoc
108         */
109        public AbstractFocussableForm(HierarchicalFormModel parentFormModel, String formId)
110        {
111            super(parentFormModel, formId);
112        }
113    
114        /**
115         * @inheritDoc
116         */
117        public AbstractFocussableForm(Object formObject)
118        {
119            super(formObject);
120        }
121    
122        /**
123         * @inheritDoc
124         */
125        public AbstractFocussableForm(String formId)
126        {
127            super(formId);
128        }
129    
130        public boolean canClose()
131        {
132            boolean userBreak = false;
133            int answer = JOptionPane.NO_OPTION; // by default no save is required.
134    
135            // unless of course there are unsaved changes and we can commit (isAuthorized)
136            if (this.getFormModel().isEnabled() && this.getFormModel().isDirty()
137                    && this.getCommitCommand().isAuthorized())
138            { // then we ask the user to save the mess first: yes/no/cancel
139                answer = RcpSupport.showWarningDialog(this.getControl(), UNSAVEDCHANGES_WARNING_ID,
140                        JOptionPane.YES_NO_CANCEL_OPTION);
141    
142                switch (answer)
143                {
144                    case JOptionPane.CANCEL_OPTION :
145                        // backup the selection change so table and detail keep in sync
146                        // gives problems (asks unsavedchanges twice)
147                        userBreak = true;
148                        break;
149                    case JOptionPane.YES_OPTION :
150                        if (this.getFormModel().getHasErrors() == true)
151                        {
152                            RcpSupport.showWarningDialog(this.getControl(), UNSAVEDCHANGES_HASERRORS_WARNING_ID);
153                            userBreak = true;
154                            break;
155                        }
156                        this.getCommitCommand().execute();
157                        break;
158                    case JOptionPane.NO_OPTION :
159                    {
160                        this.revert(); // revert so no strange things happen (hopefully)
161                        break;
162                    }
163                }
164            }
165    
166            return !userBreak;
167        }
168    
169        @Override
170        protected void init()
171        {
172            // eerst wordt parent object constructor opgeroepen waarin deze init
173            // wordt opgeroepen. Gewone fields zijn dan nog niet gezet dus doe dat
174            // hier expliciet ipv in velddeclaratie.
175    //        authorized = true;
176    //        enabled = true;
177    //        setSecurityControllerId(getId() + ".authorize");
178            ((ApplicationObjectConfigurer) getApplicationServices().getService(ApplicationObjectConfigurer.class))
179                    .configure(this, getId());
180        }
181    }
182