-1

I'm trying to create a program where you press start and a new JFrame comes up with 3 buttons , you have to switch the button after you click on it using a random , I'm fairly new to java so I don't know what to do. Thank you

package code;

import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.Timer;
public class StartListener implements java.awt.event.ActionListener {
private int counter;
private Game Ga;
private JFrame z;
private int x;
public StartListener(Game a, int co){
    Ga=a;
    counter = co;
}
public void actionPerformed(ActionEvent e) {
        Timer time = new Timer(10000,new Time(Ga));
        time.start();
        z = new JFrame("Sequence game"); 
        FlowLayout fl = new FlowLayout(0, 50, 40);    
        z.getContentPane().setLayout(fl);
        z.setVisible(true);
        JButton a = new JButton("A"); 
        Font f = a.getFont(); 
        Font myFont = f.deriveFont(Font.BOLD, f.getSize()*4); 
        a.setSize(200,100); 
        a.setVisible(true); 
         JButton b = new JButton("B"); 
        b.setVisible(true); 
        b.setSize(200,100);
        JButton c = new JButton("C");
        c.setVisible(true);
        c.setSize(200,100);
        z.getContentPane().add(a);
        z.getContentPane().add(b);
        z.getContentPane().add(c);
        z.pack();
        Random r = new Random(); 
        x=r.nextInt(3);
        figure(a,b,c,x,myFont,f);}
public void figure(JButton a,JButton b, JButton c, int x, Font myFont,Font           f){
        if(x==0){ 
            a.setEnabled(true);
            b.setEnabled(false);
            c.setEnabled(false);
            a.setFont(myFont);
            b.setFont(f);
            c.setFont(f);
            x =buttonA(a);
            figure(a,b,c,x,myFont,f);

                ;} 
        else if(x==1){ 
            a.setEnabled(false);
            b.setEnabled(true);
            c.setEnabled(false);
            a.setFont(f);
            c.setFont(f);
            b.setFont(myFont); 
                x = buttonB(b);
                figure(a,b,c,x,myFont,f);
                }
        else if(x==2){ 
            a.setEnabled(false);
            b.setEnabled(false);
            c.setEnabled(true);
            a.setFont(f);
            b.setFont(f);
            c.setFont(myFont);
            x = buttonC(c);
                    figure(a,b,c,x,myFont,f);
                    }
                } 
public int buttonA(JButton a){
    Random r = new Random();
    int rand = 0;
    a.addActionListener(new Something(Ga));
    rand = r.nextInt(3);
    return rand;
}
public int buttonB(JButton b){
    Random r = new Random();
    int rand = 0;
    b.addActionListener(new Something(Ga));
    rand=r.nextInt(3);
    return rand;
}
    public int buttonC(JButton c){
    Random r = new Random();
    int rand=0;
    c.addActionListener(new Something(Ga));
    rand = r.nextInt(3);
    return rand;
}
}

And here's the code for Something

package code;

import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Something implements ActionListener {
private Game G;

public Something(Game a){
G = a;
}
public void actionPerformed(ActionEvent e) {
    // TODO Auto-generated method stub
            G.increment();
}
}

