📄 fsatextfield.java
字号:
setText((String)fileList.getSelectedValue());
ignoreDocumentUpdates = false;
}
}
}
});
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "OnEnter");
actionMap.put("OnEnter", new AbstractAction() {
public void actionPerformed(ActionEvent e) {
// Hide the popup window if necessary and call the
// default binding.
if (popupWindow!=null && popupWindow.isVisible())
popupWindow.setVisible(false);
JRootPane root = SwingUtilities.getRootPane(
FSATextField.this);
if (root != null) {
InputMap im = root.getInputMap(
JComponent.WHEN_IN_FOCUSED_WINDOW);
ActionMap am = root.getActionMap();
if (im != null && am != null) {
Object obj = im.get(KeyStroke.getKeyStroke(
KeyEvent.VK_ENTER,0));
if (obj != null) {
Action action = am.get(obj);
if (action != null) {
action.actionPerformed(
new ActionEvent(
root, e.getID(),
e.getActionCommand(),
e.getWhen(),
e.getModifiers()));
}
}
}
}
}
});
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "OnEsc");
actionMap.put("OnEsc", new AbstractAction() {
public void actionPerformed(ActionEvent e) {
// Hide the popup window if necessary;
// otherwise, call the default binding.
if (popupWindow!=null && popupWindow.isVisible()) {
popupWindow.setVisible(false);
return;
}
JRootPane root = SwingUtilities.getRootPane(
FSATextField.this);
if (root != null) {
InputMap im = root.getInputMap(
JComponent.WHEN_IN_FOCUSED_WINDOW);
ActionMap am = root.getActionMap();
if (im != null && am != null) {
Object obj = im.get(KeyStroke.getKeyStroke(
KeyEvent.VK_ESCAPE,0));
if (obj != null) {
Action action = am.get(obj);
if (action != null) {
action.actionPerformed(
new ActionEvent(
root, e.getID(),
e.getActionCommand(),
e.getWhen(),
e.getModifiers()));
}
}
}
}
}
});
}
/*****************************************************************************/
/**
* Returns whether or not this text field previews both files and
* directories or just directories.
*
* @return Whether or not this text field shows only directories.
* @see #setDirectoriesOnly
*/
public boolean isDirectoriesOnly() {
return directoriesOnly;
}
/*****************************************************************************/
/**
* Called when the parent dialog/frame fires a component event. This
* method is here so we can hide the drop-down file list when the parent
* frame is moved or resized.
*
* @param e The component event fired by the parent dialog/frame.
*/
private void processParentComponentEvent(ComponentEvent e) {
switch (e.getID()) {
case ComponentEvent.COMPONENT_HIDDEN:
case ComponentEvent.COMPONENT_MOVED:
case ComponentEvent.COMPONENT_RESIZED:
updatePopupWindowDimensions();
if (popupWindow!=null)
setPopupVisible(false);
break;
case ComponentEvent.COMPONENT_SHOWN:
}
}
/*****************************************************************************/
/**
* Process the focus events of this text field. This is overridden so
* we can hide the drop-down file list if the text field loses focus.
*
* @param e The focus event fired by this text field.
*/
public void processFocusEvent(FocusEvent e) {
if (e.getID()==FocusEvent.FOCUS_LOST)
setPopupVisible(false);
super.processFocusEvent(e);
}
/*****************************************************************************/
/**
* Removes all items from the file list.
*
* @see #addItem
*/
public void removeAllItems() {
fileListModel.removeAllElements();
}
/*****************************************************************************/
/**
* Called when text is removed from the text component's document.
*/
public void removeUpdate(DocumentEvent e) {
if (isShowing() && fileSystemAware && !ignoreDocumentUpdates)
SwingUtilities.invokeLater(new Runnable() {
public void run() {
updateComboBoxContents();
}
});
}
/*****************************************************************************/
/**
* Sets the current directory for this text field. The current directory
* is the directory in which the text field assumes typed relative
* files reside in.
*
* @param currentDirectory The new "current directory" for this combo
* box. This value should be an absolute
* pathname.
* @see #getCurrentDirectory
*/
public void setCurrentDirectory(File currentDirectory) {
this.currentDirectory = currentDirectory.getAbsolutePath();
}
/*****************************************************************************/
/**
* Sets the current directory for this text field. The current directory
* is the directory in which the text field assumes typed relative
* files reside in.
*
* @param currentDirectory The new "current directory" for this combo
* box. This value should be an absolute
* pathname.
* @see #getCurrentDirectory
*/
public void setCurrentDirectory(String currentDirectory) {
this.currentDirectory = currentDirectory;
}
/*****************************************************************************/
/**
* Sets whether or not this text field previews both files and
* directories or just directories.
*
* @param directoriesOnly Whether or not to preview only directories.
* @see #isDirectoriesOnly
*/
public void setDirectoriesOnly(boolean directoriesOnly) {
// Lazily create the file filter used.
if (directoriesOnly) {
directoriesOnlyFilenameFilter = new FilenameFilter() {
public boolean accept(File parentDir, String fileName) {
return new File(parentDir.getAbsolutePath(),
fileName).isDirectory();
}
};
}
this.directoriesOnly = directoriesOnly;
}
/*****************************************************************************/
/**
* Sets the document for this text field. This is overridden so we can
* add a document listener to it.
*/
public void setDocument(Document document) {
if (document!=null) {
Document oldDocument = getDocument();
if (oldDocument!=null)
oldDocument.removeDocumentListener(this);
super.setDocument(document);
document.addDocumentListener(this);
}
}
/*****************************************************************************/
/**
* Toggles whether or not this dialog is file-system-aware. This
* property should be set to <code>false</code> when programmatically
* inserting text into the text field; otherwise, it has a bad habit of
* stealing the focus from the currently focused component, etc.
*
* @param aware Whether or not this text field should be file-system
* aware.
* @see #getFileSystemAware
*/
public void setFileSystemAware(boolean aware) {
fileSystemAware = aware;
}
/*****************************************************************************/
/**
* Toggles the display of the drop-down file list.
*
* @param visible Whether or not the file list is to be visible.
*/
private void setPopupVisible(boolean visible) {
if (visible) {
if (popupWindow==null) {
popupWindow = new JWindow(parent);
popupWindow.setFocusableWindowState(false);
popupWindow.setContentPane(contentPane);
}
popupWindow.pack();
Rectangle bounds = getBounds();
Point location = getLocation();
location.x = 0; // Why must we do this?
SwingUtilities.convertPointToScreen(location, this);
popupWindow.setLocation(location.x,
location.y+bounds.height-bounds.y);
popupWindow.setVisible(true);
}
else {
if (popupWindow!=null)
popupWindow.setVisible(false);
}
}
/*****************************************************************************/
/**
* Overridden so that we always have a document listener on the text field.
*/
public void setUI(javax.swing.plaf.TextUI ui) {
// Add the document listener.
Document document = getDocument();
if (document!=null)
document.removeDocumentListener(this);
super.setUI(ui);
getDocument().addDocumentListener(this);
// Update the scroll pane in the drop-down window.
if (popupWindow!=null)
SwingUtilities.updateComponentTreeUI(popupWindow);
// Install extra key actions.
installExtraKeyActions();
}
/*****************************************************************************/
/**
* Updates the text field's dropdown list to contain files matching
* the characters typed by the user into the text field's text field.
*/
private void updateComboBoxContents() {
String text = getText();
// We're nice and allow the user to type either '/' or '\\' as the separator on any OS.
int lastSeparator = Math.max(text.lastIndexOf('/'), text.lastIndexOf('\\')) + 1;
// Get the path for the file they're typing. If they haven't typed a
// separator char yet, assume it's a relative path from the current
// directory (and they're typing the name of a file in that directory).
// If they have typed a separator char, check to see if it's a relative
// directory path or an absolute one.
File t2 = null;
if (lastSeparator!=0) {
String pathPart = text.substring(0, lastSeparator);
t2 = new File(pathPart);
if (!t2.isAbsolute())
t2 = new File(currentDirectory, pathPart);
}
else {
if (text.length()==0) {
setPopupVisible(false);
lastCount = 0;
return;
}
t2 = new File(currentDirectory);
}
// An attempt to speed things up in the common case. If the
// directory they're working in hasn't changed, we don't
// have to get the list of files in the directory (as it is cached).
if (!t2.equals(directory)) {
directory = t2;
if (!directory.isDirectory()) {
lastCount = -1;
lastLastSeparator = 0;
setPopupVisible(false);
num = 0;
containedFiles = null;
return;
}
lastLastSeparator = lastSeparator;
dirName = directory.getAbsolutePath();
if (dirName.charAt(dirName.length()-1)!=File.separatorChar)
dirName += File.separatorChar; // Only need to add slash if not == "C:\" on Windows.
// If they only want to see directories, we have to take a little
// more care.
if (directoriesOnly) {
containedFiles = directory.list(directoriesOnlyFilenameFilter);
}
else {
containedFiles = directory.list();
}
// We must check for null here in case an IO error occurs.
num = containedFiles!=null ? containedFiles.length : 0;
} // End of if (lastSeparator!=lastLastSeparator).
if (num > 0) {
removeAllItems();
// We only match on the file name since the canonical-file path is
// cached in dirName.
String fpFileName = text.substring(lastSeparator);
int fpFileNameLength = fpFileName.length();
long count = 0;
for (int i=0; i<num; i++) {
// If fileName starts with fpFileName, matching case only in Windows...
if (containedFiles[i].regionMatches(IGNORE_CASE, 0, fpFileName, 0,fpFileNameLength)) {
count++;
addItem(dirName + containedFiles[i]);
}
}
if (count!=lastCount && count>0) {
// This tricks the popup menu's list to "resize" properly.
setPopupVisible(true);
}
else if (count==0)
setPopupVisible(false);
lastCount = count;
}
else {
lastCount = -1;
lastSeparator = 0;
setPopupVisible(false);
}
}
/*****************************************************************************/
/**
* Updates the size of the drop-down file list to match the width of the
* text field itself.
*/
private void updatePopupWindowDimensions() {
Dimension size = getSize();
contentPane.setMinimumSize(new Dimension(size.width,
contentPane.getMinimumSize().height));
contentPane.setPreferredSize(new Dimension(size.width,
contentPane.getPreferredSize().height));
contentPane.setMaximumSize(new Dimension(size.width,
contentPane.getMaximumSize().height));
}
/*****************************************************************************/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -