gpt4 book ai didi

java - 从 JFrame 中动态创建的变量获取数据

转载 作者:行者123 更新时间:2023-11-30 05:36:00 25 4
gpt4 key购买 nike

我有一个包含 Jspinner 的 Jframe。当 JSpinner 增加时,我的面板 headerPanel 中会创建一个新的 JTextField。该脚本创建文本框,并将整数附加到其变量名称(tFrame0、tFrame1 等)。

原始代码和所有旧编辑已移至 This粘贴宾。

链接pastebin以防万一它将来会对任何人有所帮助,并且不会弄乱当前相关的代码。

TreffnonX 的帮助下解决了这个问题!感谢您在评论和聊天中对我非常耐心。

这是工作代码,以防以后有人偶然发现此类问题。

全局变量

private JPanel headerPanel;
private JSpinner spinner;

public List<JTextField> findTextFields() {
List<JTextField> fields = new LinkedList<>();

Component[] children = headerPanel.getComponents();
for (Component child : children) {
if (child instanceof JTextField) {
JTextField childField = (JTextField) child;

// check, if the name is prefixed correctly.
String name = childField.getName();
if (name.startsWith(nameTField)) {
fields.add(childField);
}
}
}

return fields;
}

JSpinner

spinner = new JSpinner();
spinner.setModel(new SpinnerNumberModel(1, 1, 100, 1));
spinner.addContainerListener(new ContainerAdapter() {
@Override
public void componentAdded(ContainerEvent arg0) {
adaptBoxes();
}
});
spinner.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent arg0) {
int spinnerValue = (Integer) spinner.getValue();
if (spinnerValue == headerPanel.getComponentCount()) {
System.out.println("Error, spinner shouldn't change to same alue");
}
adaptBoxes();
frame.revalidate();
frame.repaint();
}
});
adaptBoxes();

adaptBoxes();方法

public void adaptBoxes() {
// Find value of spinner.
int spinnerValue = (Integer) spinner.getValue();

List<JTextField> textFields = findTextFields();
int numTextFields = textFields.size();

if (numTextFields > spinnerValue) {
// if we have too many fields.
for (JTextField textField : textFields) {
String name = textField.getName();
Matcher matcher = POSTFIX_PATTERN.matcher(name);
if (matcher.matches()) {
String strPostfix = matcher.group(1);
int postFixNumeric = Integer.parseInt(strPostfix);

System.out.println("for postFix = " + postFixNumeric + ": " + textField.getText());
if (postFixNumeric >= spinnerValue) {
System.out.println("PFN: " + postFixNumeric);
System.out.println("FTF: " + numTextFields);
headerPanel.remove(textField);
}
}
}
} else {
while (numTextFields < spinnerValue) {
// if we have too few fields.
int hp = headerPanel.getComponentCount();

JTextField tField = new JTextField();
tField.setName(nameTField + hp);

tField.getDocument().addDocumentListener(new TextFieldDocumentListener());

headerPanel.add(tField);

textFields = findTextFields();
numTextFields = textFields.size();
}
}
}

JTextField 文档监听器

/**
* Inner class
*/
private final class TextFieldDocumentListener implements DocumentListener {
@Override
public void changedUpdate(DocumentEvent e) {
warn();
}

@Override
public void removeUpdate(DocumentEvent e) {
warn();
}

@Override
public void insertUpdate(DocumentEvent e) {
warn();
}

/**
* Actual sysout to inform the user...
*/
public void warn() {
List<JTextField> textFields = findTextFields();
for (JTextField textField : textFields) {
String name = textField.getName();

Matcher matcher = POSTFIX_PATTERN.matcher(name);
System.out.println(name);

if (matcher.matches()) {
String strPostfix = matcher.group(1);
int postfixNumeric = Integer.parseInt(strPostfix);

System.out.println("for postfix = " + postfixNumeric + ": " + textField.getText());
} else {
System.out.println("matcher error: " + matcher);
}
}
}
}

最佳答案

你不能“将我的 for 循环 int i 附加到变量名”,除非你想使用反射( https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/package-summary.html )。反射将允许您搜索 java-Object 的字段,并根据它们的名称(如果公开)访问它们。

幸运的是,这并不是您真正需要的。您实际上正在寻找一种方法来通过类型和名称来识别 J?Panel 的子组件(Component),然后推断出您之前附加的索引。我的建议是执行以下操作:

// This pattern can be anywhere in the Class-file:
public static final Pattern POSTFIX_PATTERN = Pattern.compile("tFrame(\\d+)");

// This should be in your exposed GUI class (supposedly the Panel), but can be anywhere it can access headerPanel.
public List<JTextField> findTextFields() {
List<JTextField> fields = new LinkedList<>();

Component[] children = headerPanel.getComponents();
// this is your 'search-loop':
for (Component child : children) {
if (child instanceof JTextField) {
JTextField childField = (JTextField) child;
String name = childField.getName();
if (name.startsWith("tFrame")) {
fields.add(childField);
}
}
}

return fields;
}

(这也可以像使用Stream一样完成,但上面的代码更简单)。

上面的代码“查找”您现有的组件,您可以从那里开始工作,例如根据它们的名称对它们进行排序,然后进行打印。

为什么您只收到部分文本字段似乎对修改使用react的问题是因为您(可能)没有将相同的 inputData 数组传递给不同的 DocumentListener 由您创建。如果您设置断点并检查,我敢打赌输入数据数组具有不同的哈希值。也就是说,我无法 100% 推断出这一点,因为周围的代码不完整。

我建议更改:

if (tField.getText() != null) {
Object[] currentData = new Object[getFieldNum + 1];
currentData[getFieldNum] = tField.getText();

inputData[getFieldNum] = tField.getText();

for (int i = 0; i < inputData.length; i++) {
if (inputData[i] != null) {
System.out.println("for i = " + i + ": " + inputData[i]);
}

}
}

for (JTextField textField : findTextFields()) {
String name = textField.getName();
Matcher matcher = POSTFIX_PATTERN.matcher(name);
if (matcher.matches()) {
String strPostfix = matcher.group(1);
int postfixNumeric = Integer.parseInt(strPostfix);

System.out.println("for postfix = " + postfixNumeric + ": " + textField.getText());
}
}

这样,您就可以在用户实际做出您想要使用react的更改时获取组件。

还有一个旁注:一旦减少或增加 JSpinner 上的数字,您是否真的想要替换所有现有的文本字段及其当前状态?

也许考虑删除 postfixNumeric >= getTextFields().size() 的元素,或者增加元素数量而不删除那些小于 JSpinner 上先前数量的元素。这可以用你得到的循环来完成。

编辑

问题的根源在于使用了大量实例字段而不是局部变量。由于代码仅部分发布,因此仅从问题中很难确定这一点。

关于java - 从 JFrame 中动态创建的变量获取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56608760/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com