Here's the error :

Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
    at java.awt.Component.enable(Unknown Source)
    at java.awt.Component.setEnabled(Unknown Source)
    at javax.swing.JComponent.setEnabled(Unknown Source)
    at javax.swing.AbstractButton.setEnabled(Unknown Source)
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • 1
    The figure method is recursively calling itself, and likely your stopping condition is not working... I'd work on fixing this first. – Hovercraft Full Of Eels Nov 02 '15 at 01:35
  • 1
    *"..a new JFrame comes up.."* 1) See [The Use of Multiple JFrames, Good/Bad Practice?](http://stackoverflow.com/q/9554636/418556) 2) For better help sooner, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). 3) Use a logical and consistent form of indenting code lines and blocks. The indentation is intended to make the flow of the code easier to follow! 4) Please learn common Java nomenclature (naming conventions - e.g. `EachWordUpperCaseClass`, `firstWordLowerCaseMethod()`, `firstWordLowerCaseAttribute` unless it is an `UPPER_CASE_CONSTANT`) and use them! – Andrew Thompson Nov 02 '15 at 01:38

1 Answers1

2

Your figure method continuously calls itself recursively forever, or until stack space runs out. Solution: get rid of those recursive calls. Also you really don't want to keep adding multiple ActionListeners on to JButtons, all this suggesting that you will want to refactor and perhaps redesign the entire program.

You will want to change the state of a field in the class, and use that field's state to decide what to do within the ActionListener.

For example:

import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;

@SuppressWarnings("serial")
public class SwapButtons extends JPanel {
    private static final Font ACTIVE_FONT = new Font(Font.DIALOG, Font.BOLD, 15);
    private static final String[] BTN_TEXT = { "Monday", "Tuesday", "Wednesday" };
    private static final int EXTRA_WIDTH = 50;
    private List<AbstractButton> buttonList = new ArrayList<>();
    private int buttonIndex = 0;

    public SwapButtons() {
        setLayout(new GridLayout(1, 0, 5, 0));
        BtnListener btnListener = new BtnListener();
        for (int i = 0; i < BTN_TEXT.length; i++) {
            JButton button = new JButton(BTN_TEXT[i]);
            button.addActionListener(btnListener);
            buttonList.add(button); // add to ArrayList
            add(button); // add to GUI
        }
        setActiveButton();

        setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    }

    @Override
    public Dimension getPreferredSize() {
        Dimension superSz = super.getPreferredSize();
        if (isPreferredSizeSet()) {
            return superSz;
        }

        // give preferred size extra width so gui can handle larger fonts
        int prefW = superSz.width + EXTRA_WIDTH;
        int prefH = superSz.height;
        return new Dimension(prefW, prefH);
    }

    private void setActiveButton() {
        // iterate through buttonList, turning on the "active" button
        // as determined by the buttonIndex variable
        for (int i = 0; i < buttonList.size(); i++) {
            if (i == buttonIndex) {
                buttonList.get(i).setFont(ACTIVE_FONT);
                buttonList.get(i).setEnabled(true);
            } else {
                buttonList.get(i).setFont(null);
                buttonList.get(i).setEnabled(false);
            }
        }
    }

    private class BtnListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            // show which button pressed
            System.out.println("Button Pressed: " + e.getActionCommand());

            // advance button index so that next button can be activated
            buttonIndex++;

            // but change index to 0 if buttonList size is reached
            buttonIndex %= buttonList.size();

            // activate the next button:
            setActiveButton();
        }
    }

    private static void createAndShowGui() {
        SwapButtons mainPanel = new SwapButtons();

        JFrame frame = new JFrame("Swap Buttons");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }
}
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • But I need it to go to a different button after each click , how would I do so? – Andriy Ukraine Nov 02 '15 at 01:47
  • @AndriyUkraine: then change the state of a field in the class, and use that field's state to decide what to do within the ActionListener. For more specific help, describe in greater detail what you're trying to do with each button click, and show a small amount code we can run and compile and test that reproduces your error, a [mcve]. – Hovercraft Full Of Eels Nov 02 '15 at 01:49
  • What the instructor said to do was to make a program that had a start button that creates a new frame with 3 buttons, at random one of these buttons will be bigger and the other two will be grayed out. Once you click on the big button you get another point on the counter and also the big button will go back to default size while another button will get bigger – Andriy Ukraine Nov 02 '15 at 01:53
  • And what do you mean by a code that reproduces the error? – Andriy Ukraine Nov 02 '15 at 02:00
  • @AndriyUkraine: Please see edit to answer for an example of 1) code that swaps active buttons, and 2) shows a small compilable and runnable program that demonstrates what I'm trying to show you. – Hovercraft Full Of Eels Nov 02 '15 at 02:09