package org.freehep.application.mdi; import java.awt.Component; import java.awt.Point; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.List; import javax.swing.Icon; import javax.swing.JComponent; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.event.EventListenerList; import org.freehep.application.Application; import org.freehep.util.commanddispatcher.CommandProcessor; import org.freehep.util.commanddispatcher.CommandState; import org.freehep.util.commanddispatcher.CommandSourceAdapter; import org.freehep.util.commanddispatcher.CommandTargetManager; /** * A PageManager manages a set of pages. * @author Tony Johnson (tonyj@slac.stanford.edu) * @version $Id: PageManager.java 8584 2006-08-10 23:06:37Z duns $ */ public abstract class PageManager { public PageContext openPage(Component c, String title, Icon icon) { return openPage(c, title, icon, null); } public PageContext openPage(Component c, String title, Icon icon, String type) { PageContext context = new PageContext(c,title,icon, type); context.setPageManager(this); pages.add(context); return context; } /** * Called whenever the page manager becomes, or ceases to be, in use. * Can be used to allocated and/or free-up resources used by the page manager. * @param active <CODE>true</CODE> if the page manager is becoming active, <CODE>false</CODE> if it is ceasing to be active */ protected void setActive(boolean active) { } protected void firePageOpened(PageContext context) { ManagedPage mp = getManagedPage(context.getPage()); if (mp != null) mp.setPageContext(context); firePageEvent(context,PageEvent.PAGEOPENED); getCommandProcessor().setChanged(); } ManagedPage getManagedPage(Component c) { if (c instanceof ManagedPage) return (ManagedPage) c; else if (c instanceof JScrollPane) { Component cc = ((JScrollPane) c).getViewport().getView(); if (cc instanceof ManagedPage) return (ManagedPage) cc; } return null; } public boolean closeAll() { return closeAll(null); } private boolean closeAll(String type) { Iterator i = new ArrayList(pages).iterator(); while (i.hasNext()) { PageContext tmpPage = (PageContext) i.next(); if ( type == null || tmpPage.type().equals(type) ) if (!close(tmpPage)) return false; } return true; } private boolean closeOther(PageContext page) { return closeOther(page,false); } private boolean closeOther(PageContext page, boolean byType) { Iterator i = new ArrayList(pages).iterator(); while (i.hasNext()) { PageContext tmpPage = (PageContext) i.next(); if ( tmpPage != page ) if ( !byType || tmpPage.type().equals(page.type()) ) if (!close(tmpPage) ) return false; } return true; } public int getPageCount() { return pages.size(); } private int getPageCount(String type) { if ( type == null ) return getPageCount(); int count = 0; Iterator i = new ArrayList(pages).iterator(); while (i.hasNext()) { PageContext tmpPage = (PageContext) i.next(); if ( tmpPage.type().equals(type) ) count++; } return count; } public PageContext getSelectedPage() { return selected; } protected abstract void show(PageContext page); protected boolean close(PageContext page) { ManagedPage mp = getManagedPage(page.getPage()); if (mp != null && !mp.close()) return false; pages.remove(page); if (page == selected) fireSelectionChanged(null); if (mp != null) mp.pageClosed(); firePageEvent(page,PageEvent.PAGECLOSED); getCommandProcessor().setChanged(); return true; } protected abstract void titleChanged(PageContext page); protected abstract void iconChanged(PageContext page); protected abstract Component getEmbodiment(); protected CommandProcessor createCommandProcessor() { return new PageManagerCommandProcessor(); } protected CommandProcessor getCommandProcessor() { if (commandProcessor == null) commandProcessor = createCommandProcessor(); return commandProcessor; } public List pages() { return pages; } protected void init(List pages, PageContext selected) { this.pages = pages; this.selected = selected; for (Iterator i = pages.iterator(); i.hasNext();) { PageContext page = (PageContext) i.next(); page.setPageManager(this); } } protected void fireSelectionChanged(PageContext context) { if ( selected != context ) { if (selected != null) { ManagedPage mp = getManagedPage(selected.getPage()); if (mp != null) mp.pageDeselected(); firePageEvent(selected,PageEvent.PAGEDESELECTED); } selected = context; if (context != null) { ManagedPage mp = getManagedPage(selected.getPage()); if (mp != null) mp.pageSelected(); firePageEvent(selected,PageEvent.PAGESELECTED); } getCommandProcessor().setChanged(); } } protected void firePageEvent(PageContext context, int id) { PageEvent event = new PageEvent(context,id); // System.out.println("Firing event "+event); if (listenerList != null) { PageListener[] listeners = (PageListener[]) listenerList.getListeners(PageListener.class); for (int i = 0; i<listeners.length; i++) { listeners[i].pageChanged(event); } } context.firePageEvent(event,id); } /** * Add a page listener to receive notifications of user initiated changes * * @param listener The PageListener to install */ public void addPageListener(PageListener listener) { if (listenerList == null) listenerList = new EventListenerList(); listenerList.add(PageListener.class,listener); } /** * Remove a previously installed PageListener * * @param listener The PageListener to remove */ public void removePageListener(PageListener listener) { listenerList.remove(PageListener.class,listener); } List getPageListenerList() { if (listenerList == null) return Collections.EMPTY_LIST; else return Arrays.asList(listenerList.getListeners(PageListener.class)); } void removeAllPageListeners() { listenerList = null; } protected JPopupMenu modifyPopupMenu(JPopupMenu menu,Component source,Point p) { CommandTargetManager cm = Application.getApplication().getCommandTargetManager(); ((MDIApplication)Application.getApplication()).setSelectedPageManager(this); String pageType = getSelectedPage() != null ? getSelectedPage().type() : null ; boolean hasType = pageType != null; JComponent closeMenu = new JMenu("Close"); if ( menu.getComponentCount() > 0 ) menu.addSeparator(); else closeMenu = menu; JMenuItem close = new JMenuItem(makeTitle("Close",false)); close.setActionCommand("closePage"); cm.add(new CommandSourceAdapter(close)); closeMenu.add(close); JMenuItem closeAll = new JMenuItem(makeTitle("Close All", true)); closeAll.setActionCommand("closeAllPages"); cm.add(new CommandSourceAdapter(closeAll)); closeMenu.add(closeAll); if ( hasType ) { JMenuItem closeAllByType = new JMenuItem(makeTitle("Close All "+pageType, true)); closeAllByType.setActionCommand("closeAllPagesByType"); cm.add(new CommandSourceAdapter(closeAllByType)); closeMenu.add(closeAllByType); } JMenuItem closeOther = new JMenuItem(makeTitle("Close Other", true)); closeOther.setActionCommand("closeOtherPages"); cm.add(new CommandSourceAdapter(closeOther)); closeMenu.add(closeOther); if ( hasType ) { JMenuItem closeOtherByType = new JMenuItem(makeTitle("Close Other "+pageType, true)); closeOtherByType.setActionCommand("closeOtherPagesByType"); cm.add(new CommandSourceAdapter(closeOtherByType)); closeMenu.add(closeOtherByType); } if ( menu != closeMenu ) menu.add(closeMenu); return menu; } private String makeTitle(String title, boolean plural) { if ( pageManagerType() == null ) return title; title = title+" "+pageManagerType(); if ( plural ) title += "s"; return title; } protected String pageManagerType() { return pageManagerType; } public void setPageManagerType(String type) { pageManagerType = type; } public class PageManagerCommandProcessor extends CommandProcessor { public void onCloseAllPages() { closeAll(); } public void enableCloseAllPages(CommandState state) { state.setEnabled(getPageCount() > 1); } public void onClosePage() { close(getSelectedPage()); } public void enableClosePage(CommandState state) { state.setEnabled(getSelectedPage() != null); } public void onCloseOtherPages() { closeOther(getSelectedPage()); } public void enableCloseOtherPages(CommandState state) { state.setEnabled(getPageCount() > 1); } public void onCloseAllPagesByType() { closeAll(getSelectedPage().type()); } public void enableCloseAllPagesByType(CommandState state) { state.setEnabled(getPageCount(getSelectedPage().type()) > 1); } public void onCloseOtherPagesByType() { closeOther(getSelectedPage(), true); } public void enableCloseOtherPagesByType(CommandState state) { state.setEnabled(getPageCount(getSelectedPage().type()) > 1); } } private String pageManagerType = null; private CommandProcessor commandProcessor; protected EventListenerList listenerList; private List pages = new ArrayList(); private PageContext selected; }