001    /*
002     * Copyright 2002-2007 the original author or authors.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005     * use this file except in compliance with the License. You may obtain a copy of
006     * the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013     * License for the specific language governing permissions and limitations under
014     * the License.
015     */
016    package org.springframework.richclient.application.mdi;
017    
018    import org.springframework.richclient.application.*;
019    import org.springframework.richclient.application.mdi.contextmenu.DesktopCommandGroupFactory;
020    import org.springframework.richclient.application.support.AbstractApplicationPage;
021    import org.springframework.richclient.util.Assert;
022    import org.springframework.richclient.util.PopupMenuMouseListener;
023    
024    import javax.swing.*;
025    import javax.swing.event.InternalFrameAdapter;
026    import javax.swing.event.InternalFrameEvent;
027    import java.beans.PropertyVetoException;
028    import java.util.HashMap;
029    import java.util.Map;
030    
031    /**
032     * @author Peter De Bruycker
033     */
034    public class DesktopApplicationPage extends AbstractApplicationPage implements PageLayoutBuilder {
035    
036            private JDesktopPane control;
037    
038            private Map frames = new HashMap();
039    
040            private int dragMode;
041    
042        private boolean scrollable = true;
043    
044        private final DesktopCommandGroupFactory desktopCommandGroupFactory;
045    
046            public DesktopApplicationPage(ApplicationWindow window, PageDescriptor pageDescriptor, int dragMode,
047                            DesktopCommandGroupFactory desktopCommandGroupFactory) {
048                    super(window, pageDescriptor);
049                    this.desktopCommandGroupFactory = desktopCommandGroupFactory;
050    
051                    Assert.isTrue(dragMode == JDesktopPane.LIVE_DRAG_MODE || dragMode == JDesktopPane.OUTLINE_DRAG_MODE,
052                                    "dragMode must be JDesktopPane.LIVE_DRAG_MODE or JDesktopPane.OUTLINE_DRAG_MODE");
053    
054                    this.dragMode = dragMode;
055            }
056    
057        public void setScrollable(boolean scrollable) {
058            if (isControlCreated()) {
059                throw new IllegalStateException("scrollable-property can only be set before creation of control");
060            }
061            this.scrollable = scrollable;
062        }
063    
064            protected boolean giveFocusTo(PageComponent pageComponent) {
065                    if (getActiveComponent() == pageComponent) {
066                            return true;
067                    }
068    
069                    JInternalFrame frame = getInternalFrame(pageComponent);
070                    if (frame == null) {
071                            return false;
072                    }
073    
074                    try {
075                            if (frame.isIcon()) {
076                                    frame.setIcon(false);
077                            }
078    
079                            frame.setSelected(true);
080                    }
081                    catch (PropertyVetoException e) {
082                            // ignore
083                    }
084    
085                    return pageComponent.getControl().requestFocusInWindow();
086            }
087    
088            public void addView(String viewDescriptorId) {
089                    showView(viewDescriptorId);
090            }
091    
092            protected void doAddPageComponent(PageComponent pageComponent) {
093                    JInternalFrame frame = createInternalFrame(pageComponent);
094    
095                    frame.setVisible(true);
096                    control.add(frame);
097            }
098    
099            protected JInternalFrame createInternalFrame(final PageComponent pageComponent) {
100                    JInternalFrame internalFrame = new JInternalFrame(pageComponent.getDisplayName());
101                    internalFrame.setDefaultCloseOperation(JInternalFrame.DO_NOTHING_ON_CLOSE);
102    
103                    configureFrame(pageComponent, internalFrame);
104    
105                    keepFrameDetails(pageComponent, internalFrame);
106    
107                    internalFrame.addInternalFrameListener(new InternalFrameAdapter() {
108                            public void internalFrameClosing(InternalFrameEvent e) {
109                                    close(pageComponent);
110                            }
111    
112                            public void internalFrameActivated(InternalFrameEvent e) {
113                                    if (!e.getInternalFrame().isIcon()) {
114                                            setActiveComponent(pageComponent);
115                                    }
116                            }
117                    });
118    
119                    internalFrame.getContentPane().add(pageComponent.getControl());
120                    internalFrame.pack();
121                    return internalFrame;
122            }
123    
124        /**
125         * Having this method allows subclasses to enrich/wrap the internal frame, for instance with a visible resizer.
126         */
127        protected void keepFrameDetails(final PageComponent pageComponent, JInternalFrame internalFrame) {
128            frames.put(pageComponent, internalFrame);
129        }
130    
131        protected void configureFrame(PageComponent component, JInternalFrame frame) {
132                    if (component.getIcon() != null) {
133                            frame.setFrameIcon(component.getIcon());
134                    }
135    
136                    ViewDescriptor descriptor = getViewDescriptor(component.getId());
137                    if (descriptor instanceof DesktopViewDescriptor) {
138                            DesktopViewDescriptor desktopViewDescriptor = (DesktopViewDescriptor) descriptor;
139                            frame.setResizable(desktopViewDescriptor.isResizable());
140                            frame.setMaximizable(desktopViewDescriptor.isMaximizable());
141                            frame.setIconifiable(desktopViewDescriptor.isIconifiable());
142                            frame.setClosable(desktopViewDescriptor.isClosable());
143                    }
144                    else {
145                            frame.setResizable(true);
146                            frame.setMaximizable(true);
147                            frame.setIconifiable(true);
148                            frame.setClosable(true);
149                    }
150            }
151    
152            protected JInternalFrame getInternalFrame(PageComponent pageComponent) {
153                    return (JInternalFrame) frames.get(pageComponent);
154            }
155    
156            protected void doRemovePageComponent(PageComponent pageComponent) {
157                    // not used
158                    JInternalFrame frame = getInternalFrame(pageComponent);
159                    if (frame != null) {
160                            frame.dispose();
161                            frames.remove(pageComponent);
162                    }
163            }
164    
165            protected JComponent createControl() {
166                    control = createDesktopPane();
167                    control.setDragMode(dragMode);
168    
169                    getPageDescriptor().buildInitialLayout(this);
170    
171            if (scrollable) {
172                return new JScrollPane(control);
173            } else {
174                return control;
175            }
176            }
177            
178        protected JDesktopPane createDesktopPane() {
179            final JDesktopPane control;
180            if (scrollable) {
181                control = new ScrollingDesktopPane();
182            } else {
183                control = new JDesktopPane();
184            }
185            control.addMouseListener(new PopupMenuMouseListener() {
186                protected JPopupMenu getPopupMenu() {
187                    return desktopCommandGroupFactory.createContextMenuCommandGroup(getWindow().getCommandManager(),
188                            control).createPopupMenu();
189                }
190            });
191            return control; 
192        }
193    
194            protected void updatePageComponentProperties(PageComponent pageComponent) {
195                    JInternalFrame frame = getInternalFrame(pageComponent);
196    
197                    if (pageComponent.getIcon() != null) {
198                            frame.setFrameIcon(pageComponent.getIcon());
199                    }
200                    frame.setTitle(pageComponent.getDisplayName());
201                    frame.setToolTipText(pageComponent.getCaption());
202            }
203    
204            /**
205             * Overridden so it will leave iconified frames iconified.
206             */
207            protected void setActiveComponent() {
208                    // getAllFrames returns the frames in z-order (i.e. the first one in the
209                    // list is the last one used)
210                    JInternalFrame[] frames = control.getAllFrames();
211                    for (int i = 0; i < frames.length; i++) {
212                            JInternalFrame frame = frames[i];
213                            if (!frame.isIcon()) {
214                                    try {
215                                            frame.setSelected(true);
216                                    }
217                                    catch (PropertyVetoException ignore) {
218    
219                                    }
220                                    break;
221                            }
222                    }
223            }
224    }