user4099884
user4099884

Reputation:

Is this Correct way to add FocusListener to JTextFields in java?

I got hundreds of JTextFields in my application in Java and I want to add FocusListener on all of these to set Horizontal Alignment of text and add FocusListener on each of these textfields. So, I made this method and it's working great. But I just wanted to know if this correct way or there is something wrong in it or I am going against some kind of rule of OOPs?

Here is the code

public void CreateFocusListenerForFields(JTextField txt)
{
    txt.setHorizontalAlignment(JTextField.RIGHT);
    txt.addFocusListener(new FocusListener() 
    {
        @Override
        public void focusGained(FocusEvent e) {
        }

        @Override
        public void focusLost(FocusEvent e) {
            if(!NumberUtils.isNumber(txt.getText()))
            {
                txt.setBackground(new Color(254,157,157));
                txt.requestFocus();
            }
            else
            {
                txt.setBackground(Color.white);
            }
        }
    });
}

And apply this method on my textfields

CreateFocusListenerForFields(MyTextField);

Now when I run code, it works great just wanted to know if this correct or not and if not then what is the other way out when you have to set alignment and focuslistener on hundreds of fields? Thanks for your kind advice.

Upvotes: 1

Views: 6503

Answers (2)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285430

Again, my bias is to use an InputVerifier instead of a FocusListener, if only because the InputVerifier is a higher level construct, and it always seems safer to me to use these in place of lower level (closer to the metal) constructs where applicable.

An example of both:

import java.awt.Color;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import javax.swing.*;
import javax.swing.text.JTextComponent;

public class TestFieldVerification {
   public static final Color ERROR_COLOR = new Color(254,157,157);
   private static final int COLS = 8;
   private JPanel mainPanel = new JPanel();
   private JTextField verifiedField = new JTextField(COLS);
   private JTextField focusCheckedField = new JTextField(COLS);
   private Color defaultBackground = null;

   public TestFieldVerification() {
      verifiedField.setInputVerifier(new MyVerfier(this));
      focusCheckedField.addFocusListener(new MyFocusCheck(this));

      mainPanel.add(new JLabel("With InputVerfier:"));
      mainPanel.add(verifiedField);
      mainPanel.add(new JLabel("With FocusListener:"));
      mainPanel.add(focusCheckedField);
   }

   public boolean verifyText(String text) {
      try {
         Integer.parseInt(text);
         return true;
      } catch (NumberFormatException nfe) {
         return false;
      }
   }

   public void setFieldBackground(JComponent component, boolean verified) {
      if (defaultBackground == null) {
         defaultBackground = component.getBackground();
      }
      Color bg = verified ? defaultBackground : ERROR_COLOR;
      component.setBackground(bg);
   }

   public JComponent getMainPanel() {
      return mainPanel;
   }

   private static void createAndShowGui() {
      JFrame frame = new JFrame("MyVerifier");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(new TestFieldVerification().getMainPanel());
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

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

class MyVerfier extends InputVerifier {
   private TestFieldVerification gui;

   public MyVerfier(TestFieldVerification gui) {
      this.gui = gui;
   }

   @Override
   public boolean shouldYieldFocus(JComponent input) {
      gui.setFieldBackground(input, super.shouldYieldFocus(input));
      return super.shouldYieldFocus(input);
   }

   @Override
   public boolean verify(JComponent input) {
      String text = ((JTextComponent) input).getText();
      return gui.verifyText(text);
   }

}

class MyFocusCheck extends FocusAdapter {
   private TestFieldVerification gui;

   public MyFocusCheck(TestFieldVerification gui) {
      this.gui = gui;
   }

   @Override
   public void focusLost(FocusEvent e) {
      JTextComponent textComp = (JTextComponent) e.getSource();
      String text = textComp.getText();
      boolean verified = gui.verifyText(text);
      gui.setFieldBackground(textComp, verified);
      if (!verified) {
         textComp.requestFocusInWindow();
      }
   }
}

Upvotes: 2

BarrySW19
BarrySW19

Reputation: 3819

I would probably create a factory class which I then used to create all my text fields - I think this is a bit more "doing-it-right OOP", e.g.:

public class MyTextFieldFactory {
    private static final FocusListener defaultFocusListener = new FocusListener() {
        @Override
        public void focusGained(FocusEvent e) {

        }

        @Override
        public void focusLost(FocusEvent e) {
            // Your code ...
        }
    };

    public static JTextField createDefaultTextField() {
        JTextField textField = new JTextField();
        textField.setHorizontalAlignment(JTextField.RIGHT);
        textField.addFocusListener(defaultFocusListener);
        return textField;
    }
}

Then create all my text fields with:

JTextField myNewTextField = MyTextFieldFactory.createDefaultTextField();

This also has the advantage that you only create one instance of the focus listener rather than a new one for every text field.

Upvotes: 1

Related Questions