Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   *
   * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
   *
   * The contents of this file are subject to the terms of either the GNU
   * General Public License Version 2 only ("GPL") or the Common
   * Development and Distribution License("CDDL") (collectively, the
   * "License"). You may not use this file except in compliance with the
  * License. You can obtain a copy of the License at
  * http://www.netbeans.org/cddl-gplv2.html
  * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  * specific language governing permissions and limitations under the
  * License.  When distributing the software, include this License Header
  * Notice in each file and include the License file at
  * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
  * particular file as subject to the "Classpath" exception as provided
  * by Sun in the GPL Version 2 section of the License file that
  * accompanied this code. If applicable, add the following below the
  * License Header, with the fields enclosed by brackets [] replaced by
  * your own identifying information:
  * "Portions Copyrighted [year] [name of copyright owner]"
  *
  * Contributor(s):
  *
  * The Original Software is NetBeans. The Initial Developer of the Original
  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
  * Microsystems, Inc. All Rights Reserved.
  *
  * If you wish your version of this file to be governed by only the CDDL
  * or only the GPL Version 2, indicate your decision by adding
  * "[Contributor] elects to include this software in this distribution
  * under the [CDDL or GPL Version 2] license." If you do not indicate a
  * single choice of license, a recipient has the option to distribute
  * your version of this file under either the CDDL, the GPL Version 2 or
  * to extend the choice of license to its licensees as provided above.
  * However, if you add GPL Version 2 code and therefore, elected the GPL
  * Version 2 license, then the option applies only if the new code is
  * made subject to such option by the copyright holder.
  */
 
 package org.netbeans.modules.cnd.makeproject.api.runprofiles;
 
 import java.io.File;
 import java.util.List;
 
 public class RunProfile implements ConfigurationAuxObject {
     private static final boolean NO_EXEPTION = Boolean.getBoolean("org.netbeans.modules.cnd.makeproject.api.runprofiles");
 
     public static final String PROFILE_ID = "runprofile"// NOI18N
     
    
Property name: runargs (args, cd, etc.) have changed
 
     public static final String PROP_RUNARGS_CHANGED = "runargs-ch"// NOI18N
     public static final String PROP_RUNDIR_CHANGED = "rundir-ch"// NOI18N
     public static final String PROP_ENVVARS_CHANGED = "envvars-ch"// NOI18N
     
     private PropertyChangeSupport pcs = null;
     
     private boolean needSave = false;
     
     // Auxiliary info objects (debugger, ...)
     private Vector auxObjects;
     
     // Where this profile is keept
     //private Profiles parent;
     // Clone
     private RunProfile cloneOf;
     // Default Profile. One and only one profile is the default.
    private boolean defaultProfile;
    // Arguments. Quoted flat representation.
    private String argsFlat;
    private boolean argsFlatValid = false;
    // Argumants. Array form.
    private String[] argsArray;
    private boolean argsArrayValid = false;
    // Run Directory. Relative or absolute.
    private String baseDir// Alwasy set, always absolute
    private String runDir;  // relative (to baseDir) or absolute
    // Should start a build before executing/debugging.
    private boolean buildFirst;
    // Environment
    private Env environment;
    private String dorun;
    
    public static final int CONSOLE_TYPE_DEFAULT = 0;
    public static final int CONSOLE_TYPE_EXTERNAL = 1;
    public static final int CONSOLE_TYPE_OUTPUT_WINDOW = 2;
    
    private static final String[] consoleTypeNames = {
        getString("ConsoleType_Default"), // NOI18N
        getString("ConsoleType_External"), // NOI18N
        getString("ConsoleType_Output"), // NOI18N
    };
    private IntConfiguration consoleType;
    
    private HashMap<StringStringtermPaths;
    private HashMap<StringStringtermOptions;
    private final int platform;
    
    // constructor for SS compatibility, only for localhost usage
    @Deprecated
    public RunProfile(String baseDir) {
        this(baseDir, Platform.getDefaultPlatform());
    }
    
    public RunProfile(String baseDirint platform) {
        this. = platform;
        this. = baseDir;
        this. = null;
        initialize();
    }
    
    public RunProfile(String baseDirPropertyChangeSupport pcs) {
         = Platform.getDefaultPlatform(); //TODO: it's not always right
        this. = baseDir;
        this. = pcs;
        initialize();
    }
    
    public void initialize() {
        //parent = null;
         = new Env();
         = false;
         = ""// NOI18N
         = true;
         = false;
         = ""// NOI18N
         = true;
         = getDorunScript();
         = new HashMap<StringString>();
         = new HashMap<StringString>();
         = new IntConfiguration(nullnull);
         = new IntConfiguration(null, 0, setTerminalTypeNames(), null);
        clearChanged();
    }
    private String escapeDir(String dir) {
        if (dir != null) {
            dir = dir.trim();
            String quote = "\""//NOI18N
            if (!dir.startsWith(quote)) { //NOI18N
                dir = quote + dir + quote//NOI18N
            }
        }
        return  dir;
    }
    private String getDorunScript() {
        File file = InstalledFileLocator.getDefault().locate("bin/dorun.sh"nullfalse); // NOI18N
        if (file != null && file.exists()) {
            return file.getAbsolutePath();
        } else {
            if (!) {
                throw new IllegalStateException(getString("Err_MissingDorunScript")); // NOI18N
            }
            return null;
        }
    }
    
    private boolean isWindows() {
        return  == .;
    }
    
    private String[] setTerminalTypeNames() {
        List<Stringlist = new ArrayList<String>();
        String def = getString("TerminalType_Default"); // NOI18N
        String name;
        String termPath;
        
        list.add(def);
        if (isWindows()) {
            String term = getString("TerminalType_CommandWindow"); // NOI18N
            list.add(term);
            .put(term"cmd.exe"); // NOI18N
            .put(def"cmd.exe"); // NOI18N
            .put(term"/c start sh \"" +  + "\" -p \"" + getString("LBL_RunPrompt") + " \" -f \"{0}\" {1} {2}"); // NOI18N
            .put(def,  "/c start sh \"" +  + "\" -p \"" + getString("LBL_RunPrompt") + " \" -f \"{0}\" {1} {2}"); // NOI18N
        } else {
            // Start with the user's $PATH. Append various other directories and look
            // for gnome-terminal, konsole, and xterm.
            String path = Path.getPathAsString() + 
                ":/usr/X11/bin:/usr/X/bin:/usr/X11R6/bin:/opt/gnome/bin" + // NOI18N
                ":/usr/gnome/bin:/opt/kde/bin:/opt/kde4/bin:/opt/kde3/bin:/usr/kde/bin:/usr/openwin/bin"// NOI18N
            
            termPath = searchPath(path"gnome-terminal""/usr/bin"); // NOI18N
            if (termPath != null) {
                name = getString("TerminalType_GNOME"); // NOI18N
                list.add(name); 
                .put(nametermPath);
                .put(deftermPath);
                String opts = "--disable-factory --hide-menubar " + "--title=\"{1} {3}\" " + // NOI18N
                        "-x \"" +  + "\" -p \"" + getString("LBL_RunPrompt") + "\" " + // NOI18N
                        "-f \"{0}\" {1} {2}"// NOI18N
                .put(nameopts);
                .put(def,  opts);
            }
            termPath = searchPath(path"konsole"); // NOI18N
            if (termPath != null) {
                name = getString("TerminalType_KDE"); // NOI18N
                list.add(name); 
                .put(nametermPath);
                .put(name"--workdir " + escapeDir() + " -e \"" +  + // NOI18N
                        "\" -p \"" + getString("LBL_RunPrompt") + "\" -f \"{0}\" {1} {2}"); // NOI18N
                if (.get(def) == null) {
                    .put(deftermPath);
                    .put(def"--workdir " + escapeDir() + " -e \"" +  + // NOI18N
                        "\" -p \"" + getString("LBL_RunPrompt") + "\" -f \"{0}\" {1} {2}"); // NOI18N
                }
            }
            termPath = searchPath(path"xterm", Utilities.getOperatingSystem() == . ? // NOI18N
                        "/usr/openwin/bin" : "/usr/bin"); // NOI18N
            if (termPath != null) {
                name = getString("TerminalType_XTerm"); // NOI18N
                list.add(name); 
                .put(nametermPath);
                .put(name,    "-e \"" +  + "\" -p \"" + getString("LBL_RunPrompt") + "\" -f \"{0}\" {1} {2}"); // NOI18N
                if (.get(def) == null) {
                    .put(deftermPath);
                    .put(def"-e \"" +  + "\" -p \"" + getString("LBL_RunPrompt") + "\" -f \"{0}\" {1} {2}"); // NOI18N
                }
            }
            if (.get(def) == null) {
                list.add(getString("TerminalType_None")); // NOI18N
            }
        }
        return list.toArray(new String[list.size()]);
    }
    
    
Search an augmented $PATH (the user's $PATH plus various standard locations for a specific terminal emulater.

Parameters:
path The path to search for program "term"
term The terminal program we're searching for
Returns:
Either a path to the specified term or null
    private String searchPath(String pathString term) {
        return searchPath(pathtermnull);
    }
    
    
Search an augmented $PATH (the user's $PATH plus various standard locations for a specific terminal emulater.

Parameters:
path The path to search for program "term"
term The terminal program we're searching for
DefaultPath:
A possible default path to check before searching the entire path
Returns:
Either a path to the specified term or null
    private String searchPath(final String pathfinal String termString defaultPath) {
        
        if (defaultPath != null) {
            File file = new File(defaultPathterm);
            if (file.exists()) {
                return file.getAbsolutePath();
            }
        }
//        System.err.println("RP.searchPath: Doing PATH search for " + term);
        final String[] patharray = new String[1];
        patharray[0] = null;
        
        Thread thread = new Thread(new Runnable() {
            public void run() {
                StringTokenizer st = new StringTokenizer(path":"); // NOI18N
                while (st.hasMoreTokens()) {
                    String dir = st.nextToken();
                    File file = new File(dirterm);
                    if (file.exists()) {
                        patharray[0] = file.getAbsolutePath();
                        break;
                    }
                }
            }
        });
        thread.start();
        try {
            thread.join(5000);
        } catch (InterruptedException ex) {
        }
        return patharray[0];
    }
    
    public String getTerminalPath() {
        return .get(getTerminalType().getName());
    }
    
    public String getTerminalOptions() {
        return .get(getTerminalType().getName());
    }
    
    public boolean shared() {
        return false;
    }
    
    
Returns an unique id (String) used to retrive this object from the pool of aux objects OLD: and for storing the object in xml form and parsing the xml code to restore the object.
    public String getId() {
        return ;
    }
    
    // Set if this profile is a clone of another profile (not set for copy)
    public void setCloneOf(RunProfile profile) {
        this. = profile;
    }
    
    public RunProfile getCloneOf() {
        return ;
    }
    
    // Default Profile ...
    public boolean isDefault() {
        return ;
    }
    
    public void setDefault(boolean b) {
         = b;
    }
    // Args ...
    public void setArgs(String argsFlat) {
        String oldArgsFlat = getArgsFlat();
        this. = argsFlat;
         = true;
         = false;
        if ( != null && !IpeUtils.sameString(oldArgsFlatargsFlat)) {
            .firePropertyChange(oldArgsFlatargsFlat);
        }
         = true;
    }
    
    public void setArgs(String[] argsArray) {
        String[] oldArgsArray = getArgsArray();
        this. = argsArray;
         = false;
         = true;
        if ( != null && !IpeUtils.sameStringArray(oldArgsArrayargsArray)) {
            .firePropertyChange(oldArgsArrayargsArray);
        }
         = true;
    }
    
    public void setArgsRaw(String argsFlat) {
        this. = argsFlat;
         = true;
         = false;
         = true;
    }
    
    public String getArgsFlat() {
        if (!) {
             = ""// NOI18N
            for (int i = 0; i < .i++) {
                 += IpeUtils.quoteIfNecessary([i]);
                if (i < (.-1)) {
                     += " "// NOI18N
                }
            }
             = true;
        }
        return ;
    }
    
    public String[] getArgsArray() {
        if (!) {
             = Utilities.parseParameters();
             = true;
        }
        return ;
    }
    
        /*
         * as array shifted one and executable as arg 0
         */
    public String[] getArgv(String ex) {
        String[] argsArrayShifted = new String[getArgsArray().length+1];
        argsArrayShifted[0] = ex;
        for (int i = 0; i < getArgsArray().lengthi++) {
            argsArrayShifted[i+1] = getArgsArray()[i];
        }
        return argsArrayShifted;
    }
    
        /*
         * Gets base directory. Base directory is always set and is always absolute.
         * Base directory is what run directory is relative to, if it is relative.
         */
    public String getBaseDir() {
        return ;
    }
    
        /*
         * Sets base directory. Base directory should  always be set and is always absolute.
         * Base directory is what run directory is relative to if it is relative.
         */
    public void setBaseDir(String baseDir) {
        assert baseDir != null && IpeUtils.isPathAbsolutebaseDir );
        this. = baseDir;
    }
    
        /*
         * Gets run directory.
         * Run Directory is either absolute or relative (to base directory).
         */
    public String getRunDir() {
        if ( == null) {
             = ""// NOI18N
        }
        return ;
    }
    
        /*
         * sets run directory.
         * Run Directory is either absolute or relative (to base directory).
         */
    public void setRunDir(String runDir) {
        if (runDir == null) {
            runDir = ""// NOI18N
        }
        if (this. != null && this..equals(runDir)) {
            return;
        }
        this. = runDir;
        if ( != null) {
            .firePropertyChange(nullthis);
        }
         = true;
    }
    
    
        /*
         * Gets absolute run directory.
         */
    public String getRunDirectory() {
        String runDirectory;
        String runDirectoryCanonicalPath;
        String runDir2 = getRunDir();
        if (runDir2.length() == 0) {
            runDir2 = "."// NOI18N
        }
        if (IpeUtils.isPathAbsolute(runDir2)) {
            runDirectory = runDir2;
        } else {
            runDirectory = getBaseDir() + "/" + runDir2// NOI18N
        }
        
        // convert to canonical path
        File runDirectoryFile = new File(runDirectory);
        if (!runDirectoryFile.exists() || !runDirectoryFile.isDirectory()) {
            return runDirectory// ??? FIXUP
        }
        try {
            runDirectoryCanonicalPath = runDirectoryFile.getCanonicalPath();
        } catch (IOException ioe) {
            runDirectoryCanonicalPath = runDirectory;
        }
        return runDirectoryCanonicalPath;
    }
    
        /*
         * Sets run directory.
         * If new run directory is relative, just set it.
         * If new run directory is absolute, convert to relative if already relative,
         * othervise just set it.
         */
    public void setRunDirectory(String newRunDir) {
        if (newRunDir == null || newRunDir.length() == 0) {
            newRunDir = "."// NOI18N
        }
        setRunDir(IpeUtils.toAbsoluteOrRelativePath(getBaseDir(), newRunDir));
    }
    
    // Should Build ...
    public void setBuildFirst(boolean buildFirst) {
        this. = buildFirst;
    }
    
    public boolean getBuildFirst() {
        return ;
    }
    
    // Environment
    public Env getEnvironment() {
        return ;
    }
    
    public void setEnvironment(Env env) {
        Env oldEnv = ;
        this. = env;
        if ( != null && !.equals(oldEnv)) {
            .firePropertyChange(oldEnv);
        }
    }
    
    public IntConfiguration getConsoleType() {
        return ;
    }
    
    public void setConsoleType(IntConfiguration consoleType) {
        this. = consoleType;
    }
    
    public static int getDefaultConsoleType() {
        return ;
    }
    
    public IntConfiguration getTerminalType() {
        if (.getName().equals(getString("TerminalType_None"))) { // NOI18N
            return null;
        } else {
            return ;
        }
    }
    
    public void setTerminalType(IntConfiguration terminalType) {
        this. = terminalType;
    }
    
    
    // Misc...
    
    
Saves this profile *and* all other profiles of the same parent to disk
    public void saveToDisk() {
            /*
            if (parent != null) {
                parent.saveToDisk();
            }
             */
    }
    
    
Adds property change listener.

Parameters:
l new listener.
        if ( != null) {
            .addPropertyChangeListener(l);
        }
    }
    
    
Removes property change listener.

Parameters:
l removed listener.
        if ( != null) {
            .removePropertyChangeListener(l);
        }
    }
    
    //
    // XML codec support
    // This stuff ends up in <projectdir>/nbproject/private/profiles.xml
    //
    
    public XMLDecoder getXMLDecoder() {
        return new RunProfileXMLCodec(this);
    }
    
    public XMLEncoder getXMLEncoder() {
        return new RunProfileXMLCodec(this);
    }
    
    
