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 }