Java tutorial
/******************************************************************************* * Copyright (C) 2011 Atlas of Living Australia * All Rights Reserved. * * The contents of this file are subject to the Mozilla Public * License Version 1.1 (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.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. ******************************************************************************/ package au.org.ala.delta.editor; import au.org.ala.delta.editor.directives.DirectiveFilesInitialiser; import au.org.ala.delta.editor.directives.ExportController; import au.org.ala.delta.editor.directives.ImportController; import au.org.ala.delta.editor.model.EditorDataModel; import au.org.ala.delta.editor.slotfile.model.SlotFileRepository; import au.org.ala.delta.editor.support.InternalFrameApplication; import au.org.ala.delta.editor.ui.StatusBar; import au.org.ala.delta.editor.ui.util.MenuBuilder; import au.org.ala.delta.model.AbstractObservableDataSet; import au.org.ala.delta.model.DeltaDataSetRepository; import au.org.ala.delta.ui.AboutBox; import au.org.ala.delta.ui.help.HelpController; import au.org.ala.delta.ui.util.IconHelper; import au.org.ala.delta.ui.util.UIUtils; import au.org.ala.delta.util.IProgressObserver; import com.l2fprod.common.swing.JFontChooser; import org.apache.commons.lang.StringUtils; import org.jdesktop.application.Action; import org.jdesktop.application.Application; import org.jdesktop.application.ProxyActions; import org.jdesktop.application.Resource; import org.jdesktop.application.ResourceMap; import org.jdesktop.application.Task; import org.jdesktop.application.Task.BlockingScope; import javax.swing.*; import javax.swing.event.InternalFrameEvent; import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.plaf.FontUIResource; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.beans.PropertyVetoException; import java.io.File; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Enumeration; import java.util.EventObject; import java.util.List; import java.util.Map; import java.util.prefs.PreferenceChangeEvent; import java.util.prefs.PreferenceChangeListener; /** * The main class for the DELTA Editor. */ @ProxyActions({ "copySelectedWithHeaders", "selectAll", "find", "replace", "findNext" }) public class DeltaEditor extends InternalFrameApplication implements PreferenceChangeListener, DeltaViewStatusObserver, PropertyChangeListener { private static final String DELTA_FILE_EXTENSION = "dlt"; /** Helper class for notifying listeners of property changes */ private PropertyChangeSupport _propertyChangeSupport; private StatusBar _statusBar; private ActionMap _actionMap; private ResourceMap _resourceMap; /** Used to create/find/save data sets */ private DeltaDataSetRepository _dataSetRepository; private boolean _saveEnabled; private boolean _saveAsEnabled; private boolean _viewSelected; /** Flag to prevent concurrent modification exception on close all */ private boolean _closingAll; /** * There is one DeltaViewController for each open DeltaDataSet. Each controller is responsible for one or more DeltaViews. */ private List<DeltaViewController> _controllers; /** The DeltaViewController responsible for the currently selected/focused DeltaView */ private DeltaViewController _activeController; private HelpController _helpController; private JMenu _fileMenu; private JMenu _windowMenu; @Resource String windowTitleWithoutFilename; @Resource String windowTitleWithFilename; @Resource private String warning; @Resource private String warningTitle; @Resource private String closeWithoutSavingMessage; @Resource private String newDataSetName; @Resource private String unableToCloseMessage; /** Tracks the number of new datasets so a number can be added each time */ private int _newDataSetCount = 0; private String[] _args; public static void main(String[] args) { setupMacSystemProperties(DeltaEditor.class); launch(DeltaEditor.class, args); } public DeltaEditor() { _controllers = new ArrayList<DeltaViewController>(); _saveEnabled = false; _saveAsEnabled = false; _closingAll = false; _viewSelected = false; _propertyChangeSupport = new PropertyChangeSupport(this); setLookAndFeel(); } private void setLookAndFeel() { // To avoid setting the look and feel twice, we are updating the resource bundle before the Swing // Application Framework sets the look and feel. try { getContext().setApplicationClass(DeltaEditor.class); ResourceMap resources = getContext().getResourceMap(); Method method = ResourceMap.class.getDeclaredMethod("getBundlesMap"); method.setAccessible(true); Map<String, Object> resourceMap = (Map<String, Object>) method.invoke(resources); resourceMap.put("Application.lookAndFeel", EditorPreferences.getPreferredLookAndFeel()); Font font = EditorPreferences.getPreferredFont(); if (font != null) { updateFont(font); } } catch (Throwable t) { // Doesn't matter if we fail, going with the defaults is fine. } } @Override protected void initialize(String[] args) { _resourceMap = getContext().getResourceMap(DeltaEditor.class); _resourceMap.injectFields(this); _args = args; } public boolean getSaveEnabled() { return _saveEnabled; } /** * A dummy property to disable the menus that aren't yet implemented. * * @return always returns false */ public boolean isEnabled() { return false; } @Override protected void startup() { _actionMap = getContext().getActionMap(this); JFrame frame = getMainFrame(); frame.setPreferredSize(new Dimension(800, 600)); frame.setIconImages(IconHelper.getBlueIconList()); frame.setExtendedState(JFrame.MAXIMIZED_BOTH); addExitListener(new ExitListener() { @Override public void willExit(EventObject event) { } @Override public boolean canExit(EventObject event) { boolean canClose = closeAll(); return canClose; } }); _helpController = new HelpController("help/delta_editor/DeltaEditor"); _dataSetRepository = new SlotFileRepository(); _statusBar = new StatusBar(); // Hiding the status bar as it doesn't really convey much useful information and takes up screen space. //getMainView().setStatusBar(_statusBar); getMainView().setMenuBar(buildMenus()); _helpController.enableHelpKey(frame); createDesktop(); show(_desktop); } @Override protected void ready() { EditorPreferences.addPreferencesChangeListener(this); super.ready(); if (_args != null && _args.length > 0) { try { File f = new File(_args[0]); if (f.exists()) { Task<AbstractObservableDataSet, Void> fileOpenTask = new DeltaFileLoader(this, f); fileOpenTask.addPropertyChangeListener(_statusBar); fileOpenTask.execute(); } } catch (Exception ex) { throw new RuntimeException(ex); } } } public EditorDataModel getCurrentDataSet() { return _activeController.getModel(); } private JMenuBar buildMenus() { JMenuBar menuBar = new JMenuBar(); // File menu. This on is kind of special, in that it gets rebuilt each // time a file is opened. _fileMenu = new JMenu(); _fileMenu.setName("mnuFile"); buildFileMenu(_fileMenu); menuBar.add(_fileMenu); // Edit Menu JMenu mnuEdit = buildEditMenu(); menuBar.add(mnuEdit); // Search Menu JMenu mnuSearch = buildSearchMenu(); menuBar.add(mnuSearch); // View Menu JMenu mnuView = buildViewMenu(); menuBar.add(mnuView); // Window menu _windowMenu = new JMenu(); _windowMenu.setName("mnuWindow"); buildWindowMenu(_windowMenu); menuBar.add(_windowMenu); JMenu mnuHelp = new JMenu(); mnuHelp.setName("mnuHelp"); JMenuItem mnuItHelpContents = new JMenuItem(); mnuItHelpContents.setName("mnuItHelpContents"); mnuHelp.add(mnuItHelpContents); mnuItHelpContents.addActionListener(_helpController.helpAction()); JMenuItem mnuItHelpOnSelection = new JMenuItem(IconHelper.createImageIcon("help_cursor.png")); mnuItHelpOnSelection.setName("mnuItHelpOnSelection"); mnuItHelpOnSelection.addActionListener(_helpController.helpOnSelectionAction()); mnuHelp.add(mnuItHelpOnSelection); javax.swing.Action openAboutAction = _actionMap.get("openAbout"); if (isMac()) { configureMacAboutBox(openAboutAction); } else { JMenuItem mnuItAbout = new JMenuItem(); mnuItAbout.setAction(openAboutAction); mnuHelp.addSeparator(); mnuHelp.add(mnuItAbout); } menuBar.add(mnuHelp); return menuBar; } private void buildWindowMenu(JMenu mnuWindow) { mnuWindow.removeAll(); JMenuItem mnuItCascade = new JMenuItem(); mnuItCascade.setAction(_actionMap.get("cascadeFrames")); mnuWindow.add(mnuItCascade); JMenuItem mnuItTile = new JMenuItem(); mnuItTile.setAction(_actionMap.get("tileFrames")); mnuWindow.add(mnuItTile); JMenuItem mnuItTileHorz = new JMenuItem(); mnuItTileHorz.setAction(_actionMap.get("tileFramesHorizontally")); mnuWindow.add(mnuItTileHorz); JMenuItem mnuItArrangeIcons = new JMenuItem(); mnuItArrangeIcons.setAction(_actionMap.get("arrangeIcons")); mnuWindow.add(mnuItArrangeIcons); JMenuItem mnuItCloseAll = new JMenuItem(); mnuItCloseAll.setAction(_actionMap.get("closeAllFrames")); mnuWindow.add(mnuItCloseAll); mnuWindow.addSeparator(); JMenuItem mnuItChooseFont = new JMenuItem(); mnuItChooseFont.setAction(_actionMap.get("chooseFont")); mnuWindow.add(mnuItChooseFont); mnuWindow.addSeparator(); JMenu mnuLF = new JMenu(); mnuLF.setName("mnuLF"); mnuLF.setText(_resourceMap.getString("mnuLF.text")); mnuWindow.add(mnuLF); JMenuItem mnuItMetalLF = new JMenuItem(); mnuItMetalLF.setAction(_actionMap.get("metalLookAndFeel")); mnuLF.add(mnuItMetalLF); JMenuItem mnuItWindowsLF = new JMenuItem(); mnuItWindowsLF.setAction(_actionMap.get("systemLookAndFeel")); mnuLF.add(mnuItWindowsLF); try { // Nimbus L&F was added in update java 6 update 10. Class.forName("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel").newInstance(); JMenuItem mnuItNimbusLF = new JMenuItem(); mnuItNimbusLF.setAction(_actionMap.get("nimbusLookAndFeel")); mnuLF.add(mnuItNimbusLF); } catch (Exception e) { // The Nimbus L&F is not available, no matter. } mnuWindow.addSeparator(); int i = 1; for (final JInternalFrame frame : _frames) { JMenuItem windowItem = new JCheckBoxMenuItem(); if (i < 10) { windowItem.setText(String.format("%d %s", i, frame.getTitle())); windowItem.setMnemonic(KeyEvent.VK_1 + (i - 1)); } else { windowItem.setText(frame.getTitle()); } windowItem.setSelected(frame.isSelected()); windowItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { try { frame.setSelected(true); } catch (PropertyVetoException e1) { } } }); mnuWindow.add(windowItem); ++i; } } private void buildFileMenu(JMenu mnuFile) { mnuFile.removeAll(); String[] fileMenuActions = { "newFile", "loadFile", "closeFile", "-", "saveFile", "saveAsFile", "-", "importDirectives", "exportDirectives" }; MenuBuilder.buildMenu(mnuFile, fileMenuActions, _actionMap); mnuFile.addSeparator(); String[] previous = EditorPreferences.getPreviouslyUsedFiles(); if (previous != null && previous.length > 0) { javax.swing.Action a = this._actionMap.get("loadPreviousFile"); if (a != null) { for (int i = 0; i < previous.length; ++i) { String filename = previous[i]; JMenuItem item = new JMenuItem(); item.setAction(a); item.setText(String.format("%d %s", i + 1, filename)); item.putClientProperty("Filename", filename); item.setMnemonic(KeyEvent.VK_1 + i); mnuFile.add(item); } } } if (!isMac()) { mnuFile.addSeparator(); JMenuItem mnuItFileExit = new JMenuItem(); mnuItFileExit.setAction(_actionMap.get("exitApplication")); mnuFile.add(mnuItFileExit); } } @Action public void systemLookAndFeel() { UIUtils.systemLookAndFeel(getMainFrame()); EditorPreferences.setPreferredLookAndFeel("system"); } @Action public void metalLookAndFeel() { UIUtils.metalLookAndFeel(getMainFrame()); EditorPreferences.setPreferredLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); } @Action public void nimbusLookAndFeel() { UIUtils.nimbusLookAndFeel(getMainFrame()); EditorPreferences.setPreferredLookAndFeel("nimbus"); } /** * Loads a previously loaded delta file from the Most Recently Used list. It is assumed that the source ActionEvent as set the filename in a client property called "Filename". * * @param e * The action event that triggered this action * @return A DeltaFileLoader task */ @Action(block = BlockingScope.APPLICATION) public DeltaFileLoader loadPreviousFile(ActionEvent e) { DeltaFileLoader fileOpenTask = null; JComponent item = (JComponent) e.getSource(); if (item != null) { String filename = (String) item.getClientProperty("Filename"); File toOpen = new File(filename); if (toOpen != null && toOpen.exists()) { fileOpenTask = new DeltaFileLoader(this, toOpen); fileOpenTask.addPropertyChangeListener(_statusBar); } else { JOptionPane.showMessageDialog(getMainFrame(), "File not found or not readable!", "File open failed", JOptionPane.ERROR_MESSAGE); item.getParent().remove(item); EditorPreferences.removeFileFromMRU(filename); } } return fileOpenTask; } private JMenu buildSearchMenu() { JMenu mnuSearch = new JMenu(); mnuSearch.setName("mnuSearch"); String[] seachMenuActions = { "find", "findNext" }; MenuBuilder.buildMenu(mnuSearch, seachMenuActions, _actionMap); return mnuSearch; } private JMenu buildEditMenu() { JMenu mnuEdit = new JMenu(); mnuEdit.setName("mnuEdit"); String[] editMenuActions = { "copy", "paste", "-", "selectAll", "-", "copySelectedWithHeaders" }; MenuBuilder.buildMenu(mnuEdit, editMenuActions, _actionMap); return mnuEdit; } /** * Builds and returns the View menu. * * @return a new JMenu ready to be added to the menu bar. */ private JMenu buildViewMenu() { JMenu mnuView = new JMenu(); mnuView.setName("mnuView"); String[] viewMenuActions = { "newTreeView", "newGridView", "-", "viewCharacterEditor", "viewTaxonEditor", "-", "viewActionSets", "viewImageSettings" }; MenuBuilder.buildMenu(mnuView, viewMenuActions, _actionMap); return mnuView; } private File _lastDirectory = null; public File selectFile(boolean open) { File selectedFile = null; JFileChooser chooser = new JFileChooser(); if (_lastDirectory != null) { chooser.setCurrentDirectory(_lastDirectory); } chooser.setFileFilter(new FileNameExtensionFilter("Delta Editor files *.dlt", DELTA_FILE_EXTENSION)); int dialogResult; if (open) { dialogResult = chooser.showOpenDialog(getMainFrame()); } else { dialogResult = chooser.showSaveDialog(getMainFrame()); } if (dialogResult == JFileChooser.APPROVE_OPTION) { selectedFile = chooser.getSelectedFile(); _lastDirectory = chooser.getCurrentDirectory(); } return selectedFile; } private void newMatrix() { DeltaView matrixViewer = _activeController.createGridView(); newView(matrixViewer); } private void newTree() { DeltaView treeViewer = _activeController.createTreeView(); newView(treeViewer); } private void newView(DeltaView view) { // TODO need to remove this dependency on JInternalFrame.... show((JInternalFrame) view); updateTitle(); } private void createAboutBox() { AboutBox aboutBox = new AboutBox(getMainFrame(), IconHelper.createBlue32ImageIcon()); show(aboutBox); } abstract class ProgressObservingTask<T, V> extends Task<T, V> implements IProgressObserver { public ProgressObservingTask(Application app) { super(app); } @Override public void progress(String message, int percentComplete) { setProgress(percentComplete); } } /** * Loads a Delta file and creates a new tree view when it finishes. */ class DeltaFileLoader extends ProgressObservingTask<AbstractObservableDataSet, Void> { /** The file to load */ private File _deltaFile; /** * Creates a DeltaFileLoader for the specified application that will load the supplied DELTA file. * * @param app * the application this task is a part of. * @param deltaFile * the file to load. */ public DeltaFileLoader(Application app, File deltaFile) { super(app); _deltaFile = deltaFile; } @Override protected AbstractObservableDataSet doInBackground() throws Exception { message("loading", _deltaFile.getAbsolutePath()); return (AbstractObservableDataSet) _dataSetRepository.findByName(_deltaFile.getAbsolutePath(), this); } @Override protected void succeeded(AbstractObservableDataSet result) { try { EditorPreferences.addFileToMRU(_deltaFile.getAbsolutePath()); _activeController = createController(result); newTree(); } catch (Throwable e) { failed(e); e.printStackTrace(); } } /** * Shows an error dialog with the message from the supplied Throwable. */ @Override protected void failed(Throwable cause) { String message = cause.getMessage(); if (StringUtils.isEmpty(message)) { message = "An internal error occured."; } JOptionPane.showMessageDialog(getMainFrame(), message, getTitle(), JOptionPane.ERROR_MESSAGE); } @Override protected void finished() { setMessage(""); } } /** * Creates a controller to manage the supplied data set. * * @param dataSet * the data set that requires a controller. * @return a controller for the supplied dataset. */ private DeltaViewController createController(AbstractObservableDataSet dataSet) { EditorDataModel model = new EditorDataModel(dataSet); model.setName(newDataSetName()); model.addPropertyChangeListener(this); DeltaViewController controller = new DeltaViewController(model, DeltaEditor.this, _dataSetRepository, _helpController); controller.setNewDataSetName(newDataSetName); controller.setCloseWithoutSavingMessage(closeWithoutSavingMessage); controller.setUnableToCloseMessage(unableToCloseMessage); controller.addDeltaViewStatusObserver(this); _controllers.add(controller); return controller; } /** * Generates a unique name for a new data set. * @return the name to use for the new data set. */ private String newDataSetName() { String name; if (_newDataSetCount > 0) { name = String.format("%s %d", newDataSetName, _newDataSetCount); } else { name = newDataSetName; } _newDataSetCount++; return name; } /** * Called when any view is closed. Does tidy up if there are no remaining views. */ public void viewClosed(DeltaViewController controller, DeltaView view) { if (!_closingAll) { if (controller.getViewCount() == 0) { _controllers.remove(controller); if (_controllers.isEmpty()) { _activeController = null; setSaveAsEnabled(false); setSaveEnabled(false); } } } } /** * Called when a view is selected. Updates the title and the state of the save/save as menus. */ public void viewSelected(DeltaViewController controller, DeltaView view) { _activeController = controller; updateTitle(); setSaveEnabled(getCurrentDataSet().isModified()); setSaveAsEnabled(true); setViewSelected(view != null); } /** * Updates the main window title with the name of the data set displayed by the currently selected view. */ private void updateTitle() { if (_activeController == null) { if (isMac()) { getMainFrame().getRootPane().putClientProperty("Window.documentModified", Boolean.FALSE); } getMainFrame().setTitle(windowTitleWithoutFilename); return; } String dataSetName = getCurrentDataSet().getName(); String title = String.format(windowTitleWithFilename, dataSetName); boolean modified = getCurrentDataSet().isModified(); if (modified) { if (isMac()) { getMainFrame().getRootPane().putClientProperty("Window.documentModified", Boolean.TRUE); } else { title = title + "*"; } } else { if (isMac()) { getMainFrame().getRootPane().putClientProperty("Window.documentModified", Boolean.FALSE); } } getMainFrame().setTitle(title); } @Action(block = BlockingScope.APPLICATION) public Task<AbstractObservableDataSet, Void> loadFile() { Task<AbstractObservableDataSet, Void> fileOpenTask = null; File toOpen = selectFile(true); if (toOpen != null) { fileOpenTask = new DeltaFileLoader(this, toOpen); fileOpenTask.addPropertyChangeListener(_statusBar); } return fileOpenTask; } @Action(enabledProperty = "saveEnabled") public void saveFile() { _activeController.save(); } @Action(enabledProperty = "saveAsEnabled") public void saveAsFile() { _activeController.saveAs(); updateTitle(); } @Action public void exitApplication() { exit(); } @Action(enabledProperty = "saveAsEnabled") public void newGridView() { if (_activeController != null) { newMatrix(); } } @Action(enabledProperty = "saveAsEnabled") public void newTreeView() { if (_activeController != null) { newTree(); } } private boolean checkWindowCount(int number) { return _desktop != null && _desktop.getAllFrames().length >= number; } public boolean isTileEnabled() { return checkWindowCount(1); } @Action(enabledProperty = "tileEnabled") public void tileFrames() { tileFramesInDesktopPane(false); } @Action public void chooseFont() { Font f = UIManager.getFont("Label.font"); Font newFont = JFontChooser.showDialog(_desktop, "Please select a font", f); if (newFont != null) { updateFont(newFont); SwingUtilities.updateComponentTreeUI(getMainFrame()); EditorPreferences.setPreferredFont(newFont); } } private void updateFont(Font newFont) { FontUIResource fontResource = new FontUIResource(newFont); Enumeration<Object> keys = UIManager.getDefaults().keys(); while (keys.hasMoreElements()) { Object key = keys.nextElement(); Object value = UIManager.get(key); if (value instanceof FontUIResource) { UIManager.put(key, fontResource); } } } @Action(enabledProperty = "tileEnabled") public void tileFramesHorizontally() { tileFramesInDesktopPane(true); } public boolean isCascadeEnabled() { return checkWindowCount(1); } @Action(enabledProperty = "cascadeEnabled") public void cascadeFrames() { UIUtils.cascade(_desktop); } public boolean isArrangeIconsEnabled() { return checkWindowCount(1); } @Action(enabledProperty = "arrangeIconsEnabled") public void arrangeIcons() { UIUtils.arrangeMinifiedWindows(_desktop); } public boolean isCloseAllFramesEnabled() { return checkWindowCount(1); } @Action(enabledProperty = "closeAllFramesEnabled") public void closeAllFrames() { _activeController.closeAll(); } @Action public void openAbout() { createAboutBox(); } @Action(enabledProperty = "viewSelected") public void viewCharacterEditor() { DeltaView editor = _activeController.createCharacterEditView(); newView(editor); } @Action(enabledProperty = "viewSelected") public void viewTaxonEditor() { DeltaView editor = _activeController.createItemEditView(); newView(editor); } @Action(enabledProperty = "saveAsEnabled") public void viewActionSets() { DeltaView actionSets = _activeController.createActionSetsView(); newView(actionSets); } @Action(enabledProperty = "saveAsEnabled") public void viewImageSettings() { DeltaView imageSettings = _activeController.createImageSettingsView(); newView(imageSettings); } @Action public void viewImageEditor() { DeltaView editor = _activeController.createImageEditorView(); newView(editor); } @Action public void viewDirectivesEditor() { DeltaView editor = _activeController.createDirectivesEditorView(); newView(editor); } @Action(enabledProperty = "saveAsEnabled") public void importDirectives() { new ImportController(this, getCurrentDataSet()).begin(); } @Action(enabledProperty = "saveAsEnabled") public void exportDirectives() { new ExportController(this).begin(); } @Action public void newFile() { AbstractObservableDataSet dataSet = (AbstractObservableDataSet) _dataSetRepository.newDataSet(); _activeController = createController(dataSet); DirectiveFilesInitialiser initialiser = new DirectiveFilesInitialiser(this, _activeController.getModel()); initialiser.importDirectiveFileTemplates(); newTree(); } @Action(enabledProperty = "saveAsEnabled") public void closeFile() { _activeController.closeAll(); } private boolean closeAll() { _closingAll = true; for (DeltaViewController controller : _controllers) { if (!controller.closeAll()) { return false; } } return true; } @Override public void propertyChange(PropertyChangeEvent evt) { if (_activeController == null) { return; } if (evt.getSource() == _activeController.getModel()) { if ("modified".equals(evt.getPropertyName())) { setSaveEnabled((Boolean) evt.getNewValue()); } } } public void addPropertyChangeListener(PropertyChangeListener listener) { _propertyChangeSupport.addPropertyChangeListener(listener); } public void setSaveEnabled(boolean saveEnabled) { boolean oldSaveEnabled = _saveEnabled; _saveEnabled = saveEnabled; _propertyChangeSupport.firePropertyChange("saveEnabled", oldSaveEnabled, _saveEnabled); updateTitle(); } public boolean isSaveEnabled() { return _saveEnabled; } public void setSaveAsEnabled(boolean saveEnabled) { boolean oldSaveAsEnabled = _saveAsEnabled; _saveAsEnabled = saveEnabled; _propertyChangeSupport.firePropertyChange("saveAsEnabled", oldSaveAsEnabled, _saveAsEnabled); } public boolean isSaveAsEnabled() { return _saveAsEnabled; } public boolean isViewSelected() { return _viewSelected; } public void setViewSelected(boolean viewSelected) { boolean oldViewSelected = _viewSelected; _viewSelected = viewSelected; _propertyChangeSupport.firePropertyChange("viewSelected", oldViewSelected, _viewSelected); } /** * Updates the file menu when a value is added to the most recently used list. */ @Override public void preferenceChange(PreferenceChangeEvent evt) { if (EditorPreferences.MRU_PREF_KEY.equals(evt.getKey())) { buildFileMenu(_fileMenu); } } /** * Invoked when an internal frame is activated. */ public void internalFrameActivated(InternalFrameEvent e) { buildWindowMenu(_windowMenu); } @Override public void internalFrameOpened(InternalFrameEvent e) { buildWindowMenu(_windowMenu); } @Override public void internalFrameClosed(InternalFrameEvent e) { buildWindowMenu(_windowMenu); } }