如何从另一个类访问JButton [英] How to access a JButton from another class

查看:63
本文介绍了如何从另一个类访问JButton的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个类'UserInterface'和'GameEngine',我在UserInterface中声明了一个JButton组件,我试图使用其中一个变量,即在'horizo​​ntalWin'中使用'UserInterface'中的变量'button1'类"GameEngine"中的方法.

I have two classes 'UserInterface' and a 'GameEngine' I have declared a JButton component in the UserInterface and I am trying to use one of the variables i.e use the variable 'button1' from 'UserInterface' in the 'horizontalWin' method from the class 'GameEngine'.

我收到此错误,而是找不到符号-变量button1"

I got this error instead "cannot find symbol - variable button1"

用户界面:

public class UserInterface implements ActionListener
{
 private GameEngine game;
 private JFrame frame;

 JButton button1 = new JButton("");
 JButton button2 = new JButton("");
 JButton button3 = new JButton("");
 JButton button4 = new JButton("");
 JButton button5 = new JButton("");
 JButton button6 = new JButton("");
 JButton button7 = new JButton("");
 JButton button8 = new JButton("");
 JButton button9 = new JButton("");

 /**
 * Create a user interface.
 * @param engine The game's engine.
 */
 public UserInterface(GameEngine engine)
 {
    game = engine;
    makeFrame();
 }

 //some methods
}

GameEngine:

GameEngine:

public class GameEngine {
 private String buttonName;
 boolean winner = false;
 byte count;

public GameEngine()
{
    count = 0;
}

public void horizontalWin()
{
    if(button1.getText()==button2.getText() && button2.getText()==button3.getText() && button1.getText()!="" )
    {
        winner=true;
        playAgain(buttonName);

    }
    // Horizontal win row 2
    else if(button4.getText()==button5.getText() && button5.getText()==button6.getText() && button4.getText()!="" )
    {
        winner=true;
        playAgain(buttonName);

    }
    // horizontal win row 3
    else if(button7.getText()==button8.getText() && button8.getText()==button9.getText() && button7.getText()!="")
    {
        winner=true;
        playAgain(buttonName);

    }

}

推荐答案

我认为您并不是真的想要这样做,也不希望您的游戏引擎试图从视图中获取变量.而是为什么不让您的视图在按下按钮时通知引擎或模型"(通常通过称为控件"的内容).引擎便可以跟踪所按下的内容并相应地更改其状态.然后根据引擎状态的变化进行更改.

I think that you don't really want to do this, that you don't want your game engine trying to obtain variables from the view. Rather why not have your view notify the engine or "model" (usually through something called a "control", when a button has been pressed. The engine then can keep track of what has been pressed and change its state accordingly. The View can then change in response to changes in the engine's state.

例如:

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;
import javax.swing.event.SwingPropertyChangeSupport;

public class TicTacToe  {

   private static void createAndShowGui() {
      View mainPanel = new View();

      JFrame frame = new JFrame("TicTacToe");
      frame.setDefaultCloseOperation(JFrame.EXIT_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();
         }
      });
   }
}

@SuppressWarnings("serial")
class View extends JPanel {
   private static final int GAP = 2;
   private static final Font BTN_FONT = new Font(Font.SANS_SERIF, Font.BOLD, 42);
   private JButton[][] gameGrid = new JButton[Engine.ROWS][Engine.ROWS];
   private Engine engine = new Engine();

   public View() {
      engine.addPropertyChangeListener(Engine.GAME_OVER, new GameOverListener());

      JPanel gameGridPanel = new JPanel(new GridLayout(Engine.ROWS, Engine.ROWS, GAP, GAP));
      for (int i = 0; i < gameGrid.length; i++) {
         for (int j = 0; j < gameGrid[i].length; j++) {
            gameGrid[i][j] = createGameGridButton(i, j);
            gameGridPanel.add(gameGrid[i][j]);
         }
      }

      JButton resetBtn = new JButton(new ResetAction("Reset", KeyEvent.VK_R));
      JPanel northPanel = new JPanel();
      northPanel.add(resetBtn);

      setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
      setLayout(new BorderLayout(GAP, GAP));
      add(gameGridPanel, BorderLayout.CENTER);
      add(northPanel, BorderLayout.NORTH);
   }

   private JButton createGameGridButton(int i, int j) {
      JButton button = new JButton();
      button.setName(String.format("%d,%d", i, j));
      button.setText(XO.BLANK.getText());
      button.setFont(BTN_FONT);
      button.addActionListener(new GridButtonListener(i, j));
      return button;
   }

