1 19 20 package org.netbeans.beaninfo.editors; 21 22 import java.awt.event.ActionEvent ; 23 import java.awt.event.KeyEvent ; 24 import java.awt.Component ; 25 import java.awt.Container ; 26 import java.awt.Dialog ; 27 import java.awt.KeyboardFocusManager ; 28 import java.beans.PropertyChangeEvent ; 29 import java.beans.PropertyChangeListener ; 30 import java.beans.PropertyEditorSupport ; 31 import java.io.File ; 32 import java.io.FilenameFilter ; 33 import java.util.logging.Level ; 34 import java.util.logging.Logger ; 35 import javax.swing.AbstractAction ; 36 import javax.swing.AbstractButton ; 37 import javax.swing.Action ; 38 import javax.swing.JComboBox ; 39 import javax.swing.JComponent ; 40 import javax.swing.JFileChooser ; 41 import javax.swing.JScrollBar ; 42 import javax.swing.KeyStroke ; 43 import org.openide.nodes.Node; 44 import org.openide.explorer.propertysheet.ExPropertyEditor; 45 import org.openide.explorer.propertysheet.PropertyEnv; 46 import org.openide.util.HelpCtx; 47 import org.openide.util.NbBundle; 48 49 54 public class FileEditor extends PropertyEditorSupport implements ExPropertyEditor, PropertyChangeListener { 55 56 57 static final String PROPERTY_SHOW_DIRECTORIES = "directories"; 59 60 static final String PROPERTY_SHOW_FILES = "files"; 62 63 static final String PROPERTY_FILTER = "filter"; 65 66 static final String PROPERTY_CURRENT_DIR = "currentDir"; 68 69 static final String PROPERTY_BASE_DIR = "baseDir"; 71 72 static final String PROPERTY_FILE_HIDING = "file_hiding"; 74 75 private int mode = JFileChooser.FILES_AND_DIRECTORIES; 76 77 78 private boolean directories = true; 79 80 private boolean files = true; 81 82 private boolean fileHiding = false; 83 84 private javax.swing.filechooser.FileFilter fileFilter; 85 86 private File currentDirectory; 87 88 private File baseDirectory; 89 90 91 static File lastCurrentDir; 92 93 private PropertyEnv env; 94 95 101 private JFileChooser chooser; 102 103 104 private boolean editable = true; 105 106 111 public void attachEnv(PropertyEnv env) { 112 this.env = env; 113 114 directories = true; 116 files = true; 117 fileFilter = null; 118 fileHiding = false; 119 120 Object dirs = env.getFeatureDescriptor().getValue(PROPERTY_SHOW_DIRECTORIES); 121 if (dirs instanceof Boolean ) { 122 directories = ((Boolean )dirs).booleanValue(); 123 } Object fil = env.getFeatureDescriptor().getValue(PROPERTY_SHOW_FILES); 125 if (fil instanceof Boolean ) { 126 files = ((Boolean )fil).booleanValue(); 127 } Object filter = env.getFeatureDescriptor().getValue(PROPERTY_FILTER); 129 if (filter instanceof FilenameFilter ) { 130 fileFilter = new DelegatingFilenameFilter((FilenameFilter )filter); 131 } else if (filter instanceof javax.swing.filechooser.FileFilter ) { 132 fileFilter = (javax.swing.filechooser.FileFilter )filter; 133 } else if (filter instanceof java.io.FileFilter ) { 134 fileFilter = new DelegatingFileFilter((java.io.FileFilter )filter); 135 } 137 Object curDir = env.getFeatureDescriptor().getValue(PROPERTY_CURRENT_DIR); 138 if (curDir instanceof File ) { 139 currentDirectory = (File )curDir; 140 if(! currentDirectory.isDirectory()) { 141 Logger.getAnonymousLogger().warning("java.io.File will not accept currentDir=" + currentDirectory); currentDirectory = null; 143 } 144 } 146 Object baseDir = env.getFeatureDescriptor().getValue(PROPERTY_BASE_DIR); 147 if(baseDir instanceof File ) { 148 baseDirectory = (File )baseDir; 149 if(!baseDirectory.isDirectory() || !baseDirectory.isAbsolute()) { 151 Logger.getAnonymousLogger().warning("java.io.File will not accept baseDir=" + baseDirectory); baseDirectory = null; 153 } 154 } if (files) { 156 mode = directories ? JFileChooser.FILES_AND_DIRECTORIES : 157 JFileChooser.FILES_ONLY; 158 } else { 159 mode = directories ? JFileChooser.DIRECTORIES_ONLY : 160 JFileChooser.FILES_AND_DIRECTORIES; } 162 163 Object fileHide = env.getFeatureDescriptor().getValue(PROPERTY_FILE_HIDING); 164 if (fileHide instanceof Boolean ) { 165 fileHiding = ((Boolean )fileHide).booleanValue(); 166 } 167 168 if (env.getFeatureDescriptor() instanceof Node.Property){ 169 Node.Property prop = (Node.Property)env.getFeatureDescriptor(); 170 editable = prop.canWrite(); 171 } 172 } 173 174 177 public String getAsText() { 178 File file = (File )getValue(); 179 if (file == null) { 180 return ""; } 182 String path = file.getPath(); 183 if ("".equals(path)) path = "."; return path; 186 } 187 188 193 public void setAsText(String str) throws IllegalArgumentException { 194 if (str == null) { 195 throw new IllegalArgumentException ("null"); } 197 if ("".equals(str)) { setValue(null); 199 return; 200 } 201 if (".".equals(str)) str = ""; setValue(new File (str)); 204 } 205 206 209 public Component getCustomEditor() { 210 if (!editable) { 211 String info = ""; 212 Object curVal = getValue(); 213 if (curVal instanceof java.io.File ) { 214 info = ((java.io.File )curVal).getAbsolutePath(); 215 } 216 return new StringCustomEditor(info, false, true, null, this, env); 217 } 218 if (chooser == null) { 219 chooser = createHackedFileChooser(); 220 221 File originalFile = (File )getValue (); 222 if (originalFile != null && ! originalFile.isAbsolute() && baseDirectory != null) { 223 originalFile = new File (baseDirectory, originalFile.getPath()); 224 } 225 if (currentDirectory != null) { 226 chooser.setCurrentDirectory (currentDirectory); 227 } else if (originalFile != null && originalFile.getParentFile() != null) { 228 chooser.setCurrentDirectory (originalFile.getParentFile()); 229 chooser.setSelectedFile (originalFile); 230 } else if (lastCurrentDir != null) { 231 chooser.setCurrentDirectory(lastCurrentDir); 232 } 233 chooser.setFileSelectionMode(mode); 234 if (fileFilter != null) { 235 chooser.setFileFilter(fileFilter); 236 } 237 switch (mode) { 238 case JFileChooser.FILES_AND_DIRECTORIES: 239 chooser.setDialogTitle (getString ("CTL_DialogTitleFilesAndDirs")); 240 break; 241 case JFileChooser.FILES_ONLY: 242 chooser.setDialogTitle (getString ("CTL_DialogTitleFiles")); 243 break; 244 case JFileChooser.DIRECTORIES_ONLY: 245 chooser.setDialogTitle (getString ("CTL_DialogTitleDirs")); 246 break; 247 } 248 chooser.setFileHidingEnabled(fileHiding); 249 250 chooser.setControlButtonsAreShown(false); 251 252 chooser.addPropertyChangeListener( 253 JFileChooser.SELECTED_FILE_CHANGED_PROPERTY, 254 this 255 ); 256 257 HelpCtx.setHelpIDString (chooser, getHelpCtx ().getHelpID ()); 258 } 259 260 return chooser; 261 } 262 263 266 public boolean supportsCustomEditor() { 267 return true; 268 } 269 270 273 public String getJavaInitializationString() { 274 File value = (File ) getValue (); 275 if (value == null) { 276 return "null"; } else { 278 if (baseDirectory != null && !value.isAbsolute()) { 281 return "new java.io.File(" + stringify(baseDirectory.getPath()) 283 + ", " + stringify(value.getPath()) 285 + ")"; } else { 287 return "new java.io.File(" + stringify(value.getAbsolutePath()) 289 + ")"; } 291 } 292 } 293 static String stringify(String in) { 294 StringBuffer buf = new StringBuffer (in.length() * 2 + 2); 295 buf.append('"'); for (int i = 0; i < in.length(); i++) { 297 char c = in.charAt(i); 298 if (c == '\\' || c == '"') { buf.append('\\'); } 301 buf.append(c); 302 } 303 buf.append('"'); return buf.toString(); 305 } 306 307 308 private HelpCtx getHelpCtx () { 309 return new HelpCtx (FileEditor.class); 310 } 311 312 313 private static String getString(String key) { 314 return NbBundle.getBundle(FileEditor.class).getString(key); 315 } 316 317 323 static String getChildRelativePath(File baseDir, File file) { 324 if (file.equals(baseDir)) { 328 return ""; } 332 StringBuffer buf = new StringBuffer (file.getPath().length()); 333 buf.append(file.getName()); 334 for (File parent = file.getParentFile(); parent != null; parent = parent.getParentFile()) { 335 if (parent.equals(baseDir)) { 336 return buf.toString(); 337 } 338 buf.insert(0, File.separatorChar); 339 buf.insert(0, parent.getName()); 340 } 341 return null; 342 } 343 344 345 public void propertyChange(PropertyChangeEvent e) { 346 JFileChooser chooser = (JFileChooser )e.getSource(); 347 File f = chooser.getSelectedFile(); 348 if (f == null) { 349 return; 350 } 351 if (!files && f.isFile ()) return; 352 if (!directories && f.isDirectory ()) return; 353 354 if (baseDirectory != null) { 355 String rel = getChildRelativePath(baseDirectory, f); 356 if (rel != null) { 357 f = new File (rel); 358 } 359 } 360 361 setValue(new File (f.getPath())); 366 367 lastCurrentDir = chooser.getCurrentDirectory(); 368 } 369 370 374 public static JFileChooser createHackedFileChooser() { 375 JFileChooser chooser = new JFileChooser (); 376 hackFileChooser(chooser); 377 return chooser; 378 } 379 380 382 public static void hackFileChooser(final JFileChooser chooser) { 383 chooser.getAccessibleContext().setAccessibleDescription( getString("ACSD_FileEditor") ); 384 385 final Object key = chooser.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).get( 389 KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0)); 390 391 Action close = new AbstractAction () { 392 public void actionPerformed(ActionEvent ae) { 393 Component comp = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); 394 if (key != null) { 395 Action a = chooser.getActionMap().get(key); 397 if (a != null) { 398 a.actionPerformed(ae); 399 } 400 } 401 if (comp.getParent() == null) { 402 return; 405 } 406 407 Container c = chooser.getTopLevelAncestor(); 408 if (c instanceof Dialog ) { 411 if (((Dialog ) c).isVisible()) { 412 ((Dialog ) c).setVisible (false); 413 ((Dialog ) c).dispose(); 414 } 415 } 416 } 417 }; 418 chooser.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put( 419 KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "close"); 420 chooser.getActionMap().put("close", close); 421 } 422 423 private static class ButtonHider implements PropertyChangeListener { 424 public void propertyChange (PropertyChangeEvent pce) { 425 if (JFileChooser.CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY.equals(pce.getPropertyName())) { 426 JFileChooser jfc = (JFileChooser ) pce.getSource(); 427 try { 428 hideShowButtons(jfc, Boolean.TRUE.equals(pce.getNewValue())); 429 } catch (Exception e) { 430 Logger.getLogger(FileEditor.class.getName()).log(Level.WARNING, null, e); 431 } 432 } 433 } 434 435 private void hideShowButtons (Container cont, boolean val) { 436 if (cont instanceof JComboBox || cont instanceof JScrollBar ) { 437 return; 438 } 439 Component [] c = cont.getComponents(); 440 for (int i=0; i < c.length; i++) { 441 if (c[i] instanceof Container ) { 442 hideShowButtons ((Container ) c[i], val); 443 } 444 if (c[i] instanceof AbstractButton ) { 445 c[i].setVisible(val); 446 } 447 } 448 } 449 } 450 451 452 static class DelegatingFileFilter extends javax.swing.filechooser.FileFilter { 453 private java.io.FileFilter filter; 454 455 public DelegatingFileFilter(java.io.FileFilter f) { 456 this.filter = f; 457 } 458 459 public boolean accept(File f) { 460 return filter.accept(f); 461 } 462 463 public String getDescription() { 464 return null; 466 } 467 468 } 470 471 472 static class DelegatingFilenameFilter extends javax.swing.filechooser.FileFilter { 473 private FilenameFilter filter; 474 475 public DelegatingFilenameFilter(FilenameFilter f) { 476 this.filter = f; 477 } 478 481 public boolean accept(File f) { 482 return filter.accept(f.getParentFile(), f.getName()); 483 } 484 485 public String getDescription() { 486 return null; 488 } 489 } 491 } 492 | Popular Tags |