Responsible for saving the object in xml format. It should save the object in the following format using the id string from getId(): <id-string> <... <... </id-string>
    
        /* OLD
        public void writeElement(PrintWriter pw, int indent, Object object) {
            RunProfileHelper.writeProfileBlock(pw, indent, this);
        }
         */
    
    
Responsible for parsing the xml code created from above and for restoring the state of the object (but not the object itself). Refer to the Sax parser documentation for details.
    
        /* OLD
        public void startElement(String namespaceURI, String localName, String element, Attributes atts) {
            RunProfileHelper.startElement(this, element, atts);
        }
         */
    
        /* OLD
        public void endElement(String uri, String localName, String qName, String currentText) {
            RunProfileHelper.endElement(this, qName, currentText);
        }
         */
    
    // interface ProfileAuxObject
    public boolean hasChanged() {
        return ;
    }
    
    // interface ProfileAuxObject
    public void clearChanged() {
         = false;
    }
    
    public void assign(ConfigurationAuxObject profileAuxObject) {
        if (!(profileAuxObject instanceof RunProfile)) {
            // FIXUP: exception ????
            ..print("Profile - assign: Profile object type expected - got " + profileAuxObject); // NOI18N
            return;
        }
        RunProfile p = (RunProfile)profileAuxObject;
        setDefault(p.isDefault());
        setArgs(p.getArgsFlat());
        setBaseDir(p.getBaseDir());
        setRunDir(p.getRunDir());
        //setRawRunDirectory(p.getRawRunDirectory());
        setBuildFirst(p.getBuildFirst());
        getEnvironment().assign(p.getEnvironment());
        getConsoleType().assign(p.getConsoleType());
        getTerminalType().assign(p.getTerminalType());
    }
    
    