   private class GridButtonListener implements ActionListener {
      private int i;
      private int j;

      public GridButtonListener(int i, int j) {
         this.i = i;
         this.j = j;
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         if (engine.isGameOver()) {
            return;
         }
         AbstractButton source = (AbstractButton) e.getSource();
         String text = source.getText();
         if (text.trim().isEmpty()) {
            source.setText(engine.getTurn().getText());
            engine.setXO(i, j);
         }
      }
   }

   private class ResetAction extends AbstractAction {
      public ResetAction(String text, int mnemonic) {
         super(text);
         putValue(MNEMONIC_KEY, mnemonic);
      }

      public void actionPerformed(ActionEvent e) {
         engine.reset();
         for (JButton[] row : gameGrid) {
            for (JButton button : row) {
               button.setText(XO.BLANK.getText());
            }
         }
      };
   }

   private class GameOverListener implements PropertyChangeListener {
      @Override
      public void propertyChange(PropertyChangeEvent evt) {
         if (evt.getNewValue() == Boolean.TRUE) {
            JOptionPane.showMessageDialog(View.this, engine.getTurn()
                  .getText() + " is a winner!", "We Have a Winner!",
                  JOptionPane.INFORMATION_MESSAGE);
         }
      }
   }
}

class Engine {
   public static final int ROWS = 3;
   public static final String GAME_OVER = "game over";
   private XO[][] grid = new XO[ROWS][ROWS];
   private XO turn = XO.X;
   private boolean gameOver = false;
   private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport(
         this);

   public Engine() {
      reset();
   }

   public XO getTurn() {
      return turn;
   }

   public boolean isGameOver() {
      return gameOver;
   }

   public void setXO(int row, int col) {
      grid[row][col] = turn;
      checkForWin(row, col);
      turn = (turn == XO.X) ? XO.O : XO.X;
   }

   public void reset() {
      for (int r = 0; r < grid.length; r++) {
         for (int c = 0; c < grid[r].length; c++) {
            grid[r][c] = XO.BLANK;
         }
      }
      turn = XO.X;
      gameOver = false;
   }

   public void checkForWin(int i, int j) {
      boolean win = true;
      for (int col = 0; col < grid.length; col++) {
         if (grid[col][j] != turn) {
            win = false;
         }
      }
      if (!win) {
         win = true;
         for (int row = 0; row < grid[i].length; row++) {
            if (grid[i][row] != turn) {
               win = false;
            }
         }
      }
      if (!win && i == j) {
         win = true;
         for (int k = 0; k < grid.length; k++) {
            if (grid[k][k] != turn) {
               win = false;
            }
         }
      }
      if (!win && i + j == 2) {
         win = true;
         for (int k = 0; k < grid.length; k++) {
            if (grid[k][2 - k] != turn) {
               win = false;
            }
         }
      }

      if (win) {
         setGameOver(true);
      }

   }

   private void setGameOver(boolean gameOver) {
      boolean oldValue = this.gameOver;
      boolean newValue = gameOver;
      this.gameOver = gameOver;
      pcSupport.firePropertyChange(GAME_OVER, oldValue, newValue);
   }

   public void addPropertyChangeListener(PropertyChangeListener listener) {
      pcSupport.addPropertyChangeListener(listener);
   }

   public void removePropertyChangeListener(PropertyChangeListener listener) {
      pcSupport.removePropertyChangeListener(listener);
   }

   public void addPropertyChangeListener(String name,
         PropertyChangeListener listener) {
      pcSupport.addPropertyChangeListener(name, listener);
   }

   public void removePropertyChangeListener(String name,
         PropertyChangeListener listener) {
      pcSupport.removePropertyChangeListener(name, listener);
   }

}

enum XO {
   X("X"), O("O"), BLANK("   ");
   private String text;

   private XO(String text) {
      this.text = text;
   }

   public String getText() {
      return text;
   }
}

我的视图的ActionListener(在这里是AbstractAction)通知引擎某个按钮已被按下.引擎会跟踪按下了哪个按钮,并确定了获胜者时,设置gameOver字段,从而通知所有听众游戏已结束.

My view's ActionListener (here an AbstractAction) notifies the Engine that a certain button has been pushed. The Engine keeps track of which button has been pushed, and when a winner has been determined, sets a gameOver field thereby notifying all listeners that the game is over.

这篇关于如何从另一个类访问JButton的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