我收到堆栈溢出错误

时间:2015-11-02 01:33:46

标签: java swing stack overflow jbutton

我试图创建一个程序,你按下开始,一个新的JFrame出现3个按钮,你必须在使用随机点击它后切换按钮,我相当新的java所以我不知道该怎么做。谢谢

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;
}
}

这里是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();
}
}

这是错误:

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)

1 个答案:

答案 0 :(得分:2)

您的figure方法会不断地递归调用自身,或直到堆栈空间耗尽。解决方案:摆脱那些递归调用。另外,你真的不想继续向JButtons添加多个ActionListener,所有这些都表明你需要重构并重新设计整个程序。

您需要更改类中字段的状态,并使用该字段的状态来决定在ActionListener中执行的操作。

例如:

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();
            }
        });
    }
}