Clones the profile. All fields are cloned except for 'parent'.
    @Override
    public RunProfile clone(Configuration conf) {
        RunProfile p = new RunProfile(getBaseDir(), this.);
        //p.setParent(getParent());
        p.setCloneOf(this);
        p.setDefault(isDefault());
        p.setArgs(getArgsFlat());
        p.setRunDir(getRunDir());
        //p.setRawRunDirectory(getRawRunDirectory());
        p.setBuildFirst(getBuildFirst());
        p.setEnvironment(getEnvironment().clone());
        p.setConsoleType(getConsoleType().clone());
        p.setTerminalType(getTerminalType().clone());
        return p;
    }
    
    public Sheet getSheet(boolean isRemote) {
        return createSheet(isRemote);
    }
    
    public Sheet getSheet() {
        return createSheet(false);
    }
    
    private Sheet createSheet(boolean isRemote) {
        Sheet sheet = new Sheet();
        Sheet.Set set = new Sheet.Set();
        set.setName("General"); // NOI18N
        set.setDisplayName(getString("GeneralName"));
        set.setShortDescription(getString("GeneralTT"));
        set.put(new ArgumentsNodeProp());
        set.put(new RunDirectoryNodeProp());
        set.put(new EnvNodeProp());
        set.put(new BuildFirstNodeProp());
        ListenableIntNodeProp consoleTypeNP = new ListenableIntNodeProp(getConsoleType(), truenull,
                getString("ConsoleType_LBL"), getString("ConsoleType_HINT")); // NOI18N
        set.put(consoleTypeNP);
        final IntNodeProp terminalTypeNP = new IntNodeProp(getTerminalType(), truenull,
                getString("TerminalType_LBL"), getString("TerminalType_HINT")); // NOI18N
        set.put(terminalTypeNP);
        if (isRemote) {
            terminalTypeNP.setCanWrite(false);
            consoleTypeNP.setCanWrite(false);
        } else {
            consoleTypeNP.addPropertyChangeListener(new PropertyChangeListener() {
                public void propertyChange(PropertyChangeEvent evt) {
                    String value = (Stringevt.getNewValue();
                    updateTerminalTypeState(terminalTypeNPvalue);
                }
            });
            // because IntNodeProb has "setValue(String)" and "Integer getValue()"...
            updateTerminalTypeState(terminalTypeNP[(IntegerconsoleTypeNP.getValue()]);
        }
        sheet.put(set);
        return sheet;
    }
    private static void updateTerminalTypeState(IntNodeProp terminalTypeNPString value) {
        terminalTypeNP.setCanWrite[].equals(value) ||
                [].equals(value) && getDefaultConsoleType() == ) ;
    }
    
    private static String getString(String s) {
        return NbBundle.getMessage(RunProfile.classs);
    }
    
    private class ArgumentsNodeProp extends PropertySupport<String> {
        public ArgumentsNodeProp() {
            super("Arguments"String.classgetString("ArgumentsName"), getString("ArgumentsHint"), truetrue); // NOI18N
        }
        
        public String getValue() {
            return getArgsFlat();
        }
        
        public void setValue(String v) {
            setArgs(v);
        }
    }
    
    private class RunDirectoryNodeProp extends PropertySupport<String> {
        public RunDirectoryNodeProp() {
            super("Run Directory"String.classgetString("RunDirectoryName"), getString("RunDirectoryHint"), truetrue); // NOI18N
        }
        
        public String getValue() {
            return getRunDir();
        }
        
        public void setValue(String v) {
            String path = IpeUtils.toAbsoluteOrRelativePath(getBaseDir(), v);
            path = FilePathAdaptor.normalize(path);
            setRunDir(path);
        }
        
        @Override
        public PropertyEditor getPropertyEditor() {
            String seed;
            String runDir2 = getRunDir();
            if (runDir2.length() == 0) {
                runDir2 = "."// NOI18N
            }
            if (IpeUtils.isPathAbsolute(runDir2)) {
                seed = runDir2;
            } else {
                seed = getBaseDir() + . + runDir2;
            }
            return new DirEditor(seed);
        }
    }
    
    private class DirEditor extends PropertyEditorSupport implements ExPropertyEditor {
        private PropertyEnv propenv;
        private String seed;
        
        public DirEditor(String seed) {
            this. = seed;
        }
        
        @Override
        public void setAsText(String text) {
            setRunDir(text);
        }
        
        @Override
        public String getAsText() {
            return getRunDir();
        }
        
        @Override
        public Object getValue() {
            return getRunDir();
        }
        
        @Override
        public void setValue(Object v) {
            setRunDir((String)v);
        }
        
        @Override
        public boolean supportsCustomEditor() {
            return true;
        }
        
        @Override
        public java.awt.Component getCustomEditor() {
            return new DirectoryChooserPanel(this);
        }
        
        public void attachEnv(PropertyEnv propenv) {
            this. = propenv;
        }
    }
    
    private class BuildFirstNodeProp extends PropertySupport<Boolean> {
        public BuildFirstNodeProp() {
            super("Build First"Boolean.classgetString("BuildFirstName"), getString("BuildFirstHint"), truetrue); // NOI18N
        }
        
        public Boolean getValue() {
            return Boolean.valueOf(getBuildFirst());
        }
        
        public void setValue(Boolean v) {
            setBuildFirst((v).booleanValue());
        }
    }
    
    private class EnvNodeProp extends PropertySupport<Env> {
        public EnvNodeProp() {
            super("Environment"Env.classgetString("EnvironmentName"), getString("EnvironmentHint"), truetrue); // NOI18N
        }
        
        public Env getValue() {
            return getEnvironment();
        }
        
        public void setValue(Env v) {
            getEnvironment().assign(v);
        }
        
        @Override
        public PropertyEditor getPropertyEditor() {
            return new EnvEditor(getEnvironment().clone());
        }
        
        @Override
        public Object getValue(String attributeName) {
            if (attributeName.equals("canEditAsText")) { // NOI18N
                return .;
            }
            return super.getValue(attributeName);
        }
    }
    
    private static class EnvEditor extends PropertyEditorSupport implements ExPropertyEditor {
        private Env env;
        private PropertyEnv propenv;
        
        public EnvEditor(Env env) {
            this. = env;
        }
        
        @Override
        public void setAsText(String text) {
        }
        
        @Override
        public String getAsText() {
            return .toString();
        }
        
        @Override
        public java.awt.Component getCustomEditor() {
            return new EnvPanel(this);
        }
        
        @Override
        public boolean supportsCustomEditor() {
            return true;
        }
        
        public void attachEnv(PropertyEnv propenv) {
            this. = propenv;
        }
    }