Reputation:
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
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
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