将Main类实例发送到另一个类时出现Stackoverflow错误

时间:2016-09-09 09:18:49

标签: java swing stack-overflow

我是一名试图建立HangMan游戏的新手程序员。

所以,我有一个Main类(Main JFrame),它实例化了不同的其他面板类。一个这样的面板是keyboardPanel,它基本上是一个带有JButtons的面板。我在Main Class中有一个checkwithKey()方法,我需要在keyboardPanel类中调用它(对于JButtons的ActionListener类)。为此,我在MainClass中创建了一个getInstance()方法,并在keyboardPanel类中调用它。当我执行它时,我收到stackoverflow错误。

以下是MainFrame类的代码片段:

  //MainFrame class
  public class MainFrame extends JFrame {
  public KeyboardPanel keyboardPanel;
  private static MainFrame mf;

   private MainFrame(){
   keyboardPanel = KeyboardPanel.getInstance();
   add(keyboardPanel);      
   }     

  public static MainFrame getInstance(){
    if(mf==null){
        mf = new MainFrame();
        return mf;
    }
    else
        return mf;
    }

    public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                MainFrame frame = MainFrame.getInstance();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}
   protected void checkwithKey(char c){
      //Logic
     }

    }

以下是KeyboardPanel类的代码片段

   //KeyboardPanel Class
   public class KeyboardPanel extends JPanel {
      private static KeyboardPanel kdP;
      private MainFrame mf = MainFrame.getInstance() ;

      public static KeyboardPanel getInstance(){
        if(kdP == null){
          kdP = new KeyboardPanel();
          return kdP;
          }
            else
              return kdP;
        }        

        private KeyboardPanel(){
         //JButton Code..

         }

    class KeyAction implements ActionListener{

    @Override
    public void actionPerformed(ActionEvent a) {
        char c = a.getActionCommand().charAt(0);
        mf.checkwithKey(c);  // I need to call the checkwithkey() from Mainclass here
        }
      }

   }

任何人都可以帮我吗?

堆栈跟踪:

Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
at sun.awt.Win32GraphicsConfig.getBounds(Native Method)
at sun.awt.Win32GraphicsConfig.getBounds(Unknown Source)
at java.awt.Window.init(Unknown Source)
at java.awt.Window.<init>(Unknown Source)
at java.awt.Frame.<init>(Unknown Source)
at java.awt.Frame.<init>(Unknown Source)
at javax.swing.JFrame.<init>(Unknown Source)
at hangman.MainFrame.<init>(MainFrame.java:119)
at hangman.MainFrame.getInstance(MainFrame.java:30)
at hangman.MainFrame.<init>(MainFrame.java:134)
at hangman.MainFrame.getInstance(MainFrame.java:30)
at hangman.MainFrame.<init>(MainFrame.java:134)
at hangman.MainFrame.getInstance(MainFrame.java:30)
at hangman.MainFrame.<init>(MainFrame.java:134)
at hangman.MainFrame.getInstance(MainFrame.java:30)
at hangman.MainFrame.<init>(MainFrame.java:134)
at hangman.MainFrame.getInstance(MainFrame.java:30)
at hangman.MainFrame.<init>(MainFrame.java:134)
at hangman.MainFrame.getInstance(MainFrame.java:30)
at hangman.MainFrame.<init>(MainFrame.java:134)
at hangman.MainFrame.getInstance(MainFrame.java:30)
at hangman.MainFrame.<init>(MainFrame.java:134)
at hangman.MainFrame.getInstance(MainFrame.java:30)
at hangman.MainFrame.<init>(MainFrame.java:134)
at hangman.MainFrame.getInstance(MainFrame.java:30)
at hangman.MainFrame.<init>(MainFrame.java:134)
at hangman.MainFrame.getInstance(MainFrame.java:30)
at hangman.MainFrame.<init>(MainFrame.java:134)
at hangman.MainFrame.getInstance(MainFrame.java:30)
at hangman.MainFrame.<init>(MainFrame.java:134)
at hangman.MainFrame.getInstance(MainFrame.java:30)

1 个答案:

答案 0 :(得分:0)

1) MainFrame frame = MainFrame.getInstance();
2) keyboardPanel = KeyboardPanel.getInstance();
3) private MainFrame mf = MainFrame.getInstance();

在第3行中,MainFrame尚未实例化。结果

if(mf==null)

返回true。然后它试图再次实例化。所以主要问题在于你的类的使用。他们在初始化阶段被束缚。

我认为有理由将KeyboardPanel类用作单例。 仅使用MainFrame才有意义。 这是您案例中最短的解决方案:

//MainFrame class
public class MainFrame extends JFrame {
    public KeyboardPanel keyboardPanel;
    private static MainFrame mf;

    private MainFrame(){
        keyboardPanel = new KeyboardPanel(this);
        add(keyboardPanel);
    }

    public static MainFrame getInstance(){
        if(mf==null){
            mf = new MainFrame();
        }
        return mf;
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    MainFrame frame = MainFrame.getInstance();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
    protected void checkwithKey(char c){
        //Logic
    }

}


//KeyboardPanel Class
public class KeyboardPanel extends JPanel {

    public KeyboardPanel(MainFrame mf){
        this.mf = mf;
    }

    class KeyAction implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent a) {
            char c = a.getActionCommand().charAt(0);
            mf.checkwithKey(c);  // I need to call the checkwithkey() from Mainclass here
        }
    }

}