I have created a simple for-loop that changes the amount of JTextFields and JLabels based on the value of a JSpinner, as seen in the following code:
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;
}
}
The value of the Spinner is passed into the method, and the method is called using a change listener (where noQuestions is the value of the JSpinner):
noQuestions.addChangeListener(e -> {
ChangeQuestionAnswerFields((int) noQuestions.getValue());
frame.revalidate();
frame.repaint();
});
This method is first called in the code when the screen first appears, and works properly. However, whenever the value of the spinner changes the original labels and fields stay on the screen and more text fields simply appear, or disappear on top.
https://i.stack.imgur.com/6d5jL.png - JSpinner has a value of 2 https://i.stack.imgur.com/PztVd.png - JSpinner has a value of 3
Is there any way to fix this? Any help is much appreciated.
Thanks, Tom
Minimal Runnable Example:
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;
}
}