package org.freehep.application.mdi;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import javax.swing.JSplitPane;
import javax.swing.JToolBar;
import org.freehep.application.Application;
import org.freehep.application.PropertyUtilities;
import org.freehep.util.commanddispatcher.BooleanCommandState;
import org.freehep.util.commanddispatcher.CommandProcessor;
/**
* Extends Application to provide MDI facilities.
* An MDI application controls three types of sub-windows
* <ul>
* <li>Pages
* <li>Consoles
* <li>Controls
* </ul>
* There is one PageManager for each type of window. Different PageManagers
* can be installed dynamically.
*
* @author Tony Johnson (tonyj@slac.stanford.edu)
* @version $Id: MDIApplication.java 8584 2006-08-10 23:06:37Z duns $
*/
public class MDIApplication extends Application
{
/** Creates new MDIApplication */
public MDIApplication(String appName)
{
super(appName);
// By default only the page area is visible
add(getPageManager().getEmbodiment());
}
protected void loadDefaultProperties(Properties app) throws IOException
{
super.loadDefaultProperties(app);
InputStream in = MDIApplication.class.getResourceAsStream("MDIDefault.properties");
app.load(in);
in.close();
}
protected void saveUserProperties()
{
Properties user = getUserProperties();
if (consoleSplit != null) PropertyUtilities.setInteger(user,"consoleSize",consoleSplit.getHeight() - consoleSplit.getDividerLocation());
if (controlSplit != null) PropertyUtilities.setInteger(user,"controlSize",controlSplit.getDividerLocation());
if (mdiToolBarHolder != null) mdiToolBarHolder.save(user);
super.saveUserProperties();
}
public static final int TOOLBAR_DEFAULT = 0;
public static final int TOOLBAR_INVISIBLE = 1;
public static final int TOOLBAR_VISIBLE = 2;
public static final int TOOLBAR_AUTO = 3;
public static final int TOOLBAR_PROGRAM = 4;
/**
* Adds a new toolbar to the toolbar area.
* You can attach any number of toolbars to an MDIApplication. Normally the
* user gets to choose which toolbars are visible or not, but this is controlled
* by the toolbar mode, which can be one of:
* <ul>
* <li>TOOLBAR_INVISIBLE - Toolbar is not shown
* <li>TOOLBAR_VISIBLE - Toolbar is shown
* <li>TOOLBAR_AUTO - Toolbar is shown only when at least one button is enabled
* <li>TOOLBAR_PROGRAM - Toolbar visibility is controlled by the program, not the user (not recommended)
* </ul>
* The user can override the default toolBar more, unless it is set to TOOLBAR_PROGRAM. If mode is omitted, or
* set to TOOLBAR_DEFAULT, it is controlled by the application properties.
*
* @param toolBar The JToolBar to add
* @param name The name of the toolbar, used for user menus and the app/user properties file
* @param mode The mode for this toolbar
*/
public void addToolBar(JToolBar toolBar, String name, int mode)
{
if (mdiToolBarHolder == null)
{
mdiToolBarHolder = new ToolBarHolder();
getToolBarHolder().add(mdiToolBarHolder,BorderLayout.NORTH);
}
if (mode == TOOLBAR_DEFAULT)
{
mode = PropertyUtilities.getInteger(getUserProperties(),"ToolBar."+name,mode);
}
mdiToolBarHolder.add(toolBar,name,mode);
}
public void addToolBar(JToolBar toolBar, String name)
{
addToolBar(toolBar, name, TOOLBAR_DEFAULT);
}
public void removeToolBar(JToolBar toolBar)
{
mdiToolBarHolder.remove(toolBar);
}
public PageManager getPageManager()
{
if (pageManager == null) setPageManager(createPageManager());
return pageManager;
}
public void setPageManager(PageManager manager)
{
if (manager == pageManager) return;
Component oldEmbodiment = null;
if (pageManager != null)
{
oldEmbodiment = pageManager.getEmbodiment();
}
switchPageManager(pageManager,manager);
// Now we need to switch the embodiments
if (pageManager != null)
{
Container parent = oldEmbodiment.getParent();
int index = 0;
for (int i=0; i<parent.getComponentCount(); i++)
if (parent.getComponent(i) == oldEmbodiment) { index = i; break; }
parent.remove(index);
Component page = manager.getEmbodiment();
updateComponentTreeUI(page); // In case UI has changed
parent.add(page,index);
parent.validate();
getCommandProcessor().setChanged();
}
pageManager = manager;
}
public PageManager getControlManager()
{
if (controlManager == null) setControlManager(createControlManager());
return controlManager;
}
public void setControlManager(PageManager manager)
{
if (manager == controlManager) return;
switchPageManager(controlManager,manager);
controlManager = manager;
}
public PageManager getConsoleManager()
{
if (consoleManager == null) setConsoleManager(createConsoleManager());
return consoleManager;
}
public void setConsoleManager(PageManager manager)
{
if (manager == consoleManager) return;
switchPageManager(consoleManager,manager);
consoleManager = manager;
}
protected PageManager createPageManager()
{
return createManager("pageManager");
}
protected PageManager createControlManager()
{
return createManager("controlManager");
}
protected PageManager createConsoleManager()
{
PageManager p = createManager("consoleManager");
p.setPageManagerType("Console");
return p;
}
protected PageManager createManager(String type)
{
try
{
ClassLoader loader = Thread.currentThread().getContextClassLoader();
if (loader == null) loader = getClass().getClassLoader();
Class k = loader.loadClass(getUserProperties().getProperty(type));
return (PageManager) k.newInstance();
}
catch (Exception x)
{
throw new InitializationException("Could not create PageManager: "+type,x);
}
}
private void switchPageManager(PageManager oldManager, PageManager newManager)
{
newManager.setActive(true);
if (oldManager != null)
{
List listeners = oldManager.getPageListenerList();
oldManager.removeAllPageListeners();
List l = oldManager.pages();
for (Iterator i = listeners.iterator(); i.hasNext(); ) newManager.addPageListener((PageListener) i.next());
newManager.init(l,oldManager.getSelectedPage());
oldManager.setActive(false);
}
else newManager.addPageListener(pageListener);
}
public void setSelectedPageManager(PageManager manager) {
if (manager == selectedPageManager) return;
if (selectedPageManager != null)
getCommandTargetManager().remove(selectedPageManager.getCommandProcessor());
getCommandTargetManager().add(manager.getCommandProcessor());
selectedPageManager = manager;
}
public PageManager selectedPageManager() {
return selectedPageManager;
}
private class MDIPageListener implements PageListener
{
public void pageChanged(PageEvent event)
{
int id = event.getID();
if (id == PageEvent.PAGEOPENED)
{
PageManager manager = event.getPageContext().getPageManager();
if (manager.getPageCount() == 1)
{
if (manager == controlManager) showControl(true);
if (manager == consoleManager) showConsole(true);
}
}
else if (id == PageEvent.PAGECLOSED)
{
PageManager manager = event.getPageContext().getPageManager();
if (manager.getPageCount() == 0)
{
if (manager == controlManager) showControl(false);
if (manager == consoleManager) showConsole(false);
}
}
}
}
private void showControl(boolean show)
{
if (show && controlSplit == null)
{
Component pages = pageManager.getEmbodiment();
Container parent = pages.getParent();
parent.remove(pages);
Component control = controlManager.getEmbodiment();
updateComponentTreeUI(control); // In case UI has changed
controlSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,control,pages);
int pixels = PropertyUtilities.getInteger(getUserProperties(),"controlSize",-1);
if (pixels > 0) controlSplit.setDividerLocation(pixels);
parent.add(controlSplit);
revalidate();
}
else if (!show && controlSplit != null)
{
PropertyUtilities.setInteger(getUserProperties(),"controlSize",controlSplit.getDividerLocation());
Component pages = pageManager.getEmbodiment();
Container parent = controlSplit.getParent();
parent.remove(controlSplit);
controlSplit.removeAll();
controlSplit = null;
parent.add(pages);
revalidate();
}
}
private void showConsole(boolean show)
{
if (show && consoleSplit == null)
{
Component old = getComponent(0);
final int height = old.getHeight();
remove(old);
final int pixels = PropertyUtilities.getInteger(getUserProperties(),"consoleSize",-1);
Component console = consoleManager.getEmbodiment();
updateComponentTreeUI(console); // In case UI has changed
consoleSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT,old,console)
{
// If the splitpane is not yet layed out, its height will be 0
// in this case we need to postpone setting the divider location
// until later.
int consoleSize = height > 0 ? -1 : pixels;
public void doLayout()
{
if (consoleSize > 0)
{
int height = getHeight();
setDividerLocation(height - consoleSize);
consoleSize = -1;
}
super.doLayout();
}
};
consoleSplit.setResizeWeight(1.0);
if (pixels > 0 && height>0) consoleSplit.setDividerLocation(height - pixels);
add(consoleSplit);
revalidate();
}
else if (!show && consoleSplit != null)
{
int consoleSize = consoleSplit.getHeight() - consoleSplit.getDividerLocation();
PropertyUtilities.setInteger(getUserProperties(),"consoleSize",consoleSize);
Component old = consoleSplit.getTopComponent();
remove(consoleSplit);
consoleSplit.removeAll();
consoleSplit = null;
add(old);
revalidate();
}
}
protected CommandProcessor createCommandProcessor()
{
return new MDICommandProcessor();
}
protected class MDICommandProcessor extends ApplicationCommandProcessor
{
public void onTabbedPanes(boolean state)
{
if (state)
{
setPageManager(new TabbedPageManager());
getUserProperties().setProperty("pageManager",getPageManager().getClass().getName());
}
}
public void enableTabbedPanes(BooleanCommandState state)
{
state.setEnabled(true);
state.setSelected(getPageManager() instanceof TabbedPageManager);
}
public void onInternalFrames(boolean state)
{
if (state)
{
setPageManager(new InternalFramePageManager());
getUserProperties().setProperty("pageManager",getPageManager().getClass().getName());
}
}
public void enableInternalFrames(BooleanCommandState state)
{
state.setEnabled(true);
state.setSelected(getPageManager() instanceof InternalFramePageManager);
}
}
private PageListener pageListener = new MDIPageListener();
private PageManager pageManager;
private PageManager controlManager;
private PageManager consoleManager;
private JSplitPane consoleSplit;
private JSplitPane controlSplit;
private ToolBarHolder mdiToolBarHolder;
private PageManager selectedPageManager;
}