Floris Bosteels Floris Bosteels - 7 months ago 7
Java Question

Java duplicates(?) answers

So I have to make A GUI for our class softwaredesign and we're making a game for kids to practice tables of multiplication. So far it works fine when you perform a test or practice once, however when you go for a second run, it goes wrong. Normally you just have to answer 10 questions and this works fine the first time but the second time every click counts for 2 answers (I know it sounds weird) and the third time a click counts for 3 answers and so on. So only the first time you actually answer 10 questions.
So I wondered maybe it has to do with panels not properly being deleted and so registering multiple times when you make a new panel? But I'm not sure about it because I've tried a lot of ways to fix this so far.

import java.awt.*;
import javax.swing.*;

/**
* Aanmaken van het frame en laten switchen tussen verschillende panels afhankelijk van de keuze.
*/
public class GUI extends JFrame
{
JPanel currentPanel;
public static int keuze = -1;
public static int moeilijkheidsgraad = 0;
public static String TestOfOefenen;
static String[] vragen = new String[121];
static int[] antwoorden = new int[121];

/**
* Main method voor aanmaken frame
*/
public static void main(String[] args)
{
GUI menu = new GUI();
menu.setSize(800,600);
menu.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
menu.setVisible(true);
menu.setTitle("Rekenspel");

//vullen van vragen en antwoorden
/** 0-10: tafels van 0
* 11-21: tafels van 1
* 22-32: tafels van 2
* 33-43: tafels van 3
* 44-54: tafels van 4
* 55-65: tafels van 5
* 66-76: tafels van 6
* 77-87: tafels van 7
* 88-98: tafels van 8
* 99-110: tafels van 9
* 111-121: tafels van 10
**/

int teller=0;
for(int i=0; i<11; i++){
for(int j=0; j<11; j++){
int temp = i*10;
temp = temp+j;
//System.out.println(temp);

vragen[teller] = i +" x " + j + " = ...";
//System.out.println(vragen[teller]);

antwoorden[teller]=i*j;
//System.out.println(antwoorden[temp]);
teller++;
}
}
/*
for(int i=0; i<121; i++){
System.out.println(vragen[i]);
}
*/
}

public GUI()
{
// Panels weergeven
JPanel panel = new DetailsLogin(this);
setLayout(new BorderLayout());
this.currentPanel = panel;
Container c = getContentPane();
c.add(panel, BorderLayout.CENTER);
KeuzeInMenu();
}

/**
* Afhankelijk van de keuze een ander panel weergeven.
*/
public void KeuzeInMenu()
{
switch (keuze)
{
case -1: this.remove(currentPanel);
setCurrentPanel(new DetailsLogin(this));
this.add(currentPanel);
this.revalidate();
this.repaint();
this.requestFocus();
break;
case 0: this.remove(currentPanel);
setCurrentPanel(new DetailsMenu(this));
this.add(currentPanel);
this.revalidate();
this.repaint();
this.requestFocus();

break;
case 1: this.remove(currentPanel);
setCurrentPanel(new DetailsOefenen(this));
this.add(currentPanel);
this.revalidate();
this.repaint();
this.requestFocus();
break;
case 2: this.remove(currentPanel);
setCurrentPanel(new DetailsTest(this));
this.add(currentPanel);
this.revalidate();
this.repaint();
this.requestFocus();
break;
case 3: this.remove(currentPanel);
setCurrentPanel(new DetailsResultaten(this));
this.add(currentPanel);
this.revalidate();
this.repaint();
this.requestFocus();
break;
case 4: this.remove(currentPanel);
setCurrentPanel(new DetailsMoeilijkheidsgraad(this));
this.add(currentPanel);
this.revalidate();
this.repaint();
this.requestFocus();
break;
case 5: this.remove(currentPanel);
setCurrentPanel(new DetailsOefenTestBeeld(this, moeilijkheidsgraad, TestOfOefenen, vragen, antwoorden));
this.add(currentPanel);
this.revalidate();
this.repaint();
this.requestFocus();
break;
case 6: this.remove(currentPanel);
setCurrentPanel(new DetailsOefenTestKlaar(this));
this.add(currentPanel);
this.revalidate();
this.repaint();
this.requestFocus();
break;

default: System.out.println("Error");
break;
}
}

/**
* Welk panel weergeven moet worden.
*/
public void setCurrentPanel(JPanel currentPanel)
{
this.currentPanel = currentPanel;
}
}


EDIT: the class which accepts the input

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.Border;

/**
* Aanmaken van het panel voor de test of oefening.
*/
public class DetailsOefenTestBeeld extends JPanel {
static GUI g;
Boolean stop=false;
Random rand = new Random();
String vraag;
private static int[] antwoorden;
private static String[] vragen;
static int counter=0, minuten=0, seconden=0;
public static int maxTijd=300;
static String soort="", tijd="";
static ArrayList<Integer> grenzen = new ArrayList<>();

static JButton antwoord1 = new JButton("antwoord1");
static JButton antwoord2 = new JButton("antwoord2");
static JButton antwoord3 = new JButton("antwoord3");
static JButton antwoord4 = new JButton("antwoord4");
static JTextArea vraagWeergave = new JTextArea(300,100);
static JTextArea stopwatch = new JTextArea(100,100);



public DetailsOefenTestBeeld(GUI menu, int moeilijkheidsgraad, String TestOfOefenen, String[] vragen, int[] antwoorden)
{
System.out.println("test");
g = menu;
//Grootte instellen van het panel en een titel eraan geven afhankelijk of het een test of een oefening is.
Dimension size = getPreferredSize();
setPreferredSize(size);
//Is het een Test of oefening?
soort = TestOfOefenen;
if (soort == "Oefenen")
{
setBorder(BorderFactory.createTitledBorder("Oefenen"));
}
else
{
setBorder(BorderFactory.createTitledBorder("Test"));
Countdown countdown = new Countdown();
countdown.start();
}
//aanmaken van de knoppen voor het antwoorden.
antwoord1.setPreferredSize(new Dimension(150,60));
antwoord2.setPreferredSize(new Dimension(150,60));
antwoord3.setPreferredSize(new Dimension(150,60));
antwoord4.setPreferredSize(new Dimension(150,60));

//bepalen van de antwoorden.

JButton knopMenu = new JButton("Menu");
knopMenu.setPreferredSize(new Dimension(150,60));

vraagWeergave.setMinimumSize (new Dimension(160,35));
stopwatch.setMinimumSize (new Dimension (50,20));

Border border = BorderFactory.createLineBorder(Color.BLACK);
vraagWeergave.setBorder(border);
vraagWeergave.setEditable(false);
vraagWeergave.setFont(new Font("Verdana", Font.PLAIN, 25));
vraagWeergave.setVisible(true);
stopwatch.setBorder(border);
stopwatch.setEditable(false);
stopwatch.setFont(new Font("Verdana", Font.PLAIN, 13));
stopwatch.setVisible(true);

//Swing componenten toewijzen op de GridBagLayout
setLayout(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();

// 1ste Rij
gc.weightx = 1; // hoeveel plaats de knop inneemt
gc.weighty = 1;
if (soort == "Testen")
{
gc.gridx = 1;
gc.gridy = 0;
add(stopwatch, gc);
}

gc.gridx = 1;
gc.gridy = 1;
add(vraagWeergave, gc);

gc.gridx = 0;
gc.gridy = 2;
add(antwoord1, gc);

gc.gridx = 1;
gc.gridy = 2;
add(antwoord2, gc);

gc.gridx = 2;
gc.gridy = 2;
add(antwoord3, gc);

gc.gridx = 3;
gc.gridy = 2;
add(antwoord4, gc);

gc.gridx = 0;
gc.gridy = 3;
add(knopMenu, gc);

OefenTestVragen.reset();
OefenTestVragen OefenTest = new OefenTestVragen(vragen, antwoorden);
//System.out.println("constructor van DetailsOefenTestBeeld");
OefenTestVragen.kiesAntwoordenEnVraag();

// Actionlisteners op knoppen
knopMenu.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
int selectedOption = JOptionPane.showConfirmDialog(null,
"Mag je de test/oefening wel afsluiten van de Juf/Meester? \n De niet ingevulde oefeningen zullen fout gerekend worden.",
"Naar Menu",
JOptionPane.YES_NO_OPTION);
if (selectedOption == JOptionPane.YES_OPTION) {
OefenTestVragen.setMax();
OefenTestVragen.kiesAntwoordenEnVraag();
}
}
});
antwoord1.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0) {
OefenTestVragen.checkAntwoord(1);
OefenTestVragen.kiesAntwoordenEnVraag();
}
});
antwoord2.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0) {
OefenTestVragen.checkAntwoord(2);
OefenTestVragen.kiesAntwoordenEnVraag();
}
});
antwoord3.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0) {
OefenTestVragen.checkAntwoord(3);
OefenTestVragen.kiesAntwoordenEnVraag();
}
});
antwoord4.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0) {
OefenTestVragen.checkAntwoord(4);
OefenTestVragen.kiesAntwoordenEnVraag();
}
});
}
public static void setIndexen(ArrayList<Integer> indexenReceived){
grenzen = indexenReceived;
}
public static int getCounter(){
return counter;
}

//Updaten van de tijd
public static void updateTijd()
{
String tijdSeconden=String.format("%02d", DetailsOefenTestBeeld.maxTijd%60);
String tijdMinuten=String.format("%02d", DetailsOefenTestBeeld.maxTijd/60);
tijd = tijdMinuten+":"+tijdSeconden;
stopwatch.setText(tijd);
if (maxTijd==0)
{
OefenTestVragen.setMax();
OefenTestVragen.kiesAntwoordenEnVraag();
}
}
public static void changeButton(int a, int b, int c, int d, String vraag){
antwoord1.setText(Integer.toString(a));
antwoord2.setText(Integer.toString(b));
antwoord3.setText(Integer.toString(c));
antwoord4.setText(Integer.toString(d));
vraagWeergave.setText(vraag);
}
public static String[] getVragen(){
System.out.println(vragen);
return vragen;
}

public static int[] getAntwoorden(){
return antwoorden;
}

public static void einde(){
GUI.keuze = 6;
g.KeuzeInMenu();
}

public static String getSoort(){
return soort;
}
}

Answer

As I mentioned in my comment, if this were my code, I'd get rid of most all of the static modifiers, and in fact it is the use of static that is currently causing your problem. because your JButtons are static, every time you create a new DetailsOefenTestBeeld instance (and likely the other instances as well), you add a new ActionListener to already existing JButtons, so instead of having one listener, they then have 2, then 3, then...

Solution:

  • get rid of most ALL statics in your program.
  • Side recommendation: swap with a CardLayout, not how you're doing.
  • Side recommendation 2: Don't compare Strings using == or !=. Use the equals(...) or the equalsIgnoreCase(...) method instead. Understand that == checks if the two object references are the same which is not what you're interested in. The methods on the other hand check if the two Strings have the same characters in the same order, and that's what matters here.