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 }