/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun * Microsystems, Inc. All Rights Reserved. */ package org.openide.loaders; import java.io.IOException; import java.lang.ref.Reference; import java.lang.ref.WeakReference; import java.awt.event.KeyEvent; import java.beans.PropertyDescriptor; import java.lang.reflect.Method; import javax.swing.KeyStroke; import javax.swing.SwingUtilities; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import org.openide.ErrorManager; import org.openide.explorer.propertysheet.DefaultPropertyModel; import org.openide.explorer.propertysheet.PropertyPanel; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileSystem; import org.openide.util.NbBundle; import org.openide.util.Utilities; /** Dialog that can be used in create from template. * * @author Jaroslav Tulach, Jiri Rechtacek */ final class TemplateWizard2 extends javax.swing.JPanel implements DocumentListener { /** listener to changes in the wizard */ private ChangeListener listener; private static final String PROP_LOCATION_FOLDER = "locationFolder"; // NOI18N private DataFolder locationFolder; private Reference fileSystemRef = new WeakReference (null); private DefaultPropertyModel locationFolderModel; /** File extension of the template and of the created file - * it is used to test whether file already exists. */ private String extension; /** Creates new form TemplateWizard2 */ public TemplateWizard2() { initLocationFolder (); initComponents (); setName (DataObject.getString("LAB_TargetLocationPanelName")); // NOI18N // registers itself to listen to changes in the content of document java.util.ResourceBundle bundle = org.openide.util.NbBundle.getBundle(TemplateWizard2.class); newObjectName.getDocument().addDocumentListener(this); newObjectName.unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0)); newObjectName.getAccessibleContext().setAccessibleDescription(bundle.getString("ACSD_NewObjectName")); // NOI18N } /** This method is called from within the constructor to * initialize the location folder and make it accessible. * The getter/setter methods must be accessible for purposes introspection. * Because this class is not public then these methods are made accessible explicitly. */ private void initLocationFolder () { PropertyDescriptor pd = null; try { Method getterMethod = this.getClass ().getDeclaredMethod("getLocationFolder", new Class[] {}); // NOI18N getterMethod.setAccessible (true); Method setterMethod = this.getClass ().getDeclaredMethod("setLocationFolder", new Class[] {DataFolder.class}); // NOI18N setterMethod.setAccessible (true); pd = new PropertyDescriptor (PROP_LOCATION_FOLDER, getterMethod, setterMethod); } catch (java.beans.IntrospectionException ie) { ErrorManager.getDefault ().notify (ie); } catch (NoSuchMethodException nsme) { ErrorManager.getDefault ().notify (nsme); } locationFolderModel = new DefaultPropertyModel (this, pd); } /** Getter for default name of a new object. * @return the default name. */ private static String defaultNewObjectName () { return DataObject.getString ("FMT_DefaultNewObjectName"); // NOI18N } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ private void initComponents() {//GEN-BEGIN:initComponents namePanel = new javax.swing.JPanel(); jLabel1 = new javax.swing.JLabel(); newObjectName = new javax.swing.JTextField(); dataFolderPanel = dataFolderPanel = new PropertyPanel (locationFolderModel, PropertyPanel.PREF_CUSTOM_EDITOR); setLayout(new java.awt.BorderLayout()); namePanel.setLayout(new java.awt.BorderLayout(12, 0)); jLabel1.setDisplayedMnemonic(java.util.ResourceBundle.getBundle("org/openide/loaders/Bundle").getString("CTL_NewObjectName_Mnemonic").charAt(0)); jLabel1.setLabelFor(newObjectName); jLabel1.setText(java.util.ResourceBundle.getBundle("org/openide/loaders/Bundle").getString("CTL_NewObjectName")); namePanel.add(jLabel1, java.awt.BorderLayout.WEST); newObjectName.addFocusListener(new java.awt.event.FocusAdapter() { public void focusGained(java.awt.event.FocusEvent evt) { TemplateWizard2.this.newObjectNameFocusGained(evt); } }); namePanel.add(newObjectName, java.awt.BorderLayout.CENTER); add(namePanel, java.awt.BorderLayout.NORTH); add(dataFolderPanel, java.awt.BorderLayout.CENTER); }//GEN-END:initComponents private void newObjectNameFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_newObjectNameFocusGained //Code below works perfectly on Solaris with JDK 1.3 or 1.4. The //lines below show up in CVS annotate as by jglick, Apr 25, 2000, which //is the major reformat/SPL addition for open sourcing NB. I'm //guessing this was some 1.2 bug that is irrelevant now, but leaving //it in place in case of a problem. -TDB /* if ( Utilities.getOperatingSystem() == Utilities.OS_SOLARIS | Utilities.getOperatingSystem() == Utilities.OS_SUNOS ) { // does not work on CDE window manager, so better do nothin return; } */ newObjectName.selectAll (); }//GEN-LAST:event_newObjectNameFocusGained /** Add a listener to changes of the panel's validity. * @param l the listener to add * @see #isValid * */ void addChangeListener(ChangeListener l) { if (listener != null) throw new IllegalStateException (); listener = l; } public void addNotify () { super.addNotify(); //Fix for issue 31086, initial focus on Back button newObjectName.requestFocus(); } /** Helper implementation of WizardDescription.Panel for TemplateWizard.Panel2. * Provides the wizard panel with the current data--either * the default data or already-modified settings, if the user used the previous and/or next buttons. * This method can be called multiple times on one instance of <code>WizardDescriptor.Panel</code>. * <p>The settings object is originally supplied to {@link WizardDescriptor#WizardDescriptor(WizardDescriptor.Iterator,Object)}. * In the case of a <code>TemplateWizard.Iterator</code> panel, the object is * in fact the <code>TemplateWizard</code>. * @param settings the object representing wizard panel state * @exception IllegalStateException if the the data provided * by the wizard are not valid. * */ void implReadSettings(Object settings) { TemplateWizard wizard = (TemplateWizard)settings; DataObject template = wizard.getTemplate (); if (template != null) { extension = template.getPrimaryFile().getExt(); } setNewObjectName (wizard.getTargetName ()); try { setLocationFolder (wizard.getTargetFolder ()); } catch (IOException ioe) { setLocationFolder (null); } } /** Remove a listener to changes of the panel's validity. * @param l the listener to remove * */ public void removeChangeListener(ChangeListener l) { listener = null; } /** Helper implementation of WizardDescription.Panel for TemplateWizard.Panel2. * Provides the wizard panel with the opportunity to update the * settings with its current customized state. * Rather than updating its settings with every change in the GUI, it should collect them, * and then only save them when requested to by this method. * Also, the original settings passed to {@link #readSettings} should not be modified (mutated); * rather, the object passed in here should be mutated according to the collected changes, * in case it is a copy. * This method can be called multiple times on one instance of <code>WizardDescriptor.Panel</code>. * <p>The settings object is originally supplied to {@link WizardDescriptor#WizardDescriptor(WizardDescriptor.Iterator,Object)}. * In the case of a <code>TemplateWizard.Iterator</code> panel, the object is * in fact the <code>TemplateWizard</code>. * @param settings the object representing wizard panel state * */ void implStoreSettings(Object settings) { TemplateWizard wizard = (TemplateWizard)settings; wizard.setTargetFolder (locationFolder); String name = newObjectName.getText (); if (name.equals (defaultNewObjectName ())) { name = null; } wizard.setTargetName (name); } /** Helper implementation of WizardDescription.Panel for TemplateWizard.Panel2. * Test whether the panel is finished and it is safe to proceed to the next one. * If the panel is valid, the "Next" (or "Finish") button will be enabled. * @return <code>null</code> if the user has entered satisfactory information * or localized string describing the error. */ String implIsValid () { // test whether the selected folder on selected filesystem already exists FileSystem fs = (FileSystem)fileSystemRef.get (); if (locationFolder == null || fs == null) return NbBundle.getMessage(TemplateWizard2.class, "MSG_fs_or_folder_does_not_exist"); // NOI18N // target filesystem should be writable if (((FileSystem)fileSystemRef.get ()).isReadOnly ()) return NbBundle.getMessage(TemplateWizard2.class, "MSG_fs_is_readonly"); // NOI18N if (locationFolder == null) locationFolder = DataFolder.findFolder (fs.getRoot()); // test whether the selected name already exists StringBuffer sb = new StringBuffer (); sb.append (locationFolder.getPrimaryFile ().getPath ()); sb.append ("/"); sb.append (newObjectName.getText ()); if ("" != extension) { // NOI18N sb.append ('.'); sb.append (extension); } FileObject f = fs.findResource (sb.toString ()); if (f != null) { return NbBundle.getMessage(TemplateWizard2.class, "MSG_file_already_exist", sb.toString()); // NOI18N } // all ok return null; } /** Gives notification that an attribute or set of attributes changed. * * @param e the document event * */ public void changedUpdate(DocumentEvent e) { if (e.getDocument () == newObjectName.getDocument ()) { SwingUtilities.invokeLater (new Updater ()); } } /** Gives notification that there was an insert into the document. The * range given by the DocumentEvent bounds the freshly inserted region. * * @param e the document event * */ public void insertUpdate(DocumentEvent e) { changedUpdate (e); } /** Gives notification that a portion of the document has been * removed. The range is given in terms of what the view last * saw (that is, before updating sticky positions). * * @param e the document event * */ public void removeUpdate(DocumentEvent e) { // so just check the name if (e.getDocument () == newObjectName.getDocument ()) { SwingUtilities.invokeLater (new Updater ()); } } /** Does the update called from changedUpdate, insertUpdate and * removeUpdate methods. */ private class Updater implements Runnable { Updater() {} public void run () { if (newObjectName.getText().equals ("")) { // NOI18N setNewObjectName (""); // NOI18N } fireStateChanged (); } } /** Request focus. */ public void requestFocus () { newObjectName.requestFocus(); newObjectName.selectAll (); } /** Sets the class name to some reasonable value. * @param name the name to set the name to */ private void setNewObjectName (String name) { String n = name; if (name == null || name.length () == 0) { n = defaultNewObjectName (); } newObjectName.getDocument().removeDocumentListener(this); newObjectName.setText (n); newObjectName.getDocument().addDocumentListener(this); if (name == null || name.length () == 0) { newObjectName.selectAll (); } } /** Fires info to listener. */ private void fireStateChanged () { if (listener != null) { listener.stateChanged (new ChangeEvent (this)); } } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JTextField newObjectName; private javax.swing.JLabel jLabel1; private javax.swing.JPanel namePanel; private org.openide.explorer.propertysheet.PropertyPanel dataFolderPanel; // End of variables declaration//GEN-END:variables public void setLocationFolder (DataFolder fd) { if (locationFolder == fd) return ; if (locationFolder != null && locationFolder.equals (fd)) return ; DataFolder oldLocation = locationFolder; locationFolder = fd; firePropertyChange (PROP_LOCATION_FOLDER, oldLocation, locationFolder); if (fd != null) { try { fileSystemRef = new WeakReference (fd.getPrimaryFile ().getFileSystem ()); } catch (org.openide.filesystems.FileStateInvalidException fsie) { fileSystemRef = new WeakReference (null); } } fireStateChanged (); } public DataFolder getLocationFolder () { return locationFolder; } }