I have the following code
import javax.swing.*;
import java.awt.*;
import net.miginfocom.swing.MigLayout;
import Sorts.*;
import javax.swing.event.*;
import java.awt.event.*;
import java.awt.Color;
public class SortsGui
{
JFrame myMainWindow = new JFrame("Sorts");
JPanel sortPanel = new JPanel();
//first panel components
public int nextTextBox = 20;
JTextField[] allField = new JTextField [25];
//end first panel
public void runGUI()
{
myMainWindow.setBounds(10, 10, 800, 800);
myMainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myMainWindow.setLayout(new GridLayout(1,1));
createSortTestPanel();
myMainWindow.getContentPane().add(sortPanel);
myMainWindow.setVisible(true);
}
public void createSortTestPanel()
{
MigLayout layout = new MigLayout("" , "[grow]");
sortPanel.setLayout(layout);
refreshScreen();
}
public void refreshScreen()
{
sortPanel.removeAll();
for(int i = 0; i<nextTextBox;i++)
{
int fix = i+1;
allField[i] = new JTextField("");
sortPanel.add(allField[i],"growx");
allField[i].addKeyListener(new KeyListener ()
{
public void keyPressed(KeyEvent e)
{
}
public void keyReleased(KeyEvent e)
{
}
public void keyTyped(KeyEvent e)
{
char c = e.getKeyChar();
if(Character.isDigit(c))
{
}
else
{
e.consume();
}
try
{
int parseTest = Integer.parseInt(allField[i].getText());
}
catch(Exception exc)
{
allField[i].setBackground(Color.RED);
}
}
});
}
}
public static void main(String[] args)
{
SortsGui sG = new SortsGui();
sG.runGUI();
}
}
My aim here is to create an array of JTextFields which have a keylistener on. This keylistener should prevent anything other than numbers being entered in the JTextField. It should also change the color of the JTextField's background if the number entered is not an int. For example 2147483647554. However when I compile this I get the error
So how do I make this so that it is either final or effectively final on all the JTextFields?
The short answer to this is, don't use
KeyListener
, it won't capture the use cases of the user pasting text into the field or if the field is updated programmaticallyInstead you want to use a
DocumentFilter
, for exampleSee Implementing a Document Filter for more details and DocumentFilter Examples for more examples
You can do post validation using a
InputVerifier
, but that might not meet your needs.This creates a problem. The
DocumentFilter
, shouldn't care about the field it's applied to, but since, it's doing the validation, it will know when something has gone wrong, so we need some way for the filter to provide notification when the validation fails...First, we need some callback which tells us when validation has failed or passed...
Then we need to update the filter to raise those notifications based on it's rules...
Then we need to define our implementation of the
ValidationListener
to perform the actions we need...Here, the listener maintains a reference to the field which we want to control
Then we bind it altogether...
This is all a bit crude, but it gets the basic idea across.
Some improvements might include passing the reference of the
DocumentFilter
back via the methods of theValidationListener
, you could then use this to lookup the field which triggered the event and update it, reducing the number of handlers you might need to create, for example.For example
Updated ValidationListener
Updated IntFilter
Example implementation...