/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 1997-2009 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-2009 Sun * Microsystems, Inc. All Rights Reserved. * Portions Copyright 2009 Alexander Coles (Ikonoklastik Productions). * * 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.nbgit.ui.wizards; import java.io.File; import java.util.Set; import java.util.HashSet; import java.util.Iterator; import java.awt.Component; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.SwingUtilities; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import org.openide.WizardDescriptor; import org.openide.util.HelpCtx; import org.eclipse.jgit.transport.URIish; public class CloneDestinationDirectoryWizardPanel implements WizardDescriptor.Panel, DocumentListener { /** * The visual component that displays this panel. If you need to access the * component from this class, just use getComponent(). */ private CloneDestinationDirectoryPanel component; private boolean valid; private String errorMessage; // Get the visual component for the panel. In this template, the component // is kept separate. This can be more efficient: if the wizard is created // but never displayed, or not all panels are displayed, it is better to // create only those which really need to be visible. public Component getComponent() { if (component == null) { component = new CloneDestinationDirectoryPanel(); component.directoryField.getDocument().addDocumentListener(this); component.nameField.getDocument().addDocumentListener(this); valid(); } return component; } public HelpCtx getHelp() { return new HelpCtx(CloneDestinationDirectoryWizardPanel.class); } //public boolean isValid() { // If it is always OK to press Next or Finish, then: //return true; // If it depends on some condition (form filled out...), then: // return someCondition(); // and when this condition changes (last form field filled in...) then: // fireChangeEvent(); // and uncomment the complicated stuff below. //} public void insertUpdate(DocumentEvent e) { textChanged(e); } public void removeUpdate(DocumentEvent e) { textChanged(e); } public void changedUpdate(DocumentEvent e) { textChanged(e); } private void textChanged(final DocumentEvent e) { // repost later to AWT otherwise it can deadlock because // the document is locked while firing event and we try // synchronously access its content Runnable awt = new Runnable() { public void run() { if (e.getDocument() == component.nameField.getDocument () || e.getDocument() == component.directoryField.getDocument()) { if (component.isInputValid()) { valid(component.getMessage()); } else { invalid(component.getMessage()); } } } }; SwingUtilities.invokeLater(awt); } private final Set<ChangeListener> listeners = new HashSet<ChangeListener>(1); // or can use ChangeSupport in NB 6.0 public final void addChangeListener(ChangeListener l) { synchronized (listeners) { listeners.add(l); } } public final void removeChangeListener(ChangeListener l) { synchronized (listeners) { listeners.remove(l); } } protected final void fireChangeEvent() { Iterator<ChangeListener> it; synchronized (listeners) { it = new HashSet<ChangeListener>(listeners).iterator(); } ChangeEvent ev = new ChangeEvent(this); while (it.hasNext()) { it.next().stateChanged(ev); } } protected final void valid() { setValid(true, null); } protected final void valid(String extErrorMessage) { setValid(true, extErrorMessage); } protected final void invalid(String message) { setValid(false, message); } public final boolean isValid() { return valid; } public final String getErrorMessage() { return errorMessage; } private void setValid(boolean valid, String errorMessage) { boolean fire = this.valid != valid; fire |= errorMessage != null && (errorMessage.equals(this.errorMessage) == false); this.valid = valid; this.errorMessage = errorMessage; if (fire) { fireChangeEvent(); } } // You can use a settings object to keep track of state. Normally the // settings object will be the WizardDescriptor, so you can use // WizardDescriptor.getProperty & putProperty to store information entered // by the user. public void readSettings(Object settings) { if (settings instanceof WizardDescriptor) { URIish repository = (URIish) ((WizardDescriptor) settings).getProperty("repository"); // NOI18N component.nameField.setText(new File(repository.getPath()).getName()); } } public void storeSettings(Object settings) { if (settings instanceof WizardDescriptor) { String directory = ((CloneDestinationDirectoryPanel) component).getDirectory(); String cloneName = ((CloneDestinationDirectoryPanel) component).getCloneName(); ((WizardDescriptor) settings).putProperty("directory", new File(directory)); //NOI18N ((WizardDescriptor) settings).putProperty("cloneName", cloneName); //NOI18N } } }