Java tutorial
/* * Copyright 2005 the original author or authors. Licensed under the Apache License, Version 2.0 (the "License"); you * may not use this file except in compliance with the License. You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific language governing permissions and limitations under the * License. */ package com.jidesoft.spring.richclient.docking; import java.awt.BorderLayout; import java.awt.Component; import java.awt.DefaultKeyboardFocusManager; import java.awt.KeyboardFocusManager; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.HashSet; import java.util.Set; import javax.swing.Icon; import javax.swing.JComponent; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.richclient.application.ApplicationServicesLocator; import org.springframework.richclient.application.ApplicationWindow; import org.springframework.richclient.application.PageComponent; import org.springframework.richclient.application.PageComponentPane; import org.springframework.richclient.application.PageDescriptor; import org.springframework.richclient.application.ViewDescriptor; import org.springframework.richclient.application.ViewDescriptorRegistry; import org.springframework.richclient.application.support.DefaultApplicationPage; import org.springframework.richclient.command.ActionCommand; import org.springframework.richclient.command.CommandManager; import org.springframework.richclient.image.IconSource; import com.jidesoft.docking.DockContext; import com.jidesoft.docking.DockableFrame; import com.jidesoft.docking.DockingManager; import com.jidesoft.docking.Workspace; import com.jidesoft.docking.event.DockableFrameAdapter; import com.jidesoft.docking.event.DockableFrameEvent; import com.jidesoft.spring.richclient.docking.view.JideAbstractView; import com.jidesoft.spring.richclient.docking.view.JideViewDescriptor; import com.jidesoft.spring.richclient.perspective.PerspectiveManager; /** * Spring RCP ApplicationPage implementation that simply delegates most things to the underlying docking manager. The * page is constructed from an instance of DockingPageDescriptor that specifies a list of Spring RCP View instances that * are added as docked windows, and a Spring RCP View instance for the workspace. * * @author Jonny Wray */ public class JideApplicationPage extends DefaultApplicationPage { private static final Log log = LogFactory.getLog(JideApplicationPage.class); private Set pageViews = new HashSet(); private JideApplicationWindow window; private PageComponent workspaceComponent; private JComponent control; public JideApplicationPage(ApplicationWindow window, PageDescriptor pageDescriptor) { super(window, pageDescriptor); if (log.isInfoEnabled()) { log.info("Constructing Application page " + pageDescriptor.getId()); } this.window = (JideApplicationWindow) window; KeyboardFocusManager.getCurrentKeyboardFocusManager().addPropertyChangeListener("focusOwner", new FocusOwnerChangeListener()); } public PerspectiveManager getPerspectiveManager() { return ((JidePageDescriptor) getPageDescriptor()).getPerspectiveManager(); } @Override public JComponent createControl() { if (this.control == null) { this.getPageDescriptor().buildInitialLayout(this); DockingManager manager = this.window.getDockingManager(); this.control = manager.getDockedFrameContainer(); Object initialEditorContents = ((JidePageDescriptor) getPageDescriptor()).getInitialEditorContents(); if (initialEditorContents != null) { openEditor(initialEditorContents); } } return this.control; } @Override protected void doRemovePageComponent(PageComponent pageComponent) { if (log.isDebugEnabled()) { log.debug("Removing " + pageComponent.getId()); } DockingManager manager = this.window.getDockingManager(); manager.removeFrame(pageComponent.getId()); } /** * This sets the visible flag on all show view commands that are registered with the command manager. If the page * contains the view the command is visible, otherwise not. The registration of the show view command with the * command manager is the responsibility of the view descriptor. */ public void updateShowViewCommands() { ViewDescriptorRegistry viewDescriptorRegistry = (ViewDescriptorRegistry) ApplicationServicesLocator .services().getService(ViewDescriptorRegistry.class); ViewDescriptor[] views = viewDescriptorRegistry.getViewDescriptors(); for (int i = 0; i < views.length; i++) { String id = views[i].getId(); CommandManager commandManager = this.window.getCommandManager(); if (commandManager.containsActionCommand(id)) { ActionCommand command = commandManager.getActionCommand(id); command.setVisible(this.pageViews.contains(views[i].getId())); } } } @Override protected boolean giveFocusTo(PageComponent pageComponent) { if (log.isDebugEnabled()) { log.debug("Giving focus to " + pageComponent.getId()); } PageComponentPane pane = pageComponent.getContext().getPane(); pane.getControl().requestFocusInWindow(); fireFocusGained(pageComponent); return true; } @Override public void showView(ViewDescriptor viewDescriptor) { if (log.isDebugEnabled()) { log.debug("Adding view for " + viewDescriptor.getId()); } JideViewDescriptor jvd = (JideViewDescriptor) viewDescriptor; super.showView(viewDescriptor); registerPageComponent(viewDescriptor.getId()); } @Override public void addView(String viewDescriptorId) { showView(viewDescriptorId); } /** * Implementation of the openEditor command using the editor factory injected into the page descriptor. The editor * input is used as the key the factory uses to get the requires editor descriptor. If not editor factory is * injected into the page descriptor then the default factory is used which simply returns null for every editor * object resulting in no editor being opened. */ // public void openEditor(Object editorInput){ // if(log.isDebugEnabled()){ // log.debug("Attempting to open editor for "+editorInput.getClass().getName()); // } // if(workspaceComponent == null){ // log.debug("WorkspaceComponent is null"); // return; // } // if(!(workspaceComponent instanceof WorkspaceView)){ // log.debug("WorkspaceComponent is not a workspace view"); // return; // } // PageDescriptor descriptor = getPageDescriptor(); // if(descriptor instanceof JidePageDescriptor){ // if(editorInput.getClass().isArray()){ // Object[] array = (Object[])editorInput; // for(int i=0;i<array.length;i++){ // Object editorObject = array[i]; // processEditorObject(editorObject); // } // } // else{ // processEditorObject(editorInput); // } // // } // } // private void processEditorObject(Object editorObject){ // JidePageDescriptor pageDescriptor = (JidePageDescriptor)getPageDescriptor(); // EditorDescriptor editorDescriptor = // pageDescriptor.getEditorFactory().getEditorDescriptor(editorObject); // if(editorDescriptor != null){ // PageComponent pageComponent = editorDescriptor.createPageComponent(); // AbstractEditor editor = (AbstractEditor)pageComponent; // editor.initialize(editorObject); // EditorComponentPane editorPane = new EditorComponentPane(pageComponent); // pageComponent.setContext(new DefaultViewContext(this, editorPane)); // WorkspaceView workspace = (WorkspaceView)workspaceComponent; // workspace.addDocumentComponent(pageComponent); // // Fires lifecycle event so listeners can react to editor // // being opened. // LifecycleApplicationEvent event = new LifecycleApplicationEvent( // LifecycleApplicationEvent.CREATED, editor); // Application.instance().getApplicationContext().publishEvent(event); // } // } private void registerPageComponent(String viewDescriptorId) { PageComponent pageComponent = findPageComponent(viewDescriptorId); ViewDescriptor descriptor = getViewDescriptor(viewDescriptorId); if (descriptor instanceof JideViewDescriptor) { JideViewDescriptor viewDescriptor = (JideViewDescriptor) descriptor; if (viewDescriptor.isWorkspace()) { registerWorkspaceView(pageComponent); } else { registerNormalView(pageComponent, viewDescriptor); this.pageViews.add(viewDescriptorId); } } else { registerNormalView(pageComponent, null); this.pageViews.add(viewDescriptorId); } } private void registerWorkspaceView(PageComponent pageComponent) { if (log.isInfoEnabled()) { log.info("Registering workspace view " + pageComponent.getId()); } DockingManager manager = this.window.getDockingManager(); manager.getWorkspace().add(pageComponent.getControl()); this.workspaceComponent = pageComponent; } private void registerNormalView(PageComponent pageComponent, JideViewDescriptor viewDescriptor) { if (log.isInfoEnabled()) { log.info("Registering view " + pageComponent.getId()); } DockingManager manager = this.window.getDockingManager(); String frameName = pageComponent.getId(); if (manager.getAllFrameNames().contains(frameName)) { if (log.isDebugEnabled()) { log.debug("Showing existing docked frame " + frameName); } DockContext currentContext = manager.getContextOf(frameName); if (currentContext.isHidden() || currentContext.getAvailablePreviousState() == null) // mscoon 15/8/2010 - added this clause because otherwise initially hidden views were not being shown { if (viewDescriptor.isFloatOnShow()) { manager.floatFrame(frameName, viewDescriptor.getFloatBounds(), true); } else { manager.showFrame(frameName); } } else { manager.activateFrame(frameName); } } else { if (log.isDebugEnabled()) { log.debug("Adding new dockable frame " + frameName); } manager.addFrame(createDockableFrame(pageComponent, viewDescriptor)); } } protected DockableFrame createDockableFrame(final PageComponent pageComponent, JideViewDescriptor viewDescriptor) { if (log.isInfoEnabled()) { log.info("Creating dockable frame for page component " + pageComponent.getId()); } Icon icon = pageComponent.getIcon(); if (icon == null) { IconSource iconSource = (IconSource) ApplicationServicesLocator.services().getService(IconSource.class); icon = iconSource.getIcon("applicationInfo.image"); } DockableFrame dockableFrame = new DockableFrame(pageComponent.getId(), icon); dockableFrame.setTitle(pageComponent.getDisplayName()); dockableFrame.setTabTitle(pageComponent.getDisplayName()); dockableFrame.setFrameIcon(icon); if (viewDescriptor != null) { dockableFrame.getContext().setInitMode(viewDescriptor.getInitMode()); dockableFrame.getContext().setInitSide(viewDescriptor.getInitSide()); dockableFrame.getContext().setInitIndex(viewDescriptor.getInitIndex()); } else { dockableFrame.getContext().setInitMode(DockContext.STATE_FRAMEDOCKED); dockableFrame.getContext().setInitSide(DockContext.DOCK_SIDE_EAST); dockableFrame.getContext().setInitIndex(0); } dockableFrame.addDockableFrameListener(new DockableFrameAdapter() { @Override public void dockableFrameRemoved(DockableFrameEvent event) { if (log.isDebugEnabled()) { log.debug("Frame removed event on " + pageComponent.getId()); } fireClosed(pageComponent); } @Override public void dockableFrameActivated(DockableFrameEvent e) { if (log.isDebugEnabled()) { log.debug("Frame activated event on " + pageComponent.getId()); } fireFocusLost(JideApplicationPage.this.workspaceComponent); fireFocusGained(pageComponent); } @Override public void dockableFrameDeactivated(DockableFrameEvent e) { if (log.isDebugEnabled()) { log.debug("Frame deactivated event on " + pageComponent.getId()); } fireFocusLost(pageComponent); } }); dockableFrame.getContentPane().setLayout(new BorderLayout()); dockableFrame.getContentPane().add(pageComponent.getControl()); // This is where the view specific toolbar and menu bar get added. Note, // that this is different from the editors. With the views they are part // of the dockable frame, but with editors we add them to the editor // pane itself in EditorComponentPane if (pageComponent instanceof JideAbstractView) { JideAbstractView view = (JideAbstractView) pageComponent; dockableFrame.setTitleBarComponent(view.getViewToolBar()); dockableFrame.setJMenuBar(view.getViewMenuBar()); final DockableFrame ff = dockableFrame; view.getDescriptor().addPropertyChangeListener("title", new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { ff.setTitle(evt.getNewValue().toString()); ff.setTabTitle(pageComponent.getDisplayName()); } }); } return dockableFrame; } /* * These next four methods change the access from protected to public allowing non children to fire these events. * This is needs to allow the Jide events to translate into spring events */ @Override public void fireClosed(PageComponent component) { super.fireClosed(component); } @Override public void fireOpened(PageComponent component) { super.fireOpened(component); } @Override public void fireFocusLost(PageComponent component) { if (component != null) { super.fireFocusLost(component); } } @Override public void fireFocusGained(PageComponent component) { if (component != null) { super.fireFocusGained(component); } } /* * This listener (registered in the constructor on the DefaultKeyboardFocusManager) is here to deal with one odd * case in the JIDE to Spring RCP event translation. If a document tab is clicked after a specific view was active, * a documentComponentActivated event is not fired (I'm not really sure why not) causing the spring rcp command * framework not to follow the active frame/document. This overcomes that problem. The link documents the JIDE forum * thread discussing this. http://www.jidesoft.com/forum/viewtopic.php?t=2722 */ private class FocusOwnerChangeListener implements PropertyChangeListener { @Override public void propertyChange(PropertyChangeEvent evt) { DefaultKeyboardFocusManager manager = (DefaultKeyboardFocusManager) evt.getSource(); Component focusOwner = manager.getFocusOwner(); Workspace workspace = (Workspace) getDockableWorkspace(focusOwner); // if( workspace != null){ // if(logger.isDebugEnabled()){ // logger.debug("About to fire focus gained on the active workspace component"); // } // WorkspaceView workspaceView = (WorkspaceView)workspaceComponent; // workspaceView.fireFocusGainedOnActiveComponent(); // } } private Component getDockableWorkspace(Component c) { if (c == null) return null; if (c instanceof Workspace) return c; do { c = c.getParent(); if (c == null) return null; } while (!(c instanceof Workspace)); return c; } } protected PageComponent getWorkspaceComponent() { return this.workspaceComponent; } protected void setWorkspaceComponent(PageComponent workspaceComponent) { this.workspaceComponent = workspaceComponent; } }