gpt4 book ai didi

java - 在 For 循环中使用 Java Swing 时出现问题

转载 作者:行者123 更新时间:2023-12-02 04:30:44 24 4
gpt4 key购买 nike

我创建了一个简单的 for 循环,它根据 JSpinner 的值更改 JTextFields 和 JLabels 的数量,如以下代码所示:

        public static ArrayList<ArrayList<JTextField>> ChangeQuestionAnswerFields(int numberOfQuestions){
ArrayList<ArrayList<JTextField>> txtFieldArray = new ArrayList<ArrayList<JTextField>>();

JPanel scrollPanel = new JPanel(new GridBagLayout());
//JScrollPane scrollPane = new JScrollPane(scrollPanel);
frame.add(scrollPanel, BorderLayout.CENTER);
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;


for(int i = 0; i != numberOfQuestions; i++){
JTextField tempQuestion = new JTextField(10);
JTextField tempAnswer = new JTextField(10);
JLabel tempQuestionHeader = new JLabel("Question " + (i + 1)+ " ");
JLabel tempQuestionLbl = new JLabel("Question: ");
JLabel tempAnswerLbl = new JLabel("Answer: ");

ArrayList<JTextField> tempArrayList = new ArrayList<>();
tempArrayList.add(tempQuestion);
tempArrayList.add(tempAnswer);
txtFieldArray.add(tempArrayList);

c.gridy++;
c.gridx = 0;
scrollPanel.add(tempQuestionHeader, c);

c.gridy++;
c.gridx = 0;
scrollPanel.add(tempQuestionLbl, c);

c.gridx = 1;
c.gridwidth = 3;
scrollPanel.add(tempQuestion, c);

c.gridy++;
c.gridx = 0;
scrollPanel.add(tempAnswerLbl, c);

c.gridx = 1;
c.gridwidth = 3;
scrollPanel.add(tempAnswer, c);
}
return txtFieldArray;
}
}

Spinner 的值被传递到方法中,并使用更改监听器调用该方法(其中 noQuestions 是 JSpinner 的值):

noQuestions.addChangeListener(e -> {
ChangeQuestionAnswerFields((int) noQuestions.getValue());
frame.revalidate();
frame.repaint();
});

该方法在屏幕第一次出现时在代码中首先被调用,并且工作正常。但是,每当微调器的值发生更改时,原始标签和字段都会保留在屏幕上,并且更多文本字段会出现或消失在顶部。

/image/6d5jL.png - JSpinner 的值为 2 /image/PztVd.png - JSpinner 的值为 3

有什么办法可以解决这个问题吗?非常感谢任何帮助。

谢谢,汤姆

最小可运行示例:

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;

public class MainGUI {
static JFrame frame = new JFrame("Math Reviser");

public static void main(String[] args) {


frame.setSize(400, 600);
frame.setVisible(true);

createScreen();
frame.revalidate();
frame.repaint();

public static void createScreen(){
frame.getContentPane().removeAll();

JSpinner noQuestions = new JSpinner(new SpinnerNumberModel(1, 1, 10, 1));
frame.add(noQuestions, BorderLayout.NORTH);
);
changeQuestionAnswerFields(1);

frame.revalidate();
frame.repaint();

noQuestions.addChangeListener(e -> {
changeQuestionAnswerFields((int) noQuestions.getValue());
frame.revalidate();
frame.repaint();
});

}

public static ArrayList<ArrayList<JTextField>> changeQuestionAnswerFields(int numberOfQuestions){
ArrayList<ArrayList<JTextField>> txtFieldArray = new ArrayList<ArrayList<JTextField>>();

JPanel scrollPanel = new JPanel(new GridBagLayout());
frame.add(scrollPanel, BorderLayout.CENTER);
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;


for(int i = 0; i != numberOfQuestions; i++){
JTextField tempQuestion = new JTextField(10);
JTextField tempAnswer = new JTextField(10);
JLabel tempQuestionHeader = new JLabel("Question " + (i + 1)+ " ");
JLabel tempQuestionLbl = new JLabel("Question: ");
JLabel tempAnswerLbl = new JLabel("Answer: ");

ArrayList<JTextField> tempArrayList = new ArrayList<>();
tempArrayList.add(tempQuestion);
tempArrayList.add(tempAnswer);
txtFieldArray.add(tempArrayList);

c.gridy++;
c.gridx = 0;
scrollPanel.add(tempQuestionHeader, c);

c.gridy++;
c.gridx = 0;
scrollPanel.add(tempQuestionLbl, c);

c.gridx = 1;
c.gridwidth = 3;
scrollPanel.add(tempQuestion, c);

c.gridy++;
c.gridx = 0;
scrollPanel.add(tempAnswerLbl, c);

c.gridx = 1;
c.gridwidth = 3;
scrollPanel.add(tempAnswer, c);
}
return txtFieldArray;
}
}

最佳答案

使用静态变量和方法表明应用程序设计不当。不需要静态变量或方法。我建议您阅读 Swing 教程中关于 How to Use Labels 的部分。 。 LabelDemo.java 代码将向您展示如何创建包含所有组件的面板。然后该面板将被添加到框架中。该面板还将包含程序所需的所有实例变量。

不仅该示例将向您展示如何在 EDT 上创建 GUI 组件,这是您应该始终执行的操作,以防止随机错误,因为 Swing 被设计为单线程。

但是,现有代码的主要问题是您继续创建新面板并将其添加到框架的内容 Pane 中。尝试将微调器更改为 2,然后调整框架大小。然后尝试将微调器更改为 3 并调整框架大小。调整大小后,将显示第一个面板。这是因为 Swing 将绘制最先添加的最后一个组件,因此添加的第一个面板将绘制在您创建的最后一个面板的顶部。

您可以在添加新面板之前删除旧面板,从而在现有代码中更改此设置:

static JFrame frame = new JFrame("Math Reviser");
static JPanel scrollPanel = new JPanel();
...
frame.remove(scrollPanel);
//JPanel scrollPanel = new JPanel(new GridBagLayout());
scrollPanel = new JPanel(new GridBagLayout());

但是,我不推荐这种方法。正如我最初建议的那样,您需要重新设计整个类(class)。当您进行重新设计时,我将在面板上使用 BorderLayout,然后您可以将微调器添加到 PAGE_START,然后将 JScrollPane 添加到面板的中心。

然后,当您想要创建新面板时,可以使用以下代码将面板添加到滚动 Pane :

scrollPane.setViewportView( scrollPanel );

滚动 Pane 会自行刷新,您无需担心 revalidate() 或 repaint() 或其他任何事情。

关于java - 在 For 循环中使用 Java Swing 时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31496505/

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