This example Java source code file (FilePane.java) is included in the alvinalexander.com
"Java Source Code
Warehouse" project. The intent of this project is to help you "Learn
Java by Example" TM.
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.swing;
import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.*;
import java.text.DateFormat;
import java.text.MessageFormat;
import java.util.*;
import java.util.List;
import java.util.concurrent.Callable;
import javax.accessibility.AccessibleContext;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.filechooser.*;
import javax.swing.plaf.basic.*;
import javax.swing.table.*;
import javax.swing.text.*;
import sun.awt.shell.*;
/**
* <b>WARNING: This class is an implementation detail and is only
* public so that it can be used by two packages. You should NOT consider
* this public API.
* <p>
* This component is intended to be used in a subclass of
* javax.swing.plaf.basic.BasicFileChooserUI. It realies heavily on the
* implementation of BasicFileChooserUI, and is intended to be API compatible
* with earlier implementations of MetalFileChooserUI and WindowsFileChooserUI.
*
* @author Leif Samuelsson
*/
public class FilePane extends JPanel implements PropertyChangeListener {
// Constants for actions. These are used for the actions' ACTION_COMMAND_KEY
// and as keys in the action maps for FilePane and the corresponding UI classes
public final static String ACTION_APPROVE_SELECTION = "approveSelection";
public final static String ACTION_CANCEL = "cancelSelection";
public final static String ACTION_EDIT_FILE_NAME = "editFileName";
public final static String ACTION_REFRESH = "refresh";
public final static String ACTION_CHANGE_TO_PARENT_DIRECTORY = "Go Up";
public final static String ACTION_NEW_FOLDER = "New Folder";
public final static String ACTION_VIEW_LIST = "viewTypeList";
public final static String ACTION_VIEW_DETAILS = "viewTypeDetails";
private Action[] actions;
// "enums" for setViewType()
public static final int VIEWTYPE_LIST = 0;
public static final int VIEWTYPE_DETAILS = 1;
private static final int VIEWTYPE_COUNT = 2;
private int viewType = -1;
private JPanel[] viewPanels = new JPanel[VIEWTYPE_COUNT];
private JPanel currentViewPanel;
private String[] viewTypeActionNames;
private String filesListAccessibleName = null;
private String filesDetailsAccessibleName = null;
private JPopupMenu contextMenu;
private JMenu viewMenu;
private String viewMenuLabelText;
private String refreshActionLabelText;
private String newFolderActionLabelText;
private String kiloByteString;
private String megaByteString;
private String gigaByteString;
private String renameErrorTitleText;
private String renameErrorText;
private String renameErrorFileExistsText;
private static final Cursor waitCursor =
Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR);
private final KeyListener detailsKeyListener = new KeyAdapter() {
private final long timeFactor;
private final StringBuilder typedString = new StringBuilder();
private long lastTime = 1000L;
{
Long l = (Long) UIManager.get("Table.timeFactor");
timeFactor = (l != null) ? l : 1000L;
}
/**
* Moves the keyboard focus to the first element whose prefix matches
* the sequence of alphanumeric keys pressed by the user with delay
* less than value of <code>timeFactor. Subsequent same key
* presses move the keyboard focus to the next object that starts with
* the same letter until another key is pressed, then it is treated
* as the prefix with appropriate number of the same letters followed
* by first typed another letter.
*/
public void keyTyped(KeyEvent e) {
BasicDirectoryModel model = getModel();
int rowCount = model.getSize();
if (detailsTable == null || rowCount == 0 ||
e.isAltDown() || e.isControlDown() || e.isMetaDown()) {
return;
}
InputMap inputMap = detailsTable.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
KeyStroke key = KeyStroke.getKeyStrokeForEvent(e);
if (inputMap != null && inputMap.get(key) != null) {
return;
}
int startIndex = detailsTable.getSelectionModel().getLeadSelectionIndex();
if (startIndex < 0) {
startIndex = 0;
}
if (startIndex >= rowCount) {
startIndex = rowCount - 1;
}
char c = e.getKeyChar();
long time = e.getWhen();
if (time - lastTime < timeFactor) {
if (typedString.length() == 1 && typedString.charAt(0) == c) {
// Subsequent same key presses move the keyboard focus to the next
// object that starts with the same letter.
startIndex++;
} else {
typedString.append(c);
}
} else {
startIndex++;
typedString.setLength(0);
typedString.append(c);
}
lastTime = time;
if (startIndex >= rowCount) {
startIndex = 0;
}
// Find next file
int index = getNextMatch(startIndex, rowCount - 1);
if (index < 0 && startIndex > 0) { // wrap
index = getNextMatch(0, startIndex - 1);
}
if (index >= 0) {
detailsTable.getSelectionModel().setSelectionInterval(index, index);
Rectangle cellRect = detailsTable.getCellRect(index,
detailsTable.convertColumnIndexToView(COLUMN_FILENAME), false);
detailsTable.scrollRectToVisible(cellRect);
}
}
private int getNextMatch(int startIndex, int finishIndex) {
BasicDirectoryModel model = getModel();
JFileChooser fileChooser = getFileChooser();
DetailsTableRowSorter rowSorter = getRowSorter();
String prefix = typedString.toString().toLowerCase();
// Search element
for (int index = startIndex; index <= finishIndex; index++) {
File file = (File) model.getElementAt(rowSorter.convertRowIndexToModel(index));
String fileName = fileChooser.getName(file).toLowerCase();
if (fileName.startsWith(prefix)) {
return index;
}
}
return -1;
}
};
private FocusListener editorFocusListener = new FocusAdapter() {
public void focusLost(FocusEvent e) {
if (! e.isTemporary()) {
applyEdit();
}
}
};
private static FocusListener repaintListener = new FocusListener() {
public void focusGained(FocusEvent fe) {
repaintSelection(fe.getSource());
}
public void focusLost(FocusEvent fe) {
repaintSelection(fe.getSource());
}
private void repaintSelection(Object source) {
if (source instanceof JList) {
repaintListSelection((JList)source);
} else if (source instanceof JTable) {
repaintTableSelection((JTable)source);
}
}
private void repaintListSelection(JList list) {
int[] indices = list.getSelectedIndices();
for (int i : indices) {
Rectangle bounds = list.getCellBounds(i, i);
list.repaint(bounds);
}
}
private void repaintTableSelection(JTable table) {
int minRow = table.getSelectionModel().getMinSelectionIndex();
int maxRow = table.getSelectionModel().getMaxSelectionIndex();
if (minRow == -1 || maxRow == -1) {
return;
}
int col0 = table.convertColumnIndexToView(COLUMN_FILENAME);
Rectangle first = table.getCellRect(minRow, col0, false);
Rectangle last = table.getCellRect(maxRow, col0, false);
Rectangle dirty = first.union(last);
table.repaint(dirty);
}
};
private boolean smallIconsView = false;
private Border listViewBorder;
private Color listViewBackground;
private boolean listViewWindowsStyle;
private boolean readOnly;
private boolean fullRowSelection = false;
private ListSelectionModel listSelectionModel;
private JList list;
private JTable detailsTable;
private static final int COLUMN_FILENAME = 0;
// Provides a way to recognize a newly created folder, so it can
// be selected when it appears in the model.
private File newFolderFile;
// Used for accessing methods in the corresponding UI class
private FileChooserUIAccessor fileChooserUIAccessor;
private DetailsTableModel detailsTableModel;
private DetailsTableRowSorter rowSorter;
public FilePane(FileChooserUIAccessor fileChooserUIAccessor) {
super(new BorderLayout());
this.fileChooserUIAccessor = fileChooserUIAccessor;
installDefaults();
createActionMap();
}
public void uninstallUI() {
if (getModel() != null) {
getModel().removePropertyChangeListener(this);
}
}
protected JFileChooser getFileChooser() {
return fileChooserUIAccessor.getFileChooser();
}
protected BasicDirectoryModel getModel() {
return fileChooserUIAccessor.getModel();
}
public int getViewType() {
return viewType;
}
public void setViewType(int viewType) {
if (viewType == this.viewType) {
return;
}
int oldValue = this.viewType;
this.viewType = viewType;
JPanel createdViewPanel = null;
Component newFocusOwner = null;
switch (viewType) {
case VIEWTYPE_LIST:
if (viewPanels[viewType] == null) {
createdViewPanel = fileChooserUIAccessor.createList();
if (createdViewPanel == null) {
createdViewPanel = createList();
}
list = (JList) findChildComponent(createdViewPanel, JList.class);
if (listSelectionModel == null) {
listSelectionModel = list.getSelectionModel();
if (detailsTable != null) {
detailsTable.setSelectionModel(listSelectionModel);
}
} else {
list.setSelectionModel(listSelectionModel);
}
}
list.setLayoutOrientation(JList.VERTICAL_WRAP);
newFocusOwner = list;
break;
case VIEWTYPE_DETAILS:
if (viewPanels[viewType] == null) {
createdViewPanel = fileChooserUIAccessor.createDetailsView();
if (createdViewPanel == null) {
createdViewPanel = createDetailsView();
}
detailsTable = (JTable) findChildComponent(createdViewPanel, JTable.class);
detailsTable.setRowHeight(Math.max(detailsTable.getFont().getSize() + 4, 16 + 1));
if (listSelectionModel != null) {
detailsTable.setSelectionModel(listSelectionModel);
}
}
newFocusOwner = detailsTable;
break;
}
if (createdViewPanel != null) {
viewPanels[viewType] = createdViewPanel;
recursivelySetInheritsPopupMenu(createdViewPanel, true);
}
boolean isFocusOwner = false;
if (currentViewPanel != null) {
Component owner = DefaultKeyboardFocusManager.
getCurrentKeyboardFocusManager().getPermanentFocusOwner();
isFocusOwner = owner == detailsTable || owner == list;
remove(currentViewPanel);
}
currentViewPanel = viewPanels[viewType];
add(currentViewPanel, BorderLayout.CENTER);
if (isFocusOwner && newFocusOwner != null) {
newFocusOwner.requestFocusInWindow();
}
revalidate();
repaint();
updateViewMenu();
firePropertyChange("viewType", oldValue, viewType);
}
class ViewTypeAction extends AbstractAction {
private int viewType;
ViewTypeAction(int viewType) {
super(viewTypeActionNames[viewType]);
this.viewType = viewType;
String cmd;
switch (viewType) {
case VIEWTYPE_LIST: cmd = ACTION_VIEW_LIST; break;
case VIEWTYPE_DETAILS: cmd = ACTION_VIEW_DETAILS; break;
default: cmd = (String)getValue(Action.NAME);
}
putValue(Action.ACTION_COMMAND_KEY, cmd);
}
public void actionPerformed(ActionEvent e) {
setViewType(viewType);
}
}
public Action getViewTypeAction(int viewType) {
return new ViewTypeAction(viewType);
}
private static void recursivelySetInheritsPopupMenu(Container container, boolean b) {
if (container instanceof JComponent) {
((JComponent)container).setInheritsPopupMenu(b);
}
int n = container.getComponentCount();
for (int i = 0; i < n; i++) {
recursivelySetInheritsPopupMenu((Container)container.getComponent(i), b);
}
}
protected void installDefaults() {
Locale l = getFileChooser().getLocale();
listViewBorder = UIManager.getBorder("FileChooser.listViewBorder");
listViewBackground = UIManager.getColor("FileChooser.listViewBackground");
listViewWindowsStyle = UIManager.getBoolean("FileChooser.listViewWindowsStyle");
readOnly = UIManager.getBoolean("FileChooser.readOnly");
// TODO: On windows, get the following localized strings from the OS
viewMenuLabelText =
UIManager.getString("FileChooser.viewMenuLabelText", l);
refreshActionLabelText =
UIManager.getString("FileChooser.refreshActionLabelText", l);
newFolderActionLabelText =
UIManager.getString("FileChooser.newFolderActionLabelText", l);
viewTypeActionNames = new String[VIEWTYPE_COUNT];
viewTypeActionNames[VIEWTYPE_LIST] =
UIManager.getString("FileChooser.listViewActionLabelText", l);
viewTypeActionNames[VIEWTYPE_DETAILS] =
UIManager.getString("FileChooser.detailsViewActionLabelText", l);
kiloByteString = UIManager.getString("FileChooser.fileSizeKiloBytes", l);
megaByteString = UIManager.getString("FileChooser.fileSizeMegaBytes", l);
gigaByteString = UIManager.getString("FileChooser.fileSizeGigaBytes", l);
fullRowSelection = UIManager.getBoolean("FileView.fullRowSelection");
filesListAccessibleName = UIManager.getString("FileChooser.filesListAccessibleName", l);
filesDetailsAccessibleName = UIManager.getString("FileChooser.filesDetailsAccessibleName", l);
renameErrorTitleText = UIManager.getString("FileChooser.renameErrorTitleText", l);
renameErrorText = UIManager.getString("FileChooser.renameErrorText", l);
renameErrorFileExistsText = UIManager.getString("FileChooser.renameErrorFileExistsText", l);
}
/**
* Fetches the command list for the FilePane. These commands
* are useful for binding to events, such as in a keymap.
*
* @return the command list
*/
public Action[] getActions() {
if (actions == null) {
class FilePaneAction extends AbstractAction {
FilePaneAction(String name) {
this(name, name);
}
FilePaneAction(String name, String cmd) {
super(name);
putValue(Action.ACTION_COMMAND_KEY, cmd);
}
public void actionPerformed(ActionEvent e) {
String cmd = (String)getValue(Action.ACTION_COMMAND_KEY);
if (cmd == ACTION_CANCEL) {
if (editFile != null) {
cancelEdit();
} else {
getFileChooser().cancelSelection();
}
} else if (cmd == ACTION_EDIT_FILE_NAME) {
JFileChooser fc = getFileChooser();
int index = listSelectionModel.getMinSelectionIndex();
if (index >= 0 && editFile == null &&
(!fc.isMultiSelectionEnabled() ||
fc.getSelectedFiles().length <= 1)) {
editFileName(index);
}
} else if (cmd == ACTION_REFRESH) {
getFileChooser().rescanCurrentDirectory();
}
}
public boolean isEnabled() {
String cmd = (String)getValue(Action.ACTION_COMMAND_KEY);
if (cmd == ACTION_CANCEL) {
return getFileChooser().isEnabled();
} else if (cmd == ACTION_EDIT_FILE_NAME) {
return !readOnly && getFileChooser().isEnabled();
} else {
return true;
}
}
}
ArrayList<Action> actionList = new ArrayList(8);
Action action;
actionList.add(new FilePaneAction(ACTION_CANCEL));
actionList.add(new FilePaneAction(ACTION_EDIT_FILE_NAME));
actionList.add(new FilePaneAction(refreshActionLabelText, ACTION_REFRESH));
action = fileChooserUIAccessor.getApproveSelectionAction();
if (action != null) {
actionList.add(action);
}
action = fileChooserUIAccessor.getChangeToParentDirectoryAction();
if (action != null) {
actionList.add(action);
}
action = getNewFolderAction();
if (action != null) {
actionList.add(action);
}
action = getViewTypeAction(VIEWTYPE_LIST);
if (action != null) {
actionList.add(action);
}
action = getViewTypeAction(VIEWTYPE_DETAILS);
if (action != null) {
actionList.add(action);
}
actions = actionList.toArray(new Action[actionList.size()]);
}
return actions;
}
protected void createActionMap() {
addActionsToMap(super.getActionMap(), getActions());
}
public static void addActionsToMap(ActionMap map, Action[] actions) {
if (map != null && actions != null) {
for (Action a : actions) {
String cmd = (String)a.getValue(Action.ACTION_COMMAND_KEY);
if (cmd == null) {
cmd = (String)a.getValue(Action.NAME);
}
map.put(cmd, a);
}
}
}
private void updateListRowCount(JList list) {
if (smallIconsView) {
list.setVisibleRowCount(getModel().getSize() / 3);
} else {
list.setVisibleRowCount(-1);
}
}
public JPanel createList() {
JPanel p = new JPanel(new BorderLayout());
final JFileChooser fileChooser = getFileChooser();
final JList<Object> list = new JList
Other Java examples (source code examples)
Here is a short list of links related to this Java FilePane.java source code file: