- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我创建了一个简单的 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/
我是一名优秀的程序员,十分优秀!