2013-08-05 92 views
3

我想用swing写一个Tic Tac Toe程序,但是我似乎遇到了一些麻烦。在我的匿名内部类中,我尝试为每个按钮设置actionListener,但是我无法找到允许我引用按钮并将它们设置为X或Y的类型或变量。我尝试了e .getSource()。setText()在我的匿名类中,但返回错误。有什么想法吗? 谢谢! 亚历在ActionListener里面引用点击JButton

import javax.swing.*; 

import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

public class TicTacToe { 

public JFrame frame; 
public JLabel label; 
public JPanel panel; 

public static int counter; 



public void go() 
{ 
    frame = new JFrame("TicTacToe"); 
    frame.setSize(500, 500); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    panel = new JPanel(); 
    panel.setLayout(new GridLayout(3,3,10,10)); 
    frame.add(BorderLayout.CENTER, panel); 
    label= new JLabel("TIC TAC TOE"); 
    frame.add(BorderLayout.NORTH, label); 

    ; 


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





    button1.addActionListener(new ActionListener(){ 
     public void actionPerformed(ActionEvent e) 
     { 


     } 
    }); 

    button2.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) 
     { 

     } 
    }); 

    button3.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) 
     { 

     } 
    }); 

    button4.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) 
     { 

     } 
    }); 

    button5.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) 
     { 

     } 
    }); 

    button6.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) 
     { 

     } 
    }); 

    button7.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) 
     { 

     } 
    }); 

    button8.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) 
     { 

     } 
    }); 

    button9.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) 
     { 

     } 
    }); 

    panel.add(button1); 
    panel.add(button2); 
    panel.add(button3); 
    panel.add(button4); 
    panel.add(button5); 
    panel.add(button6); 
    panel.add(button7); 
    panel.add(button8); 
    panel.add(button9); 
    frame.setVisible(true); 
    panel.setVisible(true); 

} 


public static void main(String[] args) 
{ 
    TicTacToe gui = new TicTacToe(); 
    gui.go(); 

} 


} 

回答

11

记住,ActionListener可以在许多不同类型的组件中使用,所以源参考被一般化。你需要转换为回期望值

button9.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent e) 
    { 
     Object source = e.getSource(); 
     if (source instanceof JButton) { 
      JButton btn = (JButton)source; 
      // Go ahead and do what you like 
     } 
    } 
}); 

虽然我知道你ActionListener,因为它代表几乎可以保证该Object的源类型将是一个JButton,我从来不喜欢盲目地转换对象,但是这我

+1

非常感谢。我真的很感激这种帮助,而且这也创造了奇迹。 – Amloelxer

+0

另一个问题。以这种方式确定赢家的最佳方式是什么?假设我做了一个计数器并且有((JButton)源).setText(“O”);或((JButton)源).setText(“X”); – Amloelxer

+0

其实,最好的办法是建立某种模型。这将允许您检查游戏状态并确定选择哪些单元格以及由谁选择。每次玩家选择一个按钮,我都会更新模型。这个过程的一部分是为模型检查一个胜利者并且引发一个适当的事件 – MadProgrammer

2

如果您收到错误,那么你应该发布它们,但我假设这是因为你没有断言源对象实际上是一个按钮。对于你正在做的事情有两个直接的解决方案。

第一个是因为您只是为每个按钮添加一个动作侦听器,您可以假定它是动作事件引用的对象。只要注意,按钮要么必须是一个实例变量或声明为final:

button1.addActionListener(new ActionListener(){ 
     @Override 
     public void actionPerformed(ActionEvent e) 
     { 
      button1.setText("X/Y"); 
     } 
    }); 

其次,这将解决您的错误的原因,是声称ActionEvent源对象其实是一个按钮。

button1.addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      if (e.getSource() instanceof JButton) { 
       ((JButton) e.getSource()).setText("X/Y"); 
      } 
     } 
    }); 
+1

我唯一要做的评论是确保你强调一个事实,即在你的第一个例子中'JButton'要么是一个实例变量或'最后';) – MadProgrammer

+0

好点,谢谢。 –

1

我经历了和清理你的代码一点点:这是通过检查源是JButton的实例来完成。我不太清楚为什么你的代码有错误,但我没有得到任何答案。我建议,因为你有共同的代码,像我在数组中一样重用它。我还添加了一个boolean在每次点击按钮时在玩家之间切换。

最后,我建议在构造函数中或在构造函数调用的私有方法中设置JFrame(更复杂的用户界面可能有很多代码,并且分解代码是维护代码的好习惯)就像我下面展示的那样。

import javax.swing.*; 

import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

public class TicTacToe { 
    public static final boolean PLAYER_X = false; 
    public static final boolean PLAYER_O = true; 

    public static int counter; 

    private JFrame frame; 
    private JLabel label; 
    private JPanel panel; 
    private JButton[] buttons; 
    private boolean player; 

    public TicTacToe() { 
     frame = new JFrame("TicTacToe"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     panel = new JPanel(); 
     panel.setPreferredSize(new Dimension(500, 500)); 
     panel.setLayout(new GridLayout(3, 3, 10, 10)); 
     frame.add(BorderLayout.CENTER, panel); 

     label = new JLabel("TIC TAC TOE"); 
     frame.add(BorderLayout.NORTH, label); 

     /* Set the initial player turn to player X */ 
     player = PLAYER_X; 

     /* Create the JButtons */ 
     buttons = new JButton[9]; 

     /* Loop through and set all of them up */ 
     for (int i = 0; i < buttons.length; i++) { 
      buttons[i] = new JButton(); 
      buttons[i].addActionListener(new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        if (e.getSource() instanceof JButton) { 
         ((JButton)e.getSource()).setText(player ? "O" : "X"); /* Set button text */ 
         player = !player; /* Switch turns */ 
        } 
       } 
      }); 

      /* Add all of the buttons to the panel. */ 
      panel.add(buttons[i]); 
     } 

     /* Pack the frame to the contents. Basically a "fit to contents". */ 
     frame.pack(); 
    } 

    public void go() { 
     frame.setVisible(true); 
     panel.setVisible(true); 
    } 

    public static void main(String[] args) { 
     TicTacToe gui = new TicTacToe(); 
     gui.go(); 
    } 
}