001    package org.springframework.richclient.dialog;
002    
003    import com.jgoodies.forms.factories.FormFactory;
004    import com.jgoodies.forms.layout.CellConstraints;
005    import com.jgoodies.forms.layout.ColumnSpec;
006    import com.jgoodies.forms.layout.FormLayout;
007    import com.jgoodies.forms.layout.RowSpec;
008    import org.springframework.richclient.application.Application;
009    import org.springframework.richclient.application.config.ApplicationObjectConfigurer;
010    import org.springframework.richclient.command.ActionCommand;
011    import org.springframework.richclient.command.CommandGroup;
012    import org.springframework.richclient.core.DescriptionConfigurable;
013    import org.springframework.richclient.core.Message;
014    import org.springframework.richclient.core.TitleConfigurable;
015    import org.springframework.richclient.util.GuiStandardUtils;
016    import org.springframework.richclient.widget.SelectionWidget;
017    import org.springframework.richclient.widget.TitledWidget;
018    import org.springframework.richclient.widget.Widget;
019    
020    import javax.swing.*;
021    import java.awt.*;
022    import java.beans.PropertyChangeListener;
023    
024    /**
025     * Allows to create an applicationDialog in which a given widget can be shown
026     *
027     * <p>
028     * Don't forget to set the parent component if the parent isn't the application window
029     * </p>
030     */
031    public class TitledWidgetApplicationDialog extends ApplicationDialog
032            implements
033            DescriptionConfigurable,
034                Messagable
035    {
036    
037        /** Default Id for ok command. */
038        public static final String OK_COMMAND_ID = "okCommand";
039    
040        /** Default Id for cancel command. */
041        public static final String CANCEL_COMMAND_ID = "cancelCommand";
042    
043        /** Default Id for exit command. */
044        public static final String EXIT_COMMAND_ID = "exit";
045    
046        /** Default Id for select command. */
047        public static final String SELECT_COMMAND_ID = "select";
048    
049        /** Default Id for select command. */
050        public static final String SELECT_NONE_COMMAND_ID = "selectNoneCommand";
051    
052        /** Ok-mode: OK + Finish button. */
053        public static final int OK_MODE = 1;
054    
055        /** Cancel-mode: Cancel button. */
056        public static final int CANCEL_MODE = 2;
057    
058        /** Select-mode: Select + Cancel button. */
059        public static final int SELECT_CANCEL_MODE = 3;
060    
061        private final Widget widget;
062    
063        private final int mode;
064    
065        private final String finishId;
066    
067        private final String cancelId;
068    
069        private final String titledWidgetId;
070    
071        private ActionCommand selectNoneCommand;
072    
073        /**
074         * Create dialog with only OK button
075         *
076         * @param widget
077         *            The widget to show in the dialog
078         */
079        public TitledWidgetApplicationDialog(Widget widget)
080        {
081            this(widget, OK_MODE);
082        }
083    
084        /**
085         * Create dialog in specified mode
086         *
087         * @param widget
088         *            The widget to show in the dialog
089         * @param mode
090         *            The mode of the dialog:
091         *            <code>OK_MODE, CANCEL_MODE of SELECT_CANCEL_MODE</code>.
092         */
093        public TitledWidgetApplicationDialog(Widget widget, int mode)
094        {
095            this(widget, mode, mode == SELECT_CANCEL_MODE ? SELECT_COMMAND_ID : EXIT_COMMAND_ID, EXIT_COMMAND_ID);
096        }
097    
098        /**
099         * Creation of dialog with full configuration
100         *
101         * @param widget
102         *            The widget to show in the dialog
103         * @param mode
104         *            The mode of the dialog:
105         *            <code>OK_MODE, CANCEL_MODE of SELECT_CANCEL_MODE</code>.
106         * @param finishId
107         *            specific id for the finish command
108         * @param cancelId
109         *            specific id for the cancel command.
110         */
111        public TitledWidgetApplicationDialog(Widget widget, int mode, String finishId, String cancelId)
112        {
113            this.widget = widget;
114            this.mode = mode;
115            this.finishId = finishId;
116            this.cancelId = cancelId;
117            if (widget instanceof TitledWidget)
118                this.titledWidgetId = ((TitledWidget) widget).getId();
119            else
120                this.titledWidgetId = null;
121        }
122    
123        public Widget getWidget()
124        {
125            return this.widget;
126        }
127    
128        protected JComponent createButtonBar()
129        {
130            CommandGroup widgetCommands = CommandGroup.createCommandGroup(null, widget.getCommands());
131            CommandGroup dialogCommands = CommandGroup.createCommandGroup(getCommandGroupMembers());
132            JPanel panel = new JPanel(new FormLayout(new ColumnSpec[]{FormFactory.DEFAULT_COLSPEC,
133                    FormFactory.GLUE_COLSPEC, FormFactory.UNRELATED_GAP_COLSPEC, FormFactory.DEFAULT_COLSPEC},
134                    new RowSpec[]{FormFactory.DEFAULT_ROWSPEC}));
135            CellConstraints cc = new CellConstraints();
136            panel.add(widgetCommands.createButtonBar(), cc.xy(1, 1));
137            panel.add(dialogCommands.createButtonBar(), cc.xy(4, 1));
138            panel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10));
139            return panel;
140        }
141    
142        protected Object[] getCommandGroupMembers()
143        {
144            if (this.mode == SELECT_CANCEL_MODE)
145                return new Object[]{getFinishCommand(), getSelectNoneCommand(), getCancelCommand()};
146            if (this.mode == OK_MODE)
147                return new Object[]{getFinishCommand()};
148            if (this.mode == CANCEL_MODE)
149                return new Object[]{getCancelCommand()};
150            return new Object[]{getCancelCommand()};
151        }
152    
153        protected ActionCommand getSelectNoneCommand()
154        {
155            if (selectNoneCommand == null)
156            {
157                    selectNoneCommand = new ActionCommand(getSelectNoneCommandId()) {
158                            public void doExecuteCommand() {
159                                    onSelectNone();
160                            }
161                    };
162                    selectNoneCommand.setSecurityControllerId(getFinishSecurityControllerId());
163            }
164            return selectNoneCommand;
165        }
166    
167        private String getSelectNoneCommandId() {
168                    return SELECT_NONE_COMMAND_ID;
169            }
170    
171        protected void addDialogComponents()
172        {
173            JComponent dialogContentPane = createDialogContentPane();
174            if (getPreferredSize() != null)
175            {
176                dialogContentPane.setSize(getPreferredSize());
177            }
178            if (!(this.widget instanceof TitledWidget))
179            {
180                GuiStandardUtils.attachDialogBorder(dialogContentPane);
181            }
182            getDialogContentPane().add(dialogContentPane);
183            getDialogContentPane().add(createButtonBar(), BorderLayout.SOUTH);
184            if (this.titledWidgetId != null)
185                ((ApplicationObjectConfigurer) Application.services().getService(
186                        ApplicationObjectConfigurer.class)).configure(this.widget, this.titledWidgetId);
187        }
188    
189        protected void onAboutToShow()
190        {
191            super.onAboutToShow();
192            if (this.mode == SELECT_CANCEL_MODE && widget instanceof SelectionWidget)
193                ((SelectionWidget) widget).setSelectionCommand(getFinishCommand());
194            widget.onAboutToShow();
195        }
196    
197        protected void onWindowClosing()
198        {
199            widget.onAboutToHide();
200            if (this.mode == SELECT_CANCEL_MODE && widget instanceof SelectionWidget)
201                ((SelectionWidget) widget).removeSelectionCommand();
202            super.onWindowClosing();
203        }
204    
205        protected boolean onFinish()
206        {
207            return true;
208        }
209    
210            /**
211             * Hook called upon executing the select none command. This should normally
212             * de-select anything and execute the finish behaviour.
213             *
214             * @return
215             */
216        protected boolean onSelectNone()
217        {
218                    getFinishCommand().execute();
219                    return true;
220        }
221    
222        /**
223         * {@inheritDoc}
224         */
225        protected JComponent createDialogContentPane()
226        {
227            return widget.getComponent();
228        }
229    
230        /**
231         * {@inheritDoc}
232         */
233        public void setTitle(String title)
234        {
235            super.setTitle(title);
236            if ((this.widget instanceof TitleConfigurable) && (this.titledWidgetId == null))
237                ((TitleConfigurable) this.widget).setTitle(title);
238        }
239    
240        /**
241         * {@inheritDoc}
242         */
243        protected String getFinishCommandId()
244        {
245            return this.finishId;
246        }
247    
248        /**
249         * {@inheritDoc}
250         */
251        protected String getCancelCommandId()
252        {
253            return this.cancelId;
254        }
255    
256        /**
257         * {@inheritDoc}
258         */
259        public void setCaption(String shortDescription)
260        {
261            if (this.widget instanceof DescriptionConfigurable)
262                ((DescriptionConfigurable) this.widget).setCaption(shortDescription);
263        }
264    
265        /**
266         * {@inheritDoc}
267         */
268        public void setDescription(String longDescription)
269        {
270            if (this.widget instanceof DescriptionConfigurable)
271                ((DescriptionConfigurable) this.widget).setDescription(longDescription);
272        }
273    
274        /**
275         * {@inheritDoc}
276         */
277        public void setMessage(Message message)
278        {
279            if (this.widget instanceof Messagable)
280                ((Messagable) this.widget).setMessage(message);
281        }
282    
283        /**
284         * {@inheritDoc}
285         */
286        public void addPropertyChangeListener(PropertyChangeListener propertyChangeListener)
287        {
288            if (this.widget instanceof Messagable)
289                ((Messagable) this.widget).addPropertyChangeListener(propertyChangeListener);
290        }
291    
292        /**
293         * {@inheritDoc}
294         */
295        public void addPropertyChangeListener(String property, PropertyChangeListener propertyChangeListener)
296        {
297            if (this.widget instanceof Messagable)
298                ((Messagable) this.widget).addPropertyChangeListener(property, propertyChangeListener);
299        }
300    
301        /**
302         * {@inheritDoc}
303         */
304        public void removePropertyChangeListener(PropertyChangeListener propertyChangeListener)
305        {
306            if (this.widget instanceof Messagable)
307                ((Messagable) this.widget).removePropertyChangeListener(propertyChangeListener);
308        }
309    
310        /**
311         * {@inheritDoc}
312         */
313        public void removePropertyChangeListener(String property, PropertyChangeListener propertyChangeListener)
314        {
315            if (this.widget instanceof Messagable)
316                ((Messagable) this.widget).removePropertyChangeListener(property, propertyChangeListener);
317        }
318    }