home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1998 November
/
Chip_1998-11_cd.bin
/
tema
/
Cafe
/
jfc.bin
/
JDirectoryPane.java
< prev
next >
Wrap
Text File
|
1998-02-26
|
16KB
|
573 lines
/*
* @(#)JDirectoryPane.java 1.12 98/02/03
*
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
*
* This software is the confidential and proprietary information of Sun
* Microsystems, Inc. ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with Sun.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
* THIS SOFTWARE OR ITS DERIVATIVES.
*
*/
package com.sun.java.swing.preview;
import com.sun.java.swing.*;
import com.sun.java.swing.plaf.*;
import com.sun.java.swing.event.*;
import java.io.File;
import java.beans.*;
import java.util.*;
import java.awt.event.*;
import com.sun.java.accessibility.*;
/**
* A pane used to display a directory listing.
* <p>
* Warning: serialized objects of this class will not be compatible with
* future swing releases. The current serialization support is appropriate
* for short term storage or RMI between Swing1.0 applications. It will
* not be possible to load serialized Swing1.0 objects with future releases
* of Swing. The JDK1.2 release of Swing will be the compatibility
* baseline for the serialized form of Swing objects.
*
* @version 1.12 02/03/98
* @author Ray Ryan
*/
public class JDirectoryPane extends JComponent
implements SwingConstants, Accessible {
/**
* The model of the directory shown by this JDirectoryPane
*/
protected DirectoryModel directoryModel = null;
/**
* The selection model of this JDirectoryPane
*/
protected ListSelectionModel listSelectionModel = null;
/**
* Listens to property changes from directoryModel
* and rebroadcasts them with this as the source
*/
transient protected Redirector redirector = null;
/**
* Listens to value changes from listSelectionModel,
* firing an action if appropriate
*/
transient protected SelListener selListener = null;
protected String command;
protected String doubleClickCommand = "doubleClick";
protected String doubleClickContainerCommand = "doubleClickContainer";
GoUpAction goUpAction = new GoUpAction();
DefaultActionListener defaultActionListener = new DefaultActionListener();
/**
* Creates a JDirectoryPane on the user's home directory
*/
public JDirectoryPane() {
this((File)null);
}
/**
* Creates a JDirectoryPane on the given path
*/
public JDirectoryPane(String path) {
this(path == null ? null : new File(path));
}
/**
* Creates a JDirectoryPane on the given File
*/
public JDirectoryPane(File directory) {
this.setModel(this.createDirectoryModel(directory));
this.setSelectionModel(this.createSelectionModel());
this.addActionListener(this.getDefaultActionListener());
updateUI();
}
/**
* Override point for people who want to muck with the DirectoryModel
*/
protected DirectoryModel createDirectoryModel(File directory) {
return new DirectoryModel(directory);
}
/**
* Override point for people who want to muck with the ListSelectionModel
*/
protected ListSelectionModel createSelectionModel() {
return new DefaultListSelectionModel();
}
/**
* Convenient way to tell this JDirectoryPane to go up.
*/
public Action getGoUpAction() {
return this.goUpAction;
}
/**
* By default, the returned object is registered as a listener to
* this JDirectoryPane, waiting for a container to be double-clicked.
*
* <p>To defeat this behavior, do something like
* <pre><code>
* myDirPane.removeActionListener(myDirPane.getDefaultActionListener());
* </code></pre>
*/
public ActionListener getDefaultActionListener() {
return this.defaultActionListener;
}
/**
* To be called by UIs on doubleclick.
*/
public void performDoubleClick() {
TypedFile f = this.getSelectedFile();
if (f.getType().isContainer()) {
this.fireActionPerformed(this.getDoubleClickContainerCommand());
} else {
this.fireActionPerformed(this.getDoubleClickCommand());
}
}
//
// Selection Helpers
//
// Some pass through to listSelectionModel, some are conveniences
// implemented here
/**
* Returns the lead selected file or null
*/
public TypedFile getSelectedFile() {
int index = this.getListSelectionModel().getLeadSelectionIndex();
if (index >= 0) {
return (TypedFile)this.getModel().getTypedFiles().elementAt(index);
} else {
return null;
}
}
/**
* Returns the set of selected files, possibly empty, never null.
* Objects in vector are TypedFiles
*/
public Vector getSelectedFiles() {
ListSelectionModel sel = this.getListSelectionModel();
int anchor = sel.getAnchorSelectionIndex();
int lead = sel.getLeadSelectionIndex();
Vector v = new Vector();
if (anchor >= 0 && lead >= 0) {
Vector files = this.getModel().getTypedFiles();
int max = Math.max(anchor, lead);
for (int i = Math.min(anchor, lead); i <= max; i++) {
v.addElement(files.elementAt(i));
}
}
return v;
}
/**
* Returns true if nothing is selected This is a convenience
* method that just delegates to the listSelectionModel.
*
* @return True if nothing is selected
* @see ListSelectionModel#isSelectionEmpty
* @see clearSelection
* @see ListSelectionModel#addListSelectionListener
*/
public boolean isSelectionEmpty() {
return this.getListSelectionModel().isSelectionEmpty();
}
/**
* Clears the selection - after calling this method
* isSelectionEmpty() will return true. This is a convenience
* method that just delegates to the listSelectionModel.
*
* @see ListSelectionModel#clearSelection
* @see #isSelectionEmpty
* @see ListSelectionModel#addListSelectionListener
*/
public void clearSelection() {
this.getListSelectionModel().clearSelection();
}
//
// Pass through to model
//
public File getCurrentDirectory() {
return this.directoryModel.getCurrentDirectory();
}
public void setCurrentDirectory(File dir) {
this.directoryModel.setCurrentDirectory(dir);
}
public TypedFile getTypedFile(String path, String name) {
return this.directoryModel.getTypedFile(path, name);
}
public TypedFile getTypedFile(String path) {
return this.directoryModel.getTypedFile(path);
}
public Vector getTypedFiles() {
return this.directoryModel.getTypedFiles();
}
public Vector getTypedFilesForDirectory(File dir) {
return this.directoryModel.getTypedFilesForDirectory(dir);
}
public boolean canGoUp() {
return this.directoryModel.canGoUp();
}
public void goUp() {
this.directoryModel.goUp();
}
public void setHiddenRule(FileType rule) {
this.directoryModel.setHiddenRule(rule);
}
public FileType getHiddenRule() {
return this.directoryModel.getHiddenRule();
}
public void addKnownFileType(FileType type) {
this.directoryModel.addKnownFileType(type);
}
public Enumeration enumerateKnownFileTypes() {
return this.directoryModel.enumerateKnownFileTypes();
}
public Vector getKnownFileTypes() {
return this.directoryModel.getKnownFileTypes();
}
public boolean isKnownFileType(FileType t) {
return this.directoryModel.isKnownFileType(t);
}
public void setKnownFileTypes(FileType[] types) {
directoryModel.setKnownFileTypes(types);
}
//
// Swinging UI
//
public DirectoryPaneUI getUI() {
return (DirectoryPaneUI)ui;
}
public void setUI(DirectoryPaneUI ui) {
super.setUI(ui);
}
/**
* Called to replace the UI with the latest version from the
* default UIFactory.
*/
public void updateUI() {
setUI((DirectoryPaneUI)UIManager.getUI(this));
}
/**
* @return "DirectoryPaneUI"
* @see JComponent#getUIClassID
* @see UIDefaults#getUI
*/
public String getUIClassID() {
return "DirectoryPaneUI";
}
//
// DirectoryModel
//
public DirectoryModel getModel() {
return directoryModel;
}
/**
* Note that this is protected. A JDirectoryPane does not
* like having its model switched out from under it.
*/
protected void setModel(DirectoryModel newModel)
{
DirectoryModel oldModel = getModel();
if (oldModel != null) {
oldModel.removePropertyChangeListener(redirector);
redirector = null;
}
directoryModel = newModel;
if (newModel != null) {
redirector = createRedirector();
newModel.addPropertyChangeListener(redirector);
}
}
//
// Selection Model
//
public ListSelectionModel getListSelectionModel() {
return listSelectionModel;
}
/**
* Note that this is protected. A JDirectoryPane does not
* like having its selection model switched out from under it.
*/
protected void setSelectionModel(ListSelectionModel newModel) {
ListSelectionModel oldModel = getListSelectionModel();
if (oldModel != null) {
oldModel.removeListSelectionListener(selListener);
selListener = null;
}
listSelectionModel = newModel;
if (newModel != null) {
selListener = createSelectionListener();
newModel.addListSelectionListener(selListener);
}
}
/**
* Can be overridden by subclasses that want to specialize
* listening to property events from the model
*/
protected Redirector createRedirector() {
return new Redirector();
}
/**
* Serves as the PropertyChangeListener on this JDirectoryPane's
* DirectoryModel.
*/
protected class Redirector implements PropertyChangeListener {
/**
* Clear selection if we've changed directories. Rebroadcast
* all events with this JDirectoryPane as the source.
*/
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName() == "currentDirectory") {
getListSelectionModel().clearSelection();
}
/*
firePropertyChange(evt.getPropertyName(),
evt.getOldValue(),
evt.getNewValue());
*/
}
}
protected SelListener createSelectionListener() {
return new SelListener();
}
protected class SelListener implements ListSelectionListener {
/**
* If the event isn't adjusting, fire my action
*/
public void valueChanged(ListSelectionEvent evt) {
if (!evt.getValueIsAdjusting()) {
fireActionPerformed(command);
}
}
}
/**
* Adds the specified action listener to receive action events
* from this JDirectoryPane
*
* @param l the action listener
*/
public synchronized void addActionListener(ActionListener l) {
listenerList.add(ActionListener.class, l);
}
/**
* Removes the specified action listener so that it no longer
* receives action events from this JDirectoryPane
*
* @param l the action listener
*/
public synchronized void removeActionListener(ActionListener l) {
listenerList.remove(ActionListener.class, l);
}
/*
* Notify all listeners that have registered interest for
* notification on this event type. The event instance
* is lazily created using the parameters passed into
* the fire method.
* @see EventListenerList
*/
protected void fireActionPerformed(String command) {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
ActionEvent e = null;
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==ActionListener.class) {
// Lazily create the event:
if (e == null) {
e = new ActionEvent(this,
ActionEvent.ACTION_PERFORMED,
command);
}
((ActionListener)listeners[i+1]).actionPerformed(e);
}
}
}
/**
* Sets the command string used for general action events, dispatched on
* selection change.
*
* @param command the command string
*/
public void setActionCommand(String command) {
String oldCommand = this.command;
this.command = command;
this.firePropertyChange("actionCommand", oldCommand, command);
}
public String getActionCommand() {
return command;
}
/**
* Sets the command string used for action events dispatched on
* double click of non-containers
*
* @param command the command string
*/
public void setDoubleClickCommand(String command) {
String oldCommand = this.doubleClickCommand;
this.doubleClickCommand = command;
this.firePropertyChange("doubleClickCommand", oldCommand, command);
}
public String getDoubleClickCommand() {
return doubleClickCommand;
}
/**
* Sets the command string used for action events dispatched on
* double click of containers
*
* @param command the command string
*/
public void setDoubleClickContainerCommand(String command) {
String oldCommand = this.doubleClickContainerCommand;
this.doubleClickContainerCommand = command;
this.firePropertyChange("doubleClickContainerCommand", oldCommand,
command);
}
public String getDoubleClickContainerCommand() {
return doubleClickContainerCommand;
}
/**
* The Action object that implements an upward move to the directory
* that contains this one.
* <p>
* Warning: serialized objects of this class will not be compatible with
* future swing releases. The current serialization support is appropriate
* for short term storage or RMI between Swing1.0 applications. It will
* not be possible to load serialized Swing1.0 objects with future releases
* of Swing. The JDK1.2 release of Swing will be the compatibility
* baseline for the serialized form of Swing objects.
*/
protected class GoUpAction extends AbstractAction {
protected GoUpAction() {
super("Go Up");
}
public void actionPerformed(ActionEvent ignored) {
goUp();
}
}
protected class DefaultActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
if (command != null &&
command.equals(getDoubleClickContainerCommand())) {
setCurrentDirectory(getSelectedFile());
}
}
}
///
/// Accessibility Support
///
/**
* Get the AccessibleContext of this object
*
* @return the AccessibleContext of this object
*/
public AccessibleContext getAccessibleContext() {
if (accessibleContext == null) {
accessibleContext = new AccessibleJDirectoryPane();
}
return accessibleContext;
}
/**
* The class used to obtain the accessible role for this object.
* <p>
* Warning: serialized objects of this class will not be compatible with
* future swing releases. The current serialization support is appropriate
* for short term storage or RMI between Swing1.0 applications. It will
* not be possible to load serialized Swing1.0 objects with future releases
* of Swing. The JDK1.2 release of Swing will be the compatibility
* baseline for the serialized form of Swing objects.
*/
protected class AccessibleJDirectoryPane extends AccessibleJComponent {
/**
* Get the role of this object.
*
* @return an instance of AccessibleRole describing the role of the
* object
* @see AccessibleRole
*/
public AccessibleRole getAccessibleRole() {
return AccessibleRole.DIRECTORY_PANE;
}
} // AccessibleJDirectoryPane
}