【问题标题】:ActionListener: Disabling ButtonsActionListener:禁用按钮
【发布时间】:2013-06-05 16:19:39
【问题描述】:

我目前正在研究一个 Java 类,它可以生成简单的井字游戏 JFrame/JButton 布局。实现 ActionListener,我打算让选定的 JButton 将其标题设置为“X”或“O”(基于是否轮到 X 选择 JButton 的布尔语句)并禁用(因此无法播放在接下来的轮次顶部)。我创建的当前应用程序执行此操作,但它有时不会更改 JButton 文本或禁用该按钮,直到我单击另一个按钮。当我单击其中一个 JButton 时,似乎没有任何一种连贯的顺序会发生这种情况。我花了几个小时试图解决这个问题,但无济于事。我如何编写 actionPerformed 方法或如何将其添加到 JButton 中是否存在问题?

这是我班级的代码:

import javax.swing.*;
import java.awt.event.*;
import javax.swing.*;

public class TTT extends JFrame implements ActionListener{

  // private fields
  private JButton[] buttonArray;
  private JLabel prompt;
  private boolean turnX;
  private String letter;



 public TTT() {
    // Instantiates JFrame window and adds lines to board
    super.setSize(235, 280);
    super.setTitle("Tic-Tac-Toe");
    // Instantiates JButton array
    buttonArray = new JButton[9];
    // Loop that creates the JButton squares
    for(int y = 30; y <= 140; y += 55) {
      for(int x = 30; x <= 140; x += 55) {
        for(int index = 0; index < buttonArray.length; index++) {
        buttonArray[index] = new JButton();
        buttonArray[index].setSize(50, 50);
        buttonArray[index].setLocation(x, y);
        buttonArray[index].addActionListener(this);
        super.add(buttonArray[index]);
      }  
    }
    }
    prompt = new javax.swing.JLabel("X's TURN");
    prompt.setVerticalAlignment(JLabel.BOTTOM);
    super.add(prompt);

    turnX = true;

    super.setVisible(true);
  } 

 public void actionPerformed(java.awt.event.ActionEvent a) {

        // Calculate whose turn it is
        if(turnX){
            letter = "X";
            prompt.setText("O's TURN");
            turnX = false;    
        } else if(!turnX){
            letter = "O";
            prompt.setText("X's TURN");
            turnX = true;
        }
        JButton pressedButton = (JButton)a.getSource(); 
        pressedButton.setText(letter);
        pressedButton.setEnabled(false);
        super.repaint();
 }

  public static void main(String[] args) {
    new TTT();
  } 
}  

【问题讨论】:

    标签: java jframe actionlistener


    【解决方案1】:

    使用此代码:

    for(int y = 30; y <= 140; y += 55) {
      for(int x = 30; x <= 140; x += 55) {
        for(int index = 0; index < buttonArray.length; index++) {
    

    您正在添加 82(!) 个 JButton(一个在另一个之上,以 9 个为一组)。所以,实际发生的是一个被改变(禁用等),但在调用重绘时,绘制它们的顺序可能会改变,所以触发 ActionListener 的那个被绘制在仍然启用和空白的 8 个之一下面。

    你可以这样改正:

    ...
    int index = 0;   // <-- Add this line
    for(int y = 30; y <= 140; y += 55) {
        for(int x = 30; x <= 140; x += 55) {
               // <-- remove the third for-loop
            buttonArray[index] = new JButton();
            buttonArray[index].setSize(50, 50);
            buttonArray[index].setLocation(x, y);
            buttonArray[index].addActionListener(this);
            super.add(buttonArray[index]);
            index++;   // <-- increment 'index'
        }  
    }
    ...
    

    您也可以删除 super.repaint() 行,因为它是多余的。


    与您的问题没有直接关系,但应该(出于各种原因)从 Event Dispatching Thread (EDT) 调用与 Swing 相关的内容。实现此目的的一种方法是使用 SwingUtilities.invokeLater(),因此将 new TTT(); 替换为以下内容可能是个好主意:

    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            new TTT();
        }
    });
    

    【讨论】:

    • 非常感谢!当我读到我正在向 JFrame 添加 82 个按钮时,我很高兴......
    猜你喜欢
    • 1970-01-01
    • 2012-05-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-26
    • 2017-04-07
    • 2017-02-21
    • 2011-12-13
    • 2011-02-02
    相关资源
    最近更新 更多