Your problem is that you're confusing the variable name with the JTextField's name field. Calling getName()
on the JTextField returns the latter, its name field, which as you're finding out is set by default to null. Several solutions present themselves:
- You could try to use reflection to get the object that the variable you're interested in refers to -- a bad, brittle and kludgy idea -- just don't do it.
- You could in fact set the name field to be the same as the variable name, by calling
setName(...)
on the JTextField after creating it -- another bad kludge
- Better would be to place all your JTextField objects into a 1 or 2 dimensional array or collection. By doing this, it would be easy to find out which row and column your field is in.
- Perhaps the best solution (hard to tell without knowing more requirements) would be to use a JTable, one with 10 rows and 10 columns.
Your question sounds like it may in fact be an XY Problem where you ask "how do I fix this code" when the real solution is to use a different approach entirely. Please do tell us more about your "problem space" -- what overall problem that you're trying to solve, since again I think that there likely is a better solution out there for you.
Another issue: you appear to be trying to use a KeyListener with JTextFields, something I also do not recommend as this can interfere with the text fields native key processing. Instead you're almost always better off using a DocumentListener or a DocumentFilter.
Another option is to set the Swing component method, putClientProperty(...)
, to have your JTextFields "know" which row and column they're in. An example of this which uses the above method plus it's getter equivalent, and which uses an ActionListener in the JTextField to get the data is as follows:
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
@SuppressWarnings("serial")
public class ManyFields extends JPanel {
private static final int ROWS = 10;
private static final int COLS = ROWS;
private static final int GAP = 2;
private static final int TF_COLS = 5;
public static final String ROW = "row";
public static final String COL = "col";
private JTextField[][] fieldGrid = new JTextField[ROWS][COLS];
public ManyFields() {
setLayout(new GridLayout(ROWS, COLS, GAP, GAP));
setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
TFieldListener tFieldListener = new TFieldListener();
for (int row = 0; row < fieldGrid.length; row++) {
for (int col = 0; col < fieldGrid[row].length; col++) {
JTextField tField = new JTextField(TF_COLS);
tField.putClientProperty(ROW, row);
tField.putClientProperty(COL, col);
tField.addActionListener(tFieldListener);
add(tField);
fieldGrid[row][col] = tField;
}
}
}
private class TFieldListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
JTextField field = (JTextField) e.getSource();
int row = (int) field.getClientProperty(ROW);
int col = (int) field.getClientProperty(COL);
// or another way to get row and column using the array:
int row2 = -1;
int col2 = -1;
for (int r = 0; r < fieldGrid.length; r++) {
for (int c = 0; c < fieldGrid[r].length; c++) {
if (field == fieldGrid[r][c]) {
row2 = r;
col2 = c;
}
}
}
// now here row2 and col2 are set
String text = field.getText();
String title = String.format("Text for Cell [%d, %d]", col, row);
String message = "text: " + text;
int messageType = JOptionPane.INFORMATION_MESSAGE;
JOptionPane.showMessageDialog(ManyFields.this, message, title, messageType);
field.transferFocus(); // move to next component
}
}
private static void createAndShowGui() {
ManyFields mainPanel = new ManyFields();
JFrame frame = new JFrame("Many Fields");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
But again, likely a JTable would offer a better solution, however it's hard to know exactly how to create this without more requirement information.