I have an application with multiple text fields I want the text fields to take only one Letter and consume the other. I am trying to do it through ActionListener
and KeyAdapter
and by making only one listener for all text fields.
The only problem is when it takes input in one text field it does not take input in others. So please what's wrong with my code?
My code so far:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class OnlyAlphabet extends JFrame
{
int checker=0;
private final KeyAdapter listener = new KeyAdapter() {
public void keyTyped(KeyEvent e) {
char c = e.getKeyChar();
if(c==KeyEvent.VK_BACK_SPACE )
{ checker =0 ; return; }
if(checker!=0)
{ e.consume();return;}
if(!(Character.isAlphabetic(c) || (c==KeyEvent.VK_BACK_SPACE) || c==KeyEvent.VK_DELETE))
{ e.consume(); return; }
if(Character.isAlphabetic(c) && checker==0)
{ checker =1; return; }
}
};
public void initComponent() {
setLayout(new FlowLayout());
JLabel lbl = new JLabel("Enter a Letter: ");
JTextField textField = new JTextField(15);
JTextField textField2 = new JTextField(15);
add(lbl);
add(textField);
add(textField2);
textField.addKeyListener(listener);
textField2.addKeyListener(listener);
setSize(300,300);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[]args){
new OnlyAlphabet().initComponent();
}
}
Please check it out and I want to add the same Listener to multiple Textfields the code only contains 2 now but there will be more like 25-30
CodePudding user response:
Use a DocumentListener
when you want to be notified when text changes in the text filed. Use a DocumentFilter
when you want to filter what gets changed in the underlying Document
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setBorder(new EmptyBorder(32, 32, 32, 32));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
JTextField[] fields = new JTextField[2];
for (int index = 0; index < fields.length; index ) {
fields[index] = createTextField();
add(fields[index], gbc);
}
}
protected JTextField createTextField() {
JTextField textField = new JTextField(4);
((AbstractDocument) textField.getDocument()).setDocumentFilter(new LimitDocumentFilter(1));
return textField;
}
}
public class LimitDocumentFilter extends DocumentFilter {
private int maxCharacters;
public LimitDocumentFilter(int maxChars) {
maxCharacters = maxChars;
}
protected String filter(FilterBypass fb, String str) {
StringBuilder buffer = new StringBuilder(str);
for (int i = buffer.length() - 1; i >= 0; i--) {
char ch = buffer.charAt(i);
if (!Character.isAlphabetic(ch)) {
buffer.deleteCharAt(i);
}
}
int limit = maxCharacters - fb.getDocument().getLength();
if (limit == 0) {
return "";
}
return buffer.substring(0, Math.min(limit, buffer.length()));
}
public void insertString(FilterBypass fb, int offs, String str, AttributeSet a) throws BadLocationException {
String filtered = filter(fb, str);
if (!filtered.isEmpty()) {
super.insertString(fb, offs, filtered, a);
}
}
public void replace(FilterBypass fb, int offs, int length, String str, AttributeSet a) throws BadLocationException {
String filtered = filter(fb, str);
if (!filtered.isEmpty()) {
super.replace(fb, offs, length, filtered, a);
}
}
}
}