/* * @(#)OpenRecentFileAction.java * * Copyright (c) 1996-2010 The authors and contributors of JHotDraw. * You may not use, copy or modify this file, except in compliance with the * accompanying license terms. */ package org.jhotdraw.app.action.file; import org.jhotdraw.util.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.io.*; import java.net.URI; import org.jhotdraw.app.Application; import org.jhotdraw.app.View; import org.jhotdraw.app.action.AbstractApplicationAction; import org.jhotdraw.gui.BackgroundTask; import org.jhotdraw.gui.JSheet; import org.jhotdraw.gui.Worker; import org.jhotdraw.gui.event.SheetEvent; import org.jhotdraw.gui.event.SheetListener; import org.jhotdraw.net.URIUtil; /** * Loads the specified URI into an empty view. If no empty view is available, a * new view is created. * <p> * This action is called when the user selects an item in the Recent Files * submenu of the File menu. The action and the menu item is automatically * created by the application, when the {@code ApplicationModel} provides a * {@code OpenFileAction}. * <hr> * <b>Features</b> * * <p><em>Allow multiple views per URI</em><br> * When the feature is disabled, {@code OpenRecentFileAction} prevents opening * an URI which is opened in another view.<br> * See {@link org.jhotdraw.app} for a description of the feature. * </p> * * <p><em>Open last URI on launch</em><br> * {@code OpenRecentFileAction} supplies data for this feature by calling * {@link Application#addRecentURI} when it successfully opened a file. * See {@link org.jhotdraw.app} for a description of the feature. * </p> * * @author Werner Randelshofer. * @version $Id$ */ public class OpenRecentFileAction extends AbstractApplicationAction { private static final long serialVersionUID = 1L; public static final String ID = "file.openRecent"; private URI uri; /** Creates a new instance. */ public OpenRecentFileAction(Application app, URI uri) { super(app); this.uri = uri; putValue(Action.NAME, URIUtil.getName(uri)); } @Override public void actionPerformed(ActionEvent evt) { final Application app = getApplication(); if (app.isEnabled()) { // Prevent same URI from being opened more than once if (!getApplication().getModel().isAllowMultipleViewsPerURI()) { for (View vw : getApplication().getViews()) { if (vw.getURI() != null && vw.getURI().equals(uri)) { vw.getComponent().requestFocus(); return; } } } app.setEnabled(false); // Search for an empty view View emptyView = app.getActiveView(); if (emptyView == null || !emptyView.isEmpty() || !emptyView.isEnabled()) { emptyView = null; } final View p; if (emptyView == null) { p = app.createView(); app.add(p); app.show(p); } else { p = emptyView; } openView(p); } } protected void openView(final View view) { final Application app = getApplication(); app.setEnabled(true); // If there is another view with the same URI we set the multiple open // id of our view to max(multiple open id) + 1. int multipleOpenId = 1; for (View aView : app.views()) { if (aView != view && aView.isEmpty()) { multipleOpenId = Math.max(multipleOpenId, aView.getMultipleOpenId() + 1); } } view.setMultipleOpenId(multipleOpenId); view.setEnabled(false); // Open the file view.execute(new BackgroundTask() { @Override protected void construct() throws IOException { boolean exists = true; try { File f = new File(uri); exists = f.exists(); } catch (IllegalArgumentException e) { // The URI does not denote a file, thus we can not check whether the file exists. } if (exists) { view.read(uri, null); } else { ResourceBundleUtil labels = ResourceBundleUtil.getBundle("org.jhotdraw.app.Labels"); throw new IOException(labels.getFormatted("file.open.fileDoesNotExist.message", URIUtil.getName(uri))); } } @Override protected void done() { view.setURI(uri); Frame w = (Frame) SwingUtilities.getWindowAncestor(view.getComponent()); if (w != null) { w.setExtendedState(w.getExtendedState() & ~Frame.ICONIFIED); w.toFront(); } app.addRecentURI(uri); view.setEnabled(true); view.getComponent().requestFocus(); } @Override protected void failed(Throwable value) { value.printStackTrace(); String message = value.getMessage() != null ? value.getMessage() : value.toString(); ResourceBundleUtil labels = ResourceBundleUtil.getBundle("org.jhotdraw.app.Labels"); JSheet.showMessageSheet(view.getComponent(), "<html>" + UIManager.getString("OptionPane.css") + "<b>" + labels.getFormatted("file.open.couldntOpen.message", URIUtil.getName(uri)) + "</b><p>" + (message == null ? "" : message), JOptionPane.ERROR_MESSAGE, new SheetListener() { @Override public void optionSelected(SheetEvent evt) { view.setEnabled(true); } }); } }); } }