【问题标题】:How to access a JButton from another class如何从另一个类访问 JButton
【发布时间】:2015-04-03 17:20:30
【问题描述】:

我有两个类 'UserInterface' 和一个 'GameEngine' 我已经在 UserInterface 中声明了一个 JButton 组件,我正在尝试使用其中一个变量,即在 'horizo​​ntalWin' 中使用来自 'UserInterface' 的变量 'button1'来自“GameEngine”类的方法。

我得到了这个错误,而不是“找不到符号 - 变量 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
}

游戏引擎:

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

    }

}

【问题讨论】:

    标签: java swing jbutton


    【解决方案1】:

    我认为您并不想这样做,您不希望您的游戏引擎尝试从视图中获取变量。而是为什么不让您的视图通知引擎或“模型”(通常通过称为“控件”的东西,当按下按钮时。引擎然后可以跟踪已按下的内容并相应地更改其状态。视图可以然后根据引擎状态的变化而变化。

    例如:

    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 字段,从而通知所有听众游戏结束。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-29
      • 2012-01-04
      • 2012-05-06
      • 1970-01-01
      相关资源
      最近更新 更多