001: /*
002: * @(#)FileIntelliHints.java 7/24/2005
003: *
004: * Copyright 2002 - 2005 JIDE Software Inc. All rights reserved.
005: */
006: package com.jidesoft.hints;
007:
008: import javax.swing.*;
009: import javax.swing.text.BadLocationException;
010: import javax.swing.text.JTextComponent;
011: import java.awt.*;
012: import java.io.File;
013: import java.io.FilenameFilter;
014:
015: /**
016: * <code>FileIntelliHints</code> is a concrete implementation of {@link com.jidesoft.hints.IntelliHints}.
017: * It allows user to type in a file patch quickly by providing them the hints based on what
018: * is existed on file system. You can use {@link #setFolderOnly(boolean)} to control if
019: * the hints contain only the folders, or folders and files.
020: */
021: public class FileIntelliHints extends AbstractListIntelliHints {
022: private boolean _folderOnly = false;
023: private boolean _showFullPath = true;
024:
025: public FileIntelliHints(JTextComponent comp) {
026: super (comp);
027: }
028:
029: /**
030: * If the hints contain the folder names only.
031: *
032: * @return true if the hints contain the folder names only.
033: */
034: public boolean isFolderOnly() {
035: return _folderOnly;
036: }
037:
038: /**
039: * Sets the property of folder only. If true, the hints will only show the folder names.
040: * Otherwise, both folder and file names will be shown in the hints.
041: *
042: * @param folderOnly only provide hints for the folders.
043: */
044: public void setFolderOnly(boolean folderOnly) {
045: _folderOnly = folderOnly;
046: }
047:
048: /**
049: * If the hints contain the full path.
050: *
051: * @return true if the hints contain the full path.
052: */
053: public boolean isShowFullPath() {
054: return _showFullPath;
055: }
056:
057: /**
058: * Sets the property of showing full path. If true, the hints will show the full path.
059: * Otherwise, it will only show the path after user typed in so far.
060: *
061: * @param showFullPath whether show the full path.
062: */
063: public void setShowFullPath(boolean showFullPath) {
064: _showFullPath = showFullPath;
065: }
066:
067: public boolean updateHints(Object value) {
068: if (value == null) {
069: return false;
070: }
071: String s = value.toString();
072: if (s.length() == 0) {
073: return false;
074: }
075: int index1 = s.lastIndexOf('\\');
076: int index2 = s.lastIndexOf('/');
077: int index = Math.max(index1, index2);
078: if (index == -1)
079: return false;
080: String dir = s.substring(0, index + 1);
081: final String prefix = index == s.length() - 1 ? null : s
082: .substring(index + 1).toLowerCase();
083: String[] files = new File(dir).list(new FilenameFilter() {
084: public boolean accept(File dir, String name) {
085: if (isFolderOnly()) {
086: if (new File(dir.getAbsolutePath() + File.separator
087: + name).isFile()) {
088: return false;
089: }
090: }
091: return prefix == null
092: || name.toLowerCase().startsWith(prefix);
093: }
094: });
095:
096: if (files == null
097: || files.length == 0
098: || (files.length == 1 && files[0]
099: .equalsIgnoreCase(prefix))) {
100: setListData(new String[0]);
101: return false;
102: } else {
103: getList().setCellRenderer(
104: new PrefixListCellRenderer(isShowFullPath() ? dir
105: : ""));
106: setListData(files);
107: return true;
108: }
109: }
110:
111: @Override
112: public void acceptHint(Object selected) {
113: if (selected == null)
114: return;
115:
116: String selectedValue = "" + selected;
117:
118: String value = getTextComponent().getText();
119: int caretPosition = getTextComponent().getCaretPosition();
120: int index1 = value.lastIndexOf('\\', caretPosition);
121: int index2 = value.lastIndexOf('/', caretPosition);
122: int index = Math.max(index1, index2);
123: if (index == -1) {
124: return;
125: }
126: int prefixlen = caretPosition - index - 1;
127: try {
128: getTextComponent().getDocument().insertString(
129: caretPosition, selectedValue.substring(prefixlen),
130: null);
131: } catch (BadLocationException e) {
132: e.printStackTrace();
133: }
134: }
135:
136: private class PrefixListCellRenderer extends
137: DefaultListCellRenderer {
138: private String _prefix;
139:
140: public PrefixListCellRenderer(String prefix) {
141: _prefix = prefix;
142: }
143:
144: @Override
145: public Component getListCellRendererComponent(JList list,
146: Object value, int index, boolean isSelected,
147: boolean cellHasFocus) {
148: return super.getListCellRendererComponent(list, _prefix
149: + value, index, isSelected, cellHasFocus);
150: }
151: }
152: }
|