[英]Java Swing, 100 TextFields have similar task, So I want to write the one function to do so
I am working on a small project (with NetBeans' Java GUI Builder) in which I have 100 TextFields which does exact same thing on different data . 我正在做一个小项目(使用NetBeans的Java GUI Builder),其中有100个TextField,它们对不同的数据执行完全相同的操作 。 They are arranged in 10 rows and 10 columns , there (Variable) names are like: 它们排列成10行 10列 ,(变量)名称如下:
txt11, txt12, ... txt110
txt21, txt22, ... txt210
. . ... .
txt101, txt102, ... txt1010
so, that there names can easily generated by the row and column number as well as I can easily extract the row and the column of a TextField to which it belongs (But I can not). 因此,可以通过行和列号轻松生成名称,也可以轻松提取其所属的TextField的行和列(但我不能)。
Since they perform similar task I can write a single method which takes row and col as arguments and get executed whenever user writes something in any of the TextField. 由于它们执行相似的任务,因此我可以编写一个将row和col作为参数的方法 ,并在用户在任何TextField中写入内容时执行。 In order to accomplish the task I have to find out the row and the column they belong. 为了完成任务,我必须找出它们所属的行和列。
I tried to use following code inside the event listener ( I have added same event listener for all JTextField ): 我试图在事件监听器中使用以下代码(我为所有JTextField添加了相同的事件监听器):
private void TextFieldAnswerTyped(java.awt.event.KeyEvent evt) {
String name = ((JTextField)evt.getSource()).getName();
int row,col;
if(name.endsWith("10"))
{
col=10;
name=name.substring(0, name.length()-2);
}
else
{
col=Integer.parseInt(name.substring(name.length()-1,name.length()));
name=name.substring(0, name.length()-1);
}
if(name.endsWith("10"))
row=10;
else
row=Integer.parseInt(name.substring(name.length()-1,name.length()));
checkForCell(row, col); //Performs the task
}
Everytime the event occures it gives me null
as the name
. 每当事件发生时,它的name
为null
。 Am I doing any mistake here or Is there any good alternative. 我在这里做任何错误还是有什么好的选择?
Your problem is that you're confusing the variable name with the JTextField's name field. 您的问题是您将变量名称与JTextField的名称字段混淆了。 Calling getName()
on the JTextField returns the latter, its name field, which as you're finding out is set by default to null. 在JTextField上调用getName()
返回后者的名称字段,正如您所发现的那样,默认情况下将其设置为null。 Several solutions present themselves: 有几种解决方案:
setName(...)
on the JTextField after creating it -- another bad kludge 实际上,您可以通过在创建JTextField之后在JTextField上调用setName(...)
来将name字段设置为与变量名称相同的方法-另一个糟糕的做法 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. 您的问题听起来似乎实际上是一个XY问题 ,当真正的解决方案是完全使用另一种方法时,您会问“我如何修复此代码”。 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. 另一个问题:您似乎正在尝试将KeyListener与JTextFields一起使用,我也不建议这样做,因为这会干扰文本字段的本机键处理。 Instead you're almost always better off using a DocumentListener or a DocumentFilter. 相反,使用DocumentListener或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: 另一个选择是将Swing组件方法putClientProperty(...)
为让JTextFields“知道”它们所在的行和列。使用上述方法加上与getter等效的方法的示例,并且使用JTextField中用于获取数据的ActionListener如下:
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. 但是同样,JTable可能会提供更好的解决方案,但是很难在没有更多需求信息的情况下确切地知道如何创建它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.