在Java Swing中使用从一个类到另一个类的变量

时间:2017-03-27 14:06:47

标签: java swing

我正在创建一个测验游戏,并在StartGamePanel中遇到一些问题。我已经开始游戏面板,游戏面板和主菜单面板。开始游戏面板中的得分变量最初为0,但对于每个用户的正确答案,它会增加100点。我的想法是在游戏中面板,如果用户给出错误的答案,告诉他他的总积分是多少。但遗憾的是,得分变量为0。在游戏开始面板中,游戏界面显示正确的分数,逻辑正在运行,并为每个正确的答案添加100分,但是当我尝试在面板上的游戏中使用得分变量时,它是0时间。这是我的StartGamePanel:

public class StartGamePanel extends JPanel {
...
private GameData gameData;

public StartGamePanel(Frame frame, GameData gameData) {
    this.frame = frame;
    this.gameData = gameData;
    ...//creating the upper panel and set defaults for the panel

    //label for time
    timeLabel = new JLabel("Time: " + gameData.getTime());
    timeLabel.setFont(font);
    timeLabel.setForeground(Color.BLACK);

    /** updating the timeLabel */
    timer = new Timer(1000, new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            // TODO Auto-generated method stub
            if (gameData.getStartTime() > 0) {
                //getStartTime -= 1000;
                //time--;
                gameData.updateStartTime(-1000);
                gameData.updateTime(-1);
                if (gameData.getTime() == 0) {
                    frame.swapView("gameover");
                }
                timeLabel.setText("Time: " + gameData.getTime());
                timeLabel.repaint();
            }
        }
    });
    timer.start();

    //getting instance of QuestionRandomizer;       
    QuestionRandomizer qRand = new QuestionRandomizer();


    /*question 1 panel*/
    //------------------
    //------------------
    //------------------
    JPanel card1 = new JPanel(new GridBagLayout());
    card1.setBackground(new Color(0, 128, 43));
    Question q1 = qRand.getRandomQuestion();

    //label for the first question
    JLabel question1Label = new JLabel(q1.getText());
    question1Label.setFont(questionLabelsFont);
    question1Label.setForeground(Color.BLACK);

    //gbc for question1Label
    ...

    card1.add(question1Label, gbc2);

    //Panel holding buttons
    JPanel buttonsPanel = new JPanel(new GridLayout(2, 2));


    //Answer buttons

    JButton answer1 = new JButton(q1.getAnswers()[0].getText()+ "");
    answer1.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            // TODO Auto-generated method stub
            if (q1.getAnswers()[0].getIsCorrect() == true) {
            CardLayout cl = (CardLayout) cards.getLayout();
            cl.show(cards, "question2");

            //updating the scores
            gameData.updateScore(100);
            scoresLabel.setText("Scores: " + gameData.getScore());
            scoresLabel.repaint();

            //updating the timer
            timer.stop();
            gameData.setTime(16);
            gameData.setStartTime(16*1000);
            timer.start();
            }       

            //IF THE ANSWER IS INCORRECT GO TO THE GAMEOVER PANEL!!!
            if (q1.getAnswers()[0].getIsCorrect() == false) {
                frame.swapView("gameover");
            }
        }       
    });
    //I have 3 more buttons for the answers in this question card and more questions  cards but the logic is the same for everything.
    public GameData getGameData() {
    return this.gameData;
}

看一下我对面板的比赛:

public class GameOverPanel extends JPanel {
private StartGamePanel sgp;
private JLabel gameOverLabel;
private GameData gameData;

public GameOverPanel(StartGamePanel sgp) {
    this.sgp = sgp;
    this.gameData = sgp.getGameData(); // i created a method in the start game panel which returns start game panel's gameData object
    //default settings
    this.setLayout(new GridBagLayout());
    this.setBackground(new Color(0, 128, 43));
    this.setBorder(new EmptyBorder(10, 10, 10, 10));


    gameOverLabel = new JLabel("");


    gameOverLabel.setText("<html><h1>You didn't answer correctly!</h1><hr><h2></h2><h3>Your score: " + gameData.getScore() + "</h3></html>");

    gameOverLabel.setForeground(Color.BLACK);

    //constraints for the gameoverlabel
    GridBagConstraints gbc = new GridBagConstraints();
    gbc.anchor = GridBagConstraints.CENTER;
    gbc.gridwidth = GridBagConstraints.REMAINDER;

    this.add(gameOverLabel, gbc);

}
}

MainFrame类切换面板:

public class Frame extends JFrame {
CardLayout cl = new CardLayout();
GameData gameData = new GameData();
MainMenu menuPanel = new MainMenu(this);
StartGamePanel startPanel = new StartGamePanel(this, gameData);
GameOverPanel gameOverPanel = new GameOverPanel(startPanel);


public Frame() {
    this.setLayout(cl);
    this.setSize(800, 600);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setVisible(true);
    this.setResizable(false);
    //this.setEnabled(true);


    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    int screenWidth = screenSize.width;
    int screenHeight = screenSize.height;

    this.setLocation((screenWidth - getWidth()) / 2, (screenHeight - getHeight()) / 2);

    this.add(menuPanel, "menu");
    this.add(startPanel, "start");
    this.add(gameOverPanel, "gameover");
    swapView("menu");
}

public void swapView(String view) {
    cl.show(getContentPane(), view);
}
}

1 个答案:

答案 0 :(得分:2)

您尚未正确建模问题域。这就是你面临这个问题的原因。您应该将questionscoretime等保留在单独的域类(例如GameData)中,而不是JPanel类。

在用户启动游戏的事件处理程序中,您应首先创建GameData的实例,然后将该实例传递给StartGamePanel面板类,比如说,作为构造函数参数。类似地,在用户结束游戏的事件处理程序中,您应该使用与传递给spg时相同的GameData实例并将其传递给GameOverPanel

修改

根据您提供的更多信息,除了上述将游戏数据分离到独立GameData类的建议外,您还需要做以下事项:

GameOverPanel课程中添加新的setter方法。

public void setGameData(GameData gd) {
    this.gameData = gd;
}

startGamepanel类中添加新的getter方法。

public void getGameData() {
    return gamedata;
}

将主框架类中的swapView方法更新为以下内容:

public void swapView(String view) {
    if("gameover".equals(view)) {
         gameOverPanel.setGameData(startPanel.getGameData());
    }
    cl.show(getContentPane(), view);
    gameOverLabel.setText("<html><h1>You didn't answer correctly!</h1><hr><h2></h2><h3>Your score: " + gameData.getScore() + "</h3></html>");

}