简体   繁体   中英

Use variable from one class to another in Java Swing

I am creating a quiz game and have some troubles with the variables in the StartGamePanel. I have start game panel, game over panel and main menu panel. My score variable in the start game panel is initially 0 but for every user's correct answer it goes 100 more points. My idea is in the game over panel if user give wrong answer to show him what was his total points. But unfortunately the score variable is stands 0. In the start game panel the game UI shows correctly scores and the logic is working and add 100 points for every correct answer but when i try to use score variable in the game over panel it is 0 every time. This is my 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;
}

Take a look at my game over panel:

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

}
}

And the MainFrame class switching over the panels:

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

You haven't modeled your problem domain correctly. That's why you are facing this problem. You should keep question , score , time , etc in a separate domain class (say GameData ), not in the JPanel class.

In the event handler of user's starting the game, you should first create an instance of GameData and then pass that instance to your StartGamePanel panel class, say, as a constructor argument. Similarly, in the event handler of user's ending the game, you should use the same instance of GameData as you passed to spg and pass it to GameOverPanel .

Edit :

Based on the further information you have provided, here is what you need to do in addition to the above suggestion of separating the game data to an independent GameData class:

Add a new setter method in the GameOverPanel class.

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

Add a new getter method in the startGamepanel class.

public void getGameData() {
    return gamedata;
}

Update the swapView method in the main frame class to following:

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>");

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM