// 
//     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

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();
       }
   }

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.
