Enable JButtons in java after JTextFields have been validated for numeric values greater than 0?

2.4k Views Asked by At

There are two buttons which are enabled only when valid data is present in all fields, that is, numeric values and no negative numbers.. How do you do that?

4

There are 4 best solutions below

2
On

I would consider using a DocumentListener that listens to the Documents held by the JTextFields. There are examples of this sort of thing on this site (I know, because I've written one or two).

For example,

import java.awt.Component;
import java.util.ArrayList;
import java.util.List;

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.JTextComponent;

public class DocumentListenerFun extends JPanel {
   private static final int FIELD_COUNT = 5;
   private JTextField[] fields = new JTextField[FIELD_COUNT];
   private JButton fooBtn = new JButton("Foo");
   private JButton barBtn = new JButton("Bar");
   private MyFieldListener myFieldListener = new MyFieldListener();

   public DocumentListenerFun() {
      fooBtn.setEnabled(false);
      barBtn.setEnabled(false);
      for (int i = 0; i < fields.length; i++) {
         fields[i] = new JTextField(10);
         add(fields[i]);
         myFieldListener.addTextComponent(fields[i]);
      }
      myFieldListener.addComponentsToEnable(fooBtn);
      myFieldListener.addComponentsToEnable(barBtn);
      add(fooBtn);
      add(barBtn);
   }

   private static void createAndShowGui() {
      DocumentListenerFun mainPanel = new DocumentListenerFun();

      JFrame frame = new JFrame("DocumentListenerFun");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class MyFieldListener {
   private List<JTextComponent> textComponents = new ArrayList<JTextComponent>();
   private List<Component> componentsToEnable = new ArrayList<Component>();
   private MyDocListener myDocListener = new MyDocListener(this);

   public void addTextComponent(JTextComponent textComponent) {
      textComponents.add(textComponent);
      textComponent.getDocument().addDocumentListener(myDocListener);
   }

   public void addComponentsToEnable(Component comp) {
      componentsToEnable.add(comp);
   }

   public void docsChanged() {
      boolean textVerified = true;
      for (JTextComponent textComp : textComponents) {
         String text = textComp.getText();
         textVerified &= verifyText(text);
      }

      for (Component comp : componentsToEnable) {
         comp.setEnabled(textVerified);
      }

   }

   private boolean verifyText(String text) {
      try {
         int value = Integer.parseInt(text.trim());
         if (value > 0) {
            return true;
         }
      } catch (NumberFormatException e) {
         return false;
      }
      return false;
   }
}

class MyDocListener implements DocumentListener {

   private MyFieldListener myFieldListener;

   public MyDocListener(MyFieldListener myFieldListener) {
      this.myFieldListener = myFieldListener;
   }

   @Override
   public void changedUpdate(DocumentEvent e) {
      myFieldListener.docsChanged();
   }

   @Override
   public void insertUpdate(DocumentEvent e) {
      myFieldListener.docsChanged();
   }

   @Override
   public void removeUpdate(DocumentEvent e) {
      myFieldListener.docsChanged();
   }

}
1
On
0
On

Alternatively, consider the shouldYieldFocus() method of InputVerifier, illustrated here and discussed here.

1
On

If you just don't want to allow negative value then you can use DocumentFilter.

/**
 * REF: http://www.coderanch.com/t/345628/GUI/java/DocumentFilter
 */
public class NumericFilter extends DocumentFilter {

    @Override
    public void insertString(DocumentFilter.FilterBypass fb, int offset,
            String text, AttributeSet attr) throws BadLocationException {
        fb.insertString(offset, text.replaceAll("\\D", ""), attr);
    }

    // no need to override remove(): inherited version allows all removals  
    @Override
    public void replace(DocumentFilter.FilterBypass fb, int offset, int length,
            String text, AttributeSet attr) throws BadLocationException {
        fb.replace(offset, length, text.replaceAll("\\D", ""), attr);
    }
}

Then to use

((AbstractDocument)(new JTextField).getDocument()).setDocumentFilter(new NumericFilter());