// 
//     Licensed to the Apache Software Foundation (ASF) under one
//     or more contributor license agreements.  See the NOTICE file
//     distributed with this work for additional information
//     regarding copyright ownership.  The ASF licenses this file
//     to you under the Apache License, Version 2.0 (the
//     "License"); you may not use this file except in compliance
//     with the License.  You may obtain a copy of the License at
// 
//       http://www.apache.org/licenses/LICENSE-2.0
// 
//     Unless required by applicable law or agreed to in writing,
//     software distributed under the License is distributed on an
//     "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
//     KIND, either express or implied.  See the License for the
//     specific language governing permissions and limitations
//     under the License.
//

= DevFaqDialogControlOKButton
:jbake-type: wiki
:jbake-tags: wiki, devfaq, needsreview
:jbake-status: published
:keywords: Apache NetBeans wiki DevFaqDialogControlOKButton
:description: Apache NetBeans wiki DevFaqDialogControlOKButton
:toc: left
:toc-title:
:syntax: true

=== How can I control when the OK button is enabled?

The link:http://bits.netbeans.org/dev/javadoc/org-openide-dialogs/index.html?overview-summary.html[NetBeans Dialogs API] makes it easy to create consistent dialogs that behave as users would expect.  But since you don't directly create the OK button, it may not be obvious how you can enable it or disable it.

You can enable the OK button by calling <pre>setValid(true)</pre> and disable it by calling <pre>setValid(false)</pre>

When using DialogDescriptors some additional steps need to be taken. Its OK button cannot be enabled/diabled after it has been displyed via a DialogDisplyer. The following is a sample code : 

[source,java]
----

1.  Create a new Action in one of your modules using the wizard in the
NetBeans IDE


[start=2]
.  Replace the code generated inside that ActionListener with this code below:

   public void actionPerformed(ActionEvent e) {
       MyForm form = new MyForm();

       DialogDescriptor desc = new DialogDescriptor(form,

         "Hello", true, DialogDescriptor.OK_CANCEL_OPTION,
          DialogDescriptor.OK_OPTION, null);

       desc.setValid(false);

       form.setDialogDescriptor(desc);

       DialogDisplayer.getDefault().notify(desc); // displays the dialog
   }


   static class MyForm extends JPanel implements DocumentListener {

       private JTextField field;
       private DialogDescriptor desc;

       MyForm() {
           super(new BorderLayout());
           field = new JTextField();
           add(new JLabel("Type Something Here"), BorderLayout.NORTH);
           add(field, BorderLayout.SOUTH);
       }

       void setDialogDescriptor(DialogDescriptor desc) {
           this.desc = desc;
           field.getDocument().addDocumentListener(this);
       }

       private void doEnablement() {
           if (field.getText().isEmpty()) {
               desc.setValid(false);
           } else {
               desc.setValid(true);
           }
       }

       @Override
       public void insertUpdate(DocumentEvent e) {
           doEnablement();
       }

       @Override
       public void removeUpdate(DocumentEvent e) {
           doEnablement();
       }

       @Override
       public void changedUpdate(DocumentEvent e) {
           doEnablement();
       }
   }


[start=3]
.  Run your application and invoke the new action you added
----

Here the OK button in the dialog is initially disabled, but becomes enabled when some characters are typed. Removing all characters will disable it again. 

One noteworthy point is that the following alternative fails to enable the OK button and hence the given solution is the appropriate one.

[source,java]
----

desc.setValid(false);
DialogDisplayer.getDefault().notify(desc);
desc.setValid(true); //OK button doesnot get enabled
----

=== Apache Migration Information

The content in this page was kindly donated by Oracle Corp. to the
Apache Software Foundation.

This page was exported from link:http://wiki.netbeans.org/DevFaqDialogControlOKButton[http://wiki.netbeans.org/DevFaqDialogControlOKButton] , 
that was last modified by NetBeans user Darrshan 
on 2010-06-15T05:06:37Z.


*NOTE:* This document was automatically converted to the AsciiDoc format on 2018-02-07, and needs to be reviewed.
