/******************************************************************************* * Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 * which accompanies this distribution. * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * Contributors: * Oracle - initial API and implementation from Oracle TopLink ******************************************************************************/ package org.eclipse.persistence.tools.workbench.framework.internal; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.Toolkit; import java.awt.Window; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.prefs.Preferences; import javax.swing.Action; import javax.swing.BorderFactory; import javax.swing.ButtonModel; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBoxMenuItem; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JToolBar; import javax.swing.border.Border; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import org.eclipse.persistence.tools.workbench.framework.Plugin; import org.eclipse.persistence.tools.workbench.framework.action.AbstractFrameworkAction; import org.eclipse.persistence.tools.workbench.framework.action.ActionRepository; import org.eclipse.persistence.tools.workbench.framework.action.FrameworkAction; import org.eclipse.persistence.tools.workbench.framework.app.ApplicationNode; import org.eclipse.persistence.tools.workbench.framework.app.ComponentContainerDescription; import org.eclipse.persistence.tools.workbench.framework.app.GroupContainerDescription; import org.eclipse.persistence.tools.workbench.framework.app.NavigatorSelectionModel; import org.eclipse.persistence.tools.workbench.framework.app.RootMenuDescription; import org.eclipse.persistence.tools.workbench.framework.context.AbstractWorkbenchContext; import org.eclipse.persistence.tools.workbench.framework.context.ApplicationContext; import org.eclipse.persistence.tools.workbench.framework.context.WorkbenchContext; import org.eclipse.persistence.tools.workbench.framework.help.HelpFacade; import org.eclipse.persistence.tools.workbench.framework.resources.ResourceRepository; import org.eclipse.persistence.tools.workbench.framework.uitools.DropDownButton; import org.eclipse.persistence.tools.workbench.uitools.app.PropertyValueModel; import org.eclipse.persistence.tools.workbench.uitools.app.SimplePropertyValueModel; import org.eclipse.persistence.tools.workbench.uitools.app.TreeNodeValueModel; import org.eclipse.persistence.tools.workbench.uitools.swing.EmptyIcon; import org.eclipse.persistence.tools.workbench.utility.CollectionTools; import org.eclipse.persistence.tools.workbench.utility.events.StateChangeEvent; import org.eclipse.persistence.tools.workbench.utility.events.StateChangeListener; /** * This is the main window opened by the application. * * TODO allow multiple workspaces per workbench */ final class WorkbenchWindow extends JFrame { /** A backpointer to the application that created this workbench window. */ private FrameworkApplication application; /** The context passed to just about everybody. */ private WorkbenchContext context; /** The main part of the window: a navigator, an editor, and a problem list. */ private WorkspaceView workspace; /** Keep the File menu in synch with the list of recently-opened files. */ private JMenu fileMenu; private int recentFilesSize; private StateChangeListener recentFilesListener; /** This holds the actions shared by the menus and toolbars and the plug-ins. */ private FrameworkActionRepository actionRepository; /** This allows us to control the "Show Problems" check box menu item. */ private ButtonModel showProblemsButtonModel; /** * This allows us to control the development-time-only * "Synchronous Problems" check box menu item. */ private ButtonModel synchronousProblemsButtonModel; /** Wrap the menu description corresponding to the selected nodes */ private PropertyValueModel selectionMenuDescriptionHolder; /** * Listen to the tree selection so we can update * the menus, tool bars, and actions, below. */ private TreeSelectionListener treeSelectionListener; /** * These menus and toolbars are updated with every * change to the tree selection. */ private JMenu workbenchMenu; private JMenu selectionMenu; /** Collections of actions, keyed by plug-in. */ private Map pluginToolBarActions; private JToolBar selectionToolBar; /** * Hold the actions associated with the selected node(s) so we * can tear them down before replacing them with new actions * when the node selection changes. */ private Set selectionActions; private Set workbenchActions; /** hold the listener so we can remove it */ private WindowListener windowListener; private static final Icon EMPTY_ICON = new EmptyIcon(16); // private static final Border STATUS_BAR_BORDER = // BorderFactory.createCompoundBorder( // new EmptyBorder(2, 0, 0, 0), // BorderFactory.createCompoundBorder( // new ThinBevelBorder(BevelBorder.LOWERED), // new EmptyBorder(0, 2, 0, 2) // ) // ); // ********** constructors ********** /** * The workbench window works closely with the framework application. */ WorkbenchWindow(FrameworkApplication application) { super(); this.application = application; this.initialize(); } /** * Construct a workbench window that takes its initial settings from * an existing workbench window. */ WorkbenchWindow(FrameworkApplication application, WorkbenchWindow workbenchWindow) { this(application); this.copySettingsFrom(workbenchWindow); } // ********** initialization ********** private void initialize() { this.recentFilesSize = 0; this.recentFilesListener = this.buildRecentFilesListener(); this.application.recentFilesManager().addStateChangeListener(this.recentFilesListener); this.context = new LocalWorkbenchContext(); this.selectionMenuDescriptionHolder = new SimplePropertyValueModel(); this.workspace = new WorkspaceView(this.context, this.selectionMenuDescriptionHolder); this.actionRepository = new FrameworkActionRepository(this); this.selectionActions = new HashSet(); this.workbenchActions = new HashSet(); this.setBounds(50, 50, 800, 725); this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); this.initializeTitleBar(); this.windowListener = new LocalWindowListener(); this.addWindowListener(this.windowListener); this.getRootPane().setJMenuBar(this.buildMenuBar()); this.getContentPane().add(this.buildToolBarPanel(), BorderLayout.NORTH); this.getContentPane().add(this.workspace.getComponent(), BorderLayout.CENTER); this.treeSelectionListener = this.buildTreeSelectionListener(); this.getWorkspace().addNavigatorTreeSelectionListener(this.treeSelectionListener); } private void initializeTitleBar() { this.setTitle(this.application.getFullProductName()); Icon icon = this.resourceRepository().getIcon("oracle.logo.large"); if (icon instanceof ImageIcon) { this.setIconImage(((ImageIcon) icon).getImage()); } } private void copySettingsFrom(WorkbenchWindow workbenchWindow) { this.setSize(workbenchWindow.getWidth(), workbenchWindow.getHeight()); this.setExtendedState(workbenchWindow.getExtendedState()); // "cascade" the window int titleBarHeight = workbenchWindow.getLocationOnScreen().y - workbenchWindow.getRootPane().getLocationOnScreen().y; int x = workbenchWindow.getLocationOnScreen().x - titleBarHeight; int y = workbenchWindow.getLocationOnScreen().y - titleBarHeight; Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); Dimension windowSize = this.getSize(); if ((x + windowSize.width > screenSize.width) || (y + windowSize.height > screenSize.height)) { this.setLocation(0, 0); } else { this.setLocation(x, y); } this.workspace.copySettingsFrom(workbenchWindow.getWorkspace()); } // ********** menus ********** private JMenuBar buildMenuBar() { JMenuBar menuBar = new JMenuBar(); // hold on to the "File" menu so we can manipulate the recent file list this.fileMenu = this.buildFileMenu(); this.rebuildRecentFilesMenuItems(); menuBar.add(this.fileMenu); // hold on to the "Workbench" and "Selected" menus so we can // disable them when appropriate this.workbenchMenu = this.buildWorkbenchMenu(); menuBar.add(this.workbenchMenu); this.selectionMenu = this.buildSelectionMenu(); menuBar.add(this.selectionMenu); menuBar.add(this.buildToolsMenu()); menuBar.add(this.buildWindowMenu()); menuBar.add(this.buildHelpMenu()); return menuBar; } private JMenu buildFileMenu() { JMenu menu = new JMenu(); menu.setText(resourceRepository().getString("FILE_MENU")); menu.setMnemonic(resourceRepository().getMnemonic("FILE_MENU")); menu.add(this.buildNewMenu()); menu.add(new JMenuItem(this.actionRepository.getOpenAction())); menu.addSeparator(); menu.add(new JMenuItem(new WorkbenchSaveAction(getContext(), nodeManager()))); menu.add(new JMenuItem(new WorkbenchSaveAsAction(getContext(), nodeManager()))); menu.add(new JMenuItem(this.actionRepository.getSaveAllAction())); menu.addSeparator(); menu.add(new JMenuItem(new WorkbenchCloseAction(getContext(), nodeManager()))); menu.add(new JMenuItem(this.actionRepository.getCloseAllAction())); menu.addSeparator(); // menu.add(this.buildMigrateMenu()); menu.addSeparator(); // the recent files will be put here later - @see #rebuildRecentFilesMenuItems() menu.addSeparator(); menu.add(new JMenuItem(this.actionRepository.getExitAction())); return menu; } private JMenu buildNewMenu() { JMenu menu = new JMenu(); menu.setIcon(this.resourceRepository().getIcon("file")); menu.setText(this.resourceRepository().getString("file.new")); menu.setMnemonic(this.resourceRepository().getMnemonic("file.new")); menu.setToolTipText(this.resourceRepository().getString("file.new.toolTipText")); Plugin[] plugins = this.plugins(); for (int i = 0; i < plugins.length; i++) { JMenuItem[] menuItems = plugins[i].buildNewMenuItems(this.context); for (int j = 0; j < menuItems.length; j++) { menu.add(menuItems[j]); } } return menu; } private JMenu buildMigrateMenu() { JMenu menu = new JMenu(); menu.setIcon(EMPTY_ICON); menu.setText(this.resourceRepository().getString("file.migrate")); menu.setMnemonic(this.resourceRepository().getMnemonic("file.migrate")); menu.setToolTipText(this.resourceRepository().getString("file.migrate.toolTipText")); Plugin[] plugins = this.plugins(); // for (int i = 0; i < plugins.length; i++) { // JMenuItem[] menuItems = plugins[i].buildMigrateMenuItems(this.context); // for (int j = 0; j < menuItems.length; j++) { // menu.add(menuItems[j]); // } // } return menu; } /** * the "Workbench" menu starts out empty and gets populated * when a node is selected */ private JMenu buildWorkbenchMenu() { JMenu menu = new JMenu(); menu.setText(this.resourceRepository().getString("WORKBENCH_MENU")); menu.setMnemonic(this.resourceRepository().getMnemonic("WORKBENCH_MENU")); menu.setEnabled(false); return menu; } /** * the "Selected" menu starts out empty and gets populated * when a node is selected */ private JMenu buildSelectionMenu() { JMenu menu = new JMenu(); menu.setText(this.resourceRepository().getString("SELECTED_MENU")); menu.setMnemonic(this.resourceRepository().getMnemonic("SELECTED_MENU")); menu.setEnabled(false); return menu; } private JMenu buildToolsMenu() { JMenu menu = new JMenu(); menu.setText(this.resourceRepository().getString("TOOLS_MENU")); menu.setMnemonic(this.resourceRepository().getMnemonic("TOOLS_MENU")); menu.add(new GoToAction(this.getContext())); menu.add(this.workspace.problemReportAction()); menu.add(new PreferencesAction(this.getContext(), this.application)); if (this.application.isDevelopmentMode()) { menu.add(this.buildDevelopmentMenu()); } return menu; } /** * This menu should only appear in "development" mode. */ private JMenu buildDevelopmentMenu() { JMenu menu = new JMenu(); menu.setIcon(EMPTY_ICON); menu.setText(this.resourceRepository().getString("DEV_MENU")); menu.setMnemonic(this.resourceRepository().getMnemonic("DEV_MENU")); menu.add(new DevelopmentConsoleAction(this.getContext(), this.application)); menu.add(HelpFacade.buildHelpTopicIDWindowAction(this.getContext())); menu.add(new ThreadBrowserAction(this.getContext())); menu.add(new JavaHeapInformationAction(this.getContext())); menu.add(this.buildSynchronousProblemsMenuItem()); return menu; } private JMenuItem buildSynchronousProblemsMenuItem() { JCheckBoxMenuItem item = new JCheckBoxMenuItem(new SynchronousProblemsAction(this)); this.synchronousProblemsButtonModel = item.getModel(); // the workspace is already built by now this.synchronousProblemsButtonModel.setSelected(this.application.getNodeManager().projectNodesAreAddedWithSynchronousValidators()); return item; } private JMenu buildWindowMenu() { JMenu menu = new JMenu(); menu.setText(this.resourceRepository().getString("WINDOW_MENU")); menu.setMnemonic(this.resourceRepository().getMnemonic("WINDOW_MENU")); menu.add(new NewWindowAction(this.getContext(), this.application)); menu.add(this.buildShowProblemsMenuItem()); return menu; } private JMenuItem buildShowProblemsMenuItem() { JCheckBoxMenuItem item = new JCheckBoxMenuItem(new ShowProblemsAction(this)); this.showProblemsButtonModel = item.getModel(); // the workspace is already built by now this.showProblemsButtonModel.setSelected(this.workspace.problemsAreVisible()); return item; } private JMenu buildHelpMenu() { JMenu menu = new JMenu(); menu.setText(this.resourceRepository().getString("HELP_MENU")); menu.setMnemonic(this.resourceRepository().getMnemonic("HELP_MENU")); menu.add(new HomeAction(this.getContext())); menu.add(new UsersGuideAction(this.getContext())); menu.add(new ExamplesAction(this.getContext())); menu.add(new JavaDocAction(this.getContext())); //menu.addSeparator(); //menu.add(new ReleaseNotesAction(this.getContext())); menu.addSeparator(); menu.add(new AboutAction(this.getContext())); return menu; } // ********** toolbars ********** private JPanel buildToolBarPanel() { JPanel panel = new JPanel(new GridLayout(2, 1)); panel.add(this.buildMainToolBar()); this.selectionToolBar = this.buildToolBar("SELECTION_TOOL_BAR"); panel.add(this.selectionToolBar); return panel; } private JToolBar buildMainToolBar() { JToolBar toolBar = this.buildToolBar("MAIN_TOOL_BAR"); toolBar.add(this.buildNewToolBarButton()); JButton button = toolBar.add(this.actionRepository.getOpenAction()); button.setMnemonic('\0'); button = toolBar.add(new WorkbenchSaveAction(getContext(), nodeManager())); button.setMnemonic('\0'); button = toolBar.add(new WorkbenchSaveAsAction(getContext(), nodeManager())); button.setMnemonic('\0'); button = toolBar.add(this.actionRepository.getSaveAllAction()); button.setMnemonic('\0'); button = toolBar.add(new WorkbenchCloseAction(getContext(), nodeManager())); button.setMnemonic('\0'); button = toolBar.add(this.actionRepository.getCloseAllAction()); button.setMnemonic('\0'); this.pluginToolBarActions = new HashMap(); Plugin[] plugins = this.plugins(); for (int i = 0; i < plugins.length; i++) { Plugin plugin = plugins[i]; ComponentContainerDescription ccd = plugin.buildToolBarDescription(this.getContext()); if (ccd.hasComponents()) { toolBar.addSeparator(); } for (Iterator stream = ccd.components(); stream.hasNext(); ) { toolBar.add((Component) stream.next()); } Collection actions = new ArrayList(); for (Iterator stream = ccd.actions(); stream.hasNext(); ) { Action action = (Action) stream.next(); action.setEnabled(false); actions.add(action); } this.pluginToolBarActions.put(plugin, actions); } toolBar.addSeparator(); button = toolBar.add(new HelpAction(this.getContext())); button.setMnemonic('\0'); return toolBar; } private DropDownButton buildNewToolBarButton() { DropDownButton button = new DropDownButton(); // the client property must be set before the action is set button.putClientProperty("hideActionText", Boolean.TRUE); button.setAction(this.buildNewToolBarAction()); button.setMenu(this.buildNewMenu().getPopupMenu()); button.setMnemonic('\0'); return button; } private FrameworkAction buildNewToolBarAction() { return new AbstractFrameworkAction(this.getContext()) { protected void initialize() { this.initializeIcon("file"); this.initializeText("file.new"); this.initializeToolTipText("file.new.toolTipText"); } protected void execute() { // do nothing - the DropDownButton will display the pop-up menu } }; } private JToolBar buildToolBar(String key) { JToolBar toolBar = new JToolBar(this.resourceRepository().getString(key)); Border shadow = BorderFactory.createMatteBorder(0, 0, 1, 0, toolBar.getBackground().darker()); Border highlight = BorderFactory.createMatteBorder(0, 0, 1, 0, toolBar.getBackground().brighter()); toolBar.setBorder(BorderFactory.createCompoundBorder(highlight, shadow)); toolBar.setRollover(true); // TODO should we allow the user to undock toolbars? // the panel will collapse sometimes when you undock the toolbar; // need to look at the border if we allow this, since some L&Fs // show the border differently if it is floatable (we build a custom // border above) toolBar.setFloatable(false); return toolBar; } // ********** plug-in and selection actions ********** private TreeSelectionListener buildTreeSelectionListener() { return new TreeSelectionListener() { public void valueChanged(TreeSelectionEvent e) { WorkbenchWindow.this.treeSelectionChanged(); } }; } /** * Synchronize the "Workbench" and "Selected" menus and the tool bars with * the navigator tree selection. */ void treeSelectionChanged() { ApplicationNode[] selectedNodes = this.navigatorSelectionModel().getSelectedNodes(); Plugin selectedPlugin = this.selectedPlugin(selectedNodes); this.updateWorkbenchActions(selectedPlugin); this.enablePluginToolBarActions(selectedPlugin); this.updateSelectionActions(selectedNodes, selectedPlugin); } /** * Return the single plug-in associated with the specified nodes. * If all the selected nodes are associated with a single plug-in, * return that plug-in. If no nodes are selected or if the selected * nodes span multiple plug-ins, return null. */ private Plugin selectedPlugin(ApplicationNode[] selectedNodes) { int len = selectedNodes.length; if (len == 0) { return null; } // grab the first and compare to the rest Plugin selectedPlugin = selectedNodes[0].getPlugin(); for (int i = 1; i < len; i++) { // note we start with 1 if (selectedNodes[i].getPlugin() != selectedPlugin) { return null; } } return selectedPlugin; } /** * Enable the buttons in the "plug-in" tool bar (the top tool bar) * corresponding to the specified plug-in. */ private void enablePluginToolBarActions(Plugin selectedPlugin) { for (Iterator stream1 = this.pluginToolBarActions.entrySet().iterator(); stream1.hasNext(); ) { Map.Entry entry = (Map.Entry) stream1.next(); boolean enabled = entry.getKey() == selectedPlugin; for (Iterator stream2 = ((Collection) entry.getValue()).iterator(); stream2.hasNext(); ) { ((Action) stream2.next()).setEnabled(enabled); } } } private void updateWorkbenchActions(Plugin selectedPlugin) { this.tearDownWorkbenchActions(); this.workbenchActions.clear(); this.workbenchMenu.removeAll(); if (selectedPlugin != null) { ComponentContainerDescription workbenchMenuDescription = selectedPlugin.buildMenuDescription(this.getContext()); for (Iterator stream = workbenchMenuDescription.components(); stream.hasNext(); ) { this.workbenchMenu.add((Component) stream.next()); } CollectionTools.addAll(this.workbenchActions, workbenchMenuDescription.actions()); this.setUpWorkbenchActions(); } this.workbenchMenu.setEnabled(this.workbenchMenu.getMenuComponentCount() > 0); } private void setUpWorkbenchActions() { for (Iterator stream = this.workbenchActions.iterator(); stream.hasNext(); ) { ((FrameworkAction) stream.next()).setUp(); } } private void tearDownWorkbenchActions() { for (Iterator stream = this.workbenchActions.iterator(); stream.hasNext(); ) { ((FrameworkAction) stream.next()).tearDown(); } } /** * Tear down the previous set of "selection" actions, rebuild the * "selection" menu and tool bar, and set up the new set of * "selection" actions. */ private void updateSelectionActions(ApplicationNode[] selectedNodes, Plugin selectedPlugin) { this.tearDownSelectionActions(); this.selectionActions.clear(); this.updateSelectionMenu(selectedNodes, selectedPlugin); this.updateSelectionToolBar(selectedNodes, selectedPlugin); this.setUpSelectionActions(); } private void setUpSelectionActions() { for (Iterator stream = this.selectionActions.iterator(); stream.hasNext(); ) { ((FrameworkAction) stream.next()).setUp(); } } private void tearDownSelectionActions() { for (Iterator stream = this.selectionActions.iterator(); stream.hasNext(); ) { ((FrameworkAction) stream.next()).tearDown(); } } private void updateSelectionMenu(ApplicationNode[] selectedNodes, Plugin selectedPlugin) { this.selectionMenu.removeAll(); if (selectedPlugin == null) { this.selectionMenu.setEnabled(false); this.selectionMenuDescriptionHolder.setValue(new RootMenuDescription()); return; } // at this point we know we have 1 or more nodes from the same plug-in GroupContainerDescription selectionMenuDescription = selectedNodes[0].buildMenuDescription(this.context); for (int i = 1; i < selectedNodes.length; i++) { // note we start with 1 selectionMenuDescription.mergeWith(selectedNodes[i].buildMenuDescription(this.context)); } for (Iterator stream = selectionMenuDescription.components(); stream.hasNext(); ) { this.selectionMenu.add((Component) stream.next()); } this.selectionMenu.setEnabled(this.selectionMenu.getMenuComponentCount() > 0); CollectionTools.addAll(this.selectionActions, selectionMenuDescription.actions()); this.selectionMenuDescriptionHolder.setValue(selectionMenuDescription); } private void updateSelectionToolBar(ApplicationNode[] selectedNodes, Plugin selectedPlugin) { this.selectionToolBar.removeAll(); this.selectionToolBar.revalidate(); this.selectionToolBar.repaint(); if (selectedPlugin == null) { return; } // at this point we know we have 1 or more nodes from the same plug-in GroupContainerDescription selectionToolBarDescription = selectedNodes[0].buildToolBarDescription(this.context); for (int i = 1; i < selectedNodes.length; i++) { // note we start with 1 selectionToolBarDescription.mergeWith(selectedNodes[i].buildToolBarDescription(this.context)); } for (Iterator stream = selectionToolBarDescription.components(); stream.hasNext(); ) { this.selectionToolBar.add((Component) stream.next()); } CollectionTools.addAll(this.selectionActions, selectionToolBarDescription.actions()); } // ********** recent files ********** private StateChangeListener buildRecentFilesListener() { return new StateChangeListener() { public void stateChanged(StateChangeEvent e) { WorkbenchWindow.this.recentFilesChanged(); } }; } void recentFilesChanged() { this.rebuildRecentFilesMenuItems(); } private void rebuildRecentFilesMenuItems() { // point just beyond the last menu item (exit) int base = this.fileMenu.getMenuComponentCount(); // jump to the last separator base = base - 2; // jump to the first recent file menu item base = base - this.recentFilesSize; // remove all the old entries for (int i = 0; i < this.recentFilesSize; i++) { this.fileMenu.remove(base); } // now insert the new entries File[] recentFiles = this.application.recentFilesManager().getRecentFiles(); this.recentFilesSize = recentFiles.length; for (int i = 0; i < this.recentFilesSize; i++) { this.fileMenu.insert(this.buildRecentFileMenuItem(i + 1, recentFiles[i]), base + i); } // Show the last separator if there are any recent files this.fileMenu.getMenuComponent(this.fileMenu.getMenuComponentCount() - 2).setVisible(recentFiles.length > 0); } private JMenuItem buildRecentFileMenuItem(int count, File recentFile) { return new JMenuItem(new OpenRecentFileAction(this, count, recentFile)); } // ********** saving/restoring window state ********** void saveState(Preferences windowsPreferences) { windowsPreferences.putInt("x-location", this.getLocation().x); windowsPreferences.putInt("y-location", this.getLocation().y); windowsPreferences.putInt("height", this.getSize().height); windowsPreferences.putInt("width", this.getSize().width); windowsPreferences.putInt("extended state", this.getExtendedState()); this.workspace.saveState(windowsPreferences); windowsPreferences.putBoolean("problems view visible", this.workspace.problemsAreVisible()); } void restoreState(Preferences windowsPreferences) { int x = windowsPreferences.getInt("x-location", this.getLocation().x); int y = windowsPreferences.getInt("y-location", this.getLocation().y); this.setLocation(x, y); int height = windowsPreferences.getInt("height", this.getSize().height); int width = windowsPreferences.getInt("width", this.getSize().width); this.setSize(width, height); this.setExtendedState(windowsPreferences.getInt("extended state", this.getExtendedState())); this.workspace.restoreState(windowsPreferences); if ( ! windowsPreferences.getBoolean("problems view visible", true)) { this.toggleShowProblems(); } } void saveTreeExpansionState(Preferences windowsPreferences) { this.workspace.saveTreeExpansionState(windowsPreferences); } void restoreTreeExpansionState(Preferences windowsPreferences) { this.workspace.restoreTreeExpansionState(windowsPreferences); } // ********** miscellaneous behavior ********** /** * Delegate to the workspace: if the problems are currently * displayed, hide them; if they are hidden, display them. * Synchronize the "Show Problems" menu item check box. */ void toggleShowProblems() { this.showProblemsButtonModel.setSelected(this.workspace.toggleShowProblems()); } /** * Delegate to the node manager: if projects are currently added * with synchronous validators, start adding them with asynchronous * validators, and vice versa. * Synchronize the "Synchronous Problems" menu item check box. */ void toggleSynchronousProblems() { this.synchronousProblemsButtonModel.setSelected(this.application.getNodeManager().toggleAddProjectNodesWithSynchronousValidators()); } /** * Ask the application to close the window. */ void closing() { this.application.close(this); } /** * The window was actually closed. */ void closed() { this.application.recentFilesManager().removeStateChangeListener(this.recentFilesListener); this.getWorkspace().removeNavigatorTreeSelectionListener(this.treeSelectionListener); this.tearDownSelectionActions(); this.workspace.close(); // stop listening to the window, or, for some odd reason, // we will receive the WINDOW_CLOSED event twice... this.removeWindowListener(this.windowListener); } // ********** queries ********** FrameworkApplication getApplication() { return this.application; } WorkbenchContext getContext() { return this.context; } WorkspaceView getWorkspace() { return this.workspace; } ActionRepository getActionRepository() { return this.actionRepository; } Plugin[] plugins() { return this.application.getPlugins(); } ResourceRepository resourceRepository() { return this.application.getResourceRepository(); } ApplicationContext applicationContext() { return this.application.getRootApplicationContext(); } FrameworkNodeManager nodeManager() { return this.application.getNodeManager(); } TreeNodeValueModel rootNode() { return this.nodeManager().getRootNode(); } NavigatorSelectionModel navigatorSelectionModel() { return this.workspace.navigatorSelectionModel(); } Component getPropertiesPage() { return this.workspace.getPropertiesPage(); } // ******************** member classes ******************** private class LocalWorkbenchContext extends AbstractWorkbenchContext { public ApplicationContext getApplicationContext() { return WorkbenchWindow.this.applicationContext(); } public Window getCurrentWindow() { return WorkbenchWindow.this; } public NavigatorSelectionModel getNavigatorSelectionModel() { return WorkbenchWindow.this.navigatorSelectionModel(); } public ActionRepository getActionRepository() { return WorkbenchWindow.this.getActionRepository(); } public Component getPropertiesPage() { return WorkbenchWindow.this.getPropertiesPage(); } } private class LocalWindowListener extends WindowAdapter { public void windowClosing(WindowEvent e) { WorkbenchWindow.this.closing(); } public void windowClosed(WindowEvent e) { WorkbenchWindow.this.closed(); } } }