Lines 23-28
Link Here
|
23 |
import java.beans.PropertyChangeListener; |
23 |
import java.beans.PropertyChangeListener; |
24 |
import java.beans.PropertyVetoException; |
24 |
import java.beans.PropertyVetoException; |
25 |
import java.beans.VetoableChangeListener; |
25 |
import java.beans.VetoableChangeListener; |
|
|
26 |
import java.util.Enumeration; |
26 |
import java.util.ArrayList; |
27 |
import java.util.ArrayList; |
27 |
import java.util.Arrays; |
28 |
import java.util.Arrays; |
28 |
import javax.swing.*; |
29 |
import javax.swing.*; |
Lines 1123-1128
Link Here
|
1123 |
// TreeCancelEditingAction was fixed in BasicTreeUI for JDK1.4 |
1124 |
// TreeCancelEditingAction was fixed in BasicTreeUI for JDK1.4 |
1124 |
getActionMap().put("cancel", new OurTreeCancelEditingAction()); // NOI18N |
1125 |
getActionMap().put("cancel", new OurTreeCancelEditingAction()); // NOI18N |
1125 |
} |
1126 |
} |
|
|
1127 |
setupSearch(); |
1128 |
} |
1129 |
|
1130 |
private JTextField searchTextField = new JTextField(); |
1131 |
|
1132 |
private void setupSearch() { |
1133 |
KeyListener keyListeners[] = getKeyListeners(); |
1134 |
for (int i = 0; i < keyListeners.length; i++) { |
1135 |
removeKeyListener(keyListeners[i]); |
1136 |
} |
1137 |
// Invoked when the search field should be dismissed by using |
1138 |
// the escape key |
1139 |
ActionListener escapeListener = new ActionListener() { |
1140 |
public void actionPerformed(ActionEvent e) { |
1141 |
removeSearchField(); |
1142 |
} |
1143 |
}; |
1144 |
searchTextField.registerKeyboardAction(escapeListener, |
1145 |
KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), 0); |
1146 |
// An action in the textfield will expand the selected node |
1147 |
searchTextField.addActionListener(new ActionListener() { |
1148 |
public void actionPerformed(ActionEvent e) { |
1149 |
removeSearchField(); |
1150 |
expandPath(getSelectionPath()); |
1151 |
} |
1152 |
}); |
1153 |
// When the search field looses focus, hide it |
1154 |
// searchTextField.addFocusListener(new FocusAdapter() { |
1155 |
// public void focusLost(FocusEvent e) { |
1156 |
// removeSearchField(); |
1157 |
// } |
1158 |
// }); |
1159 |
// Every change in the search fields document adds invokes a new search |
1160 |
// action |
1161 |
searchTextField.getDocument().addDocumentListener(new DocumentListener() { |
1162 |
public void insertUpdate(DocumentEvent e) { |
1163 |
searchForNode(); |
1164 |
} |
1165 |
public void removeUpdate(DocumentEvent e) { |
1166 |
searchForNode(); |
1167 |
} |
1168 |
public void changedUpdate(DocumentEvent e) { |
1169 |
searchForNode(); |
1170 |
} |
1171 |
|
1172 |
private void searchForNode() { |
1173 |
String text = searchTextField.getText().toUpperCase(); |
1174 |
if (text.length() == 0) { |
1175 |
return; |
1176 |
} |
1177 |
|
1178 |
TreePath selectionPath = getSelectionPath(); |
1179 |
TreePath rootPath = new TreePath(getModel().getRoot()); |
1180 |
TreePath newPath = null; |
1181 |
if (selectionPath != null) { |
1182 |
newPath = doSearch(text, selectionPath); |
1183 |
} |
1184 |
if (newPath == null) { |
1185 |
newPath = doSearch(text, rootPath); |
1186 |
} |
1187 |
if (newPath != null) { |
1188 |
setSelectionPath(newPath); |
1189 |
scrollPathToVisible(newPath); |
1190 |
} else { |
1191 |
clearSelection(); |
1192 |
} |
1193 |
} |
1194 |
}); |
1195 |
// The first key press in the tree must be dispatched to the text field |
1196 |
addKeyListener(new KeyAdapter() { |
1197 |
public void keyPressed(KeyEvent e) { |
1198 |
char c = e.getKeyChar(); |
1199 |
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { |
1200 |
searchTextField.setText(String.valueOf(c)); |
1201 |
} |
1202 |
} |
1203 |
}); |
1204 |
// Any key press in the text field triggers the addition of the |
1205 |
// search field to the tree |
1206 |
ActionListener keyPressListener = new ActionListener() { |
1207 |
public void actionPerformed(ActionEvent e) { |
1208 |
displaySearchField(); |
1209 |
} |
1210 |
}; |
1211 |
registerKeyboardActions(keyPressListener, 'a', 'z'); |
1212 |
registerKeyboardActions(keyPressListener, 'A', 'Z'); |
1213 |
|
1214 |
} |
1215 |
|
1216 |
private int originalScrollMode; |
1217 |
|
1218 |
/** |
1219 |
* Method used to recursively search for a named node in a tree path. |
1220 |
*/ |
1221 |
private TreePath doSearch(String str, TreePath path) { |
1222 |
TreeNode node = (TreeNode) path.getLastPathComponent(); |
1223 |
if (node.toString().toUpperCase().startsWith(str)) { |
1224 |
// Return if the current path matches |
1225 |
return path; |
1226 |
} |
1227 |
// It's a collapsed path, so return |
1228 |
if (isCollapsed(path)) { |
1229 |
return null; |
1230 |
} |
1231 |
Enumeration children = node.children(); |
1232 |
while (children.hasMoreElements()) { |
1233 |
TreeNode child = (TreeNode) children.nextElement(); |
1234 |
TreePath newPath = path.pathByAddingChild(child); |
1235 |
if (child.toString().toUpperCase().startsWith(str)) { |
1236 |
return newPath; |
1237 |
} |
1238 |
// Recursive search |
1239 |
newPath = doSearch(str, newPath); |
1240 |
if (newPath != null) { |
1241 |
return newPath; |
1242 |
} |
1243 |
} |
1244 |
return null; |
1245 |
} |
1246 |
|
1247 |
private void registerKeyboardActions(ActionListener keyPressListener, char lowerChar, char upperChar) { |
1248 |
for (char c = lowerChar; c <= upperChar; c++) { |
1249 |
registerKeyboardAction(keyPressListener, KeyStroke.getKeyStroke(c), 0); |
1250 |
} |
1251 |
} |
1252 |
/** |
1253 |
* Adds the search field to the tree. |
1254 |
*/ |
1255 |
private void displaySearchField() { |
1256 |
if (!searchTextField.isDisplayable()) { |
1257 |
JViewport viewport = TreeView.this.getViewport(); |
1258 |
originalScrollMode = viewport.getScrollMode(); |
1259 |
viewport.setScrollMode(JViewport.SIMPLE_SCROLL_MODE); |
1260 |
Rectangle visibleTreeRect = getVisibleRect(); |
1261 |
add(searchTextField); |
1262 |
repaint(); |
1263 |
searchTextField.requestFocus(); |
1264 |
} |
1265 |
} |
1266 |
|
1267 |
public void paint(Graphics g) { |
1268 |
Rectangle visibleRect = getVisibleRect(); |
1269 |
if (searchTextField.isDisplayable()) { |
1270 |
searchTextField.setBounds(visibleRect.x + visibleRect.width - 163, visibleRect.y + 3, 160, 18); |
1271 |
} |
1272 |
super.paint(g); |
1273 |
} |
1274 |
/** |
1275 |
* Removes the search field from the tree. |
1276 |
*/ |
1277 |
private void removeSearchField() { |
1278 |
searchTextField.setText(""); |
1279 |
remove(searchTextField); |
1280 |
TreeView.this.getViewport().setScrollMode(originalScrollMode); |
1281 |
repaint(); |
1282 |
requestFocus(); |
1126 |
} |
1283 |
} |
1127 |
|
1284 |
|
1128 |
|
1285 |
|