简体   繁体   English

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

[英]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. 我正在创建一个问答游戏,并且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. 我在开始游戏面板中的得分变量最初为0,但对于每个用户的正确答案,它又增加了100分。 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. 但是不幸的是,分数变量为0。在开始游戏面板中,游戏UI正确显示了分数,逻辑正在工作,并且为每个正确答案添加了100分,但是当我尝试在面板中使用分数变量时,每个分数都为0时间。 This is my StartGamePanel: 这是我的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: 然后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);
}
}

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. 您应该将questionscoretime等保留在单独的域类(例如GameData )中,而不是JPanel类中。

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. 在用户启动游戏的事件处理程序中,您应该首先创建GameData的实例,然后将该实例作为构造函数参数传递给StartGamePanel面板类。 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 . 同样,在用户结束游戏的事件处理程序中,应使用与传递给GameOverPanel并将其传递给GameData相同的GameData实例。

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: 根据您提供的更多信息,除了以上将游戏数据分离为独立GameData类的建议之外,还需要执行以下操作:

Add a new setter method in the GameOverPanel class. GameOverPanel类中添加一个新的setter方法。

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

Add a new getter method in the startGamepanel class. startGamepanel类中添加一个新的getter方法。

public void getGameData() {
    return gamedata;
}

Update the swapView method in the main frame class to following: 将主框架类中的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>");

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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