package com.mucommander.ui.viewer;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.io.IOException;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JScrollPane;
import javax.swing.KeyStroke;
import com.mucommander.commons.file.AbstractFile;
import com.mucommander.commons.runtime.OsFamily;
/**
* Abstract class that serves as a common base for the file presenter objects (FileViewer, FileEditor).
*
* @author Arik Hadas
*/
public abstract class FilePresenter extends JScrollPane {
/** FileFrame instance that contains this presenter (may be null). */
private FileFrame frame;
/** File currently being presented. */
private AbstractFile file;
protected final static String CUSTOM_FULL_SCREEN_EVENT = "CUSTOM_FULL_SCREEN_EVENT";
private final static String CUSTOM_DISPOSE_EVENT = "CUSTOM_DISPOSE_EVENT";
public FilePresenter() {
super(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
addFocusListener(new FocusListener() {
public void focusLost(FocusEvent e) {}
public void focusGained(FocusEvent e) {
// Delegate the focus to the JComponent that actually present the file
Component component = FilePresenter.this.getViewport().getComponent(0);
if (component != null)
component.requestFocus();
}
});
// Catch Apple+W keystrokes under Mac OS X to close the window
if(OsFamily.MAC_OS_X.isCurrent()) {
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_W, ActionEvent.META_MASK), CUSTOM_DISPOSE_EVENT);
getActionMap().put(CUSTOM_DISPOSE_EVENT, new AbstractAction() {
public void actionPerformed(ActionEvent e){
getFrame().dispose();
}
});
}
}
/**
* Set component to be presented in the ScrollPane viewport
*
* @param component the component to be presented
*/
protected void setComponentToPresent(JComponent component) {
getViewport().removeAll();
getViewport().add(component);
}
/**
* Returns the frame which contains this presenter.
* <p>
* This method may return <code>null</code>if the presenter is not inside a FileFrame.
* </p>
* @return the frame which contains this presenter.
* @see #setFrame(FileFrame)
*/
protected FileFrame getFrame() {
return frame;
}
/**
* Sets the FileFrame (separate window) that contains this FilePresenter.
* @param frame frame that contains this <code>FilePresenter</code>.
* @see #getFrame()
*/
public void setFrame(FileFrame frame) {
this.frame = frame;
}
/**
* Returns a description of the file currently being presented which will be used as a window title.
* This method returns the file's name but it can be overridden to provide more information.
* @return this dialog's title.
*/
protected String getTitle() {
return file.getAbsolutePath();
}
/**
* Returns the file that is being presented.
*
* @return the file that is being presented.
*/
protected AbstractFile getCurrentFile() {
return file;
}
/**
* Sets the file that is to be presented.
* This method will automatically be called after a file presenter is created and should not be called directly.
*
* @param file file that is to be presented.
*/
protected final void setCurrentFile(AbstractFile file) {
this.file = file;
// Update frame's title
getFrame().setTitle(getTitle());
}
/**
* Open a given AbstraceFile for display.
*
* @param file the file to be presented
* @throws IOException in case of an I/O problem
*/
public void open(AbstractFile file) throws IOException {
show(file);
setCurrentFile(file);
}
//////////////////////
// Abstract methods //
//////////////////////
/**
* This method is invoked when the specified file is about to be opened.
* This method should retrieve the file and do the necessary so that this component can be displayed.
*
* @param file the file that is about to be viewed.
* @throws IOException if an I/O error occurs.
*/
protected abstract void show(AbstractFile file) throws IOException;
/**
* Returns the menu bar that controls the presenter's frame. The menu bar should be retrieved using this method and
* not by calling {@link JFrame#getJMenuBar()}, which may return <code>null</code>.
*
* @return the menu bar that controls the presenter's frame.
*/
protected abstract JMenuBar getMenuBar();
}