我已经创建了Tic-Tac-Toe游戏的一部分,我试图确保一旦游戏开始,“玩家VS玩家”按钮就会被禁用。我是Java swing和所有图形的新手,所以请,任何帮助表示赞赏。我使用过.removeActionListener,但似乎没有做任何事情(或者我注意到的任何事情)。我的代码可能看起来很糟糕,但正如我所说,我是新手。现在可能不需要某些导入,但我打算稍后再使用它们。 提前谢谢!
import java.util.Scanner;
import java.lang.Object;
import java.awt.Component;
import java.awt.Container;
import java.awt.Window;
import java.awt.Frame;
import javax.swing.JFrame;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComponent;
import javax.swing.text.JTextComponent;
import javax.swing.JTextField;
import java.lang.Thread;
import java.util.EventObject;
import java.awt.AWTEvent;
import java.awt.event.ComponentEvent;
import java.awt.event.WindowEvent;
import java.awt.Font;
import javax.swing.*;
class ticTacToe implements ActionListener
{
public static JFrame menuFrame = new JFrame("Tic-Tac-Toe");
public static JPanel menu = new JPanel();
public static JButton instruct = new JButton("Instructions"), pvp = new JButton("Player VS. Player"), pvc = new JButton("Player VS. Computer");
public static String pOne = "bla", pTwo = "bla";
public static boolean namesEntered = false;
public static JFrame pvpFrame = new JFrame (pOne+" "+"VS."+" "+pTwo);
public static JPanel board = new JPanel (), turns = new JPanel();
public static JLabel turn1 = new JLabel (pOne+" has taken 0 turn(s)."), turn2 = new JLabel (pTwo+" has taken 0 turn(s).");
public static JButton btn1 = new JButton (), btn2 = new JButton (), btn3 = new JButton (), btn4 = new JButton (), btn5 = new JButton (), btn6 = new JButton (), btn7 = new JButton (), btn8 = new JButton (), btn9 = new JButton ();
public static int choice = 3;
public static Font f = new Font("Arial", Font.PLAIN, 40);
public static void main (String[]args)
{
instruct.addActionListener(new Instructions());
pvp.addActionListener(new playerVSPlayer());
pvc.addActionListener(new Action());
menu();
}
public static void menu ()//the main menu of the game
{
menu.setLayout(new FlowLayout());//arranges the layout of the buttons on the panel
menu.add(instruct);//adds the instruction button
menu.add(pvp);//adds the player vs player button
menu.add(pvc);//adds the player vs computer button
menuFrame.add(menu);//creates the panel
menuFrame.setSize(450, 78);
menuFrame.setLocationRelativeTo(null);//sets the location to the centre of the screen
menuFrame.setVisible(true);//makes the menu visible
menuFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//extis program when window is closed
}
public void actionPerformed (ActionEvent e)//detection of the clicked button
{
if (e.getSource().equals(instruct))
{
instructions();
}
else if (e.getSource().equals(pvp))
{
if (e.getSource().equals(btn1))
{
btn1.setFont(f);
btn1.setText("X");
btn1.removeActionListener(new playerVSPlayer());
}
else
{
players();
if (!pOne.equals("0")&&!pTwo.equals("0"))
{
firstTurn();
}
if (namesEntered==true&&choice==1)
{
gameBoard();
btn1.addActionListener(new playerVSPlayer());
}
pvp.removeActionListener(new playerVSPlayer());
}
}
}
public static void instructions ()
{
JFrame frame = new JFrame ("Instructions");
frame.setVisible(true);
frame.setSize(300,145);
JLabel label = new JLabel ("The goal of this game is to be the first player that ");
JLabel label2 = new JLabel ("gets 3 X's or O's in a row diagonally, vertically, or");
JLabel label3 = new JLabel ("horizontally. It is possible to tie, by having all");
JLabel label4 = new JLabel ("spaces played with no spots left to win. Click a");
JLabel label5 = new JLabel ("space to enter your X or O.");
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
frame.add(panel);
panel.add(label);
panel.add(label2);
panel.add(label3);
panel.add(label4);
panel.add(label5);
}
public static void players ()
{
Scanner in = new Scanner (System.in);
System.out.println("Player One, please enter a word no longer than 4 letters, representing your username for this game.");
pOne = in.nextLine();
if (pOne.equals("0"))
{
System.out.println("You have cancelled the match. Please choose an option in the main menu, or close the main menu.");
}
else {
while (pOne.length()>4||pOne.length()<1)
{
System.out.println("Player One, your username MUST be between 1 and 4 letters long.");
pOne = in.nextLine();
}
}
if (!pOne.equals("0"))
{
System.out.println("Player Two, please enter a word no longer than 4 letters, representing your username for this game.");
pTwo = in.nextLine();
if (pTwo.equals("0"))
{
System.out.println("You have cancelled the match. Please choose an option in the main menu, or close the main menu.");
}
else {
while (pTwo.length()>4||pTwo.length()<1)
{
System.out.println("Player Two, your username MUST be between 1 and 4 letters long.");
pTwo = in.nextLine();
}
}
}
if (!pOne.equals("0")&&!pTwo.equals("0"))
{
namesEntered= true;
}
}
public static void gameBoard ()
{
pvpFrame = new JFrame (pOne+" "+"VS."+" "+pTwo);
pvpFrame.setLayout(new GridLayout());
pvpFrame.setVisible(true);
pvpFrame.setSize(600,400);
pvpFrame.setLocationRelativeTo(null);
board.setLayout(new GridLayout(3,3));
turns.setLayout(new FlowLayout());
pvpFrame.add(board);
pvpFrame.add(turns);
turn1 = new JLabel (pOne+" has taken 0 turns.");
turn2 = new JLabel (pTwo+" has taken 0 turns.");
turns.add(turn1);
turns.add(turn2);
board.add(btn1);
board.add(btn2);
board.add(btn3);
board.add(btn4);
board.add(btn5);
board.add(btn6);
board.add(btn7);
board.add(btn8);
board.add(btn9);
}
public static void firstTurn ()
{
Scanner in = new Scanner (System.in);
System.out.println(pOne+" will be X and "+pTwo+" will be O. Enter 1 if you would like to continue. Enter 0 if you would like to cancel this match and return to the main menu.");
choice = in.nextInt();
while (choice!=0&&choice!=1)
{
System.out.println("Your choice did not match 1 or 0. Please enter your choice again.");
choice = in.nextInt();
}
if (choice==0)
{
System.out.println("You have cancelled the match. Please choose an option in the main menu, or close the main menu.");
}
}
}
编辑1:
public void actionPerformed (ActionEvent e)//detection of the clicked button
{
if (e.getSource().equals(instruct))
{
instructions(); // This just runs the instruction panel
}
else if (e.getSource().equals(pvp))
{
if (e.getSource().equals(btn1))
{
btn1.setFont(f);
btn1.setText("X");
btn1.removeActionListener(new playerVSPlayer());
}
else
{
players();
if (!pOne.equals("0")&&!pTwo.equals("0"))
{
firstTurn();
}
if (namesEntered==true&&choice==1)
{
gameBoard();
pvp.setEnabled(false); // my goal here is to make the button no longer usable once the
//game starts, but I also need to make sure later that i can use the button once this game is closed
btn1.addActionListener(new playerVSPlayer());
}
}
}
}
问题是,这不会禁用按钮
答案 0 :(得分:4)
我的代码有几个问题,但就您的问题而言,有两个主要问题:
addActionListener(this)
。话虽如此,我尽量避免使用我的GUI&#34;查看&#34;类实现了监听器接口。setAction(...)
方法交换JButton AbstractActions。将AbstractActions想象为类固醇上的ActionListeners,因为它们可以执行ActionListener可以执行的所有操作,然后执行一些操作。这样做,你不必担心删除以前的听众,因为按钮只能有一个动作。其他问题:
修改强>
是的,如果你重写equals和hashCode以便一个类型的所有监听器都是相同的,那么你可以在你尝试的时候删除它们。
例如,检查此测试代码:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class TestActionListeners extends JPanel {
private JButton button = new JButton("Button");
public TestActionListeners() {
add(button);
button.addActionListener(new Listener1());
}
private static void createAndShowGui() {
TestActionListeners mainPanel = new TestActionListeners();
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.DISPOSE_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();
}
});
}
}
class Listener1 implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("in listener 1");
AbstractButton button = (AbstractButton) e.getSource();
button.removeActionListener(new Listener1());
button.addActionListener(new Listener2());
}
@Override
public boolean equals(Object obj) {
return obj instanceof Listener1;
}
@Override
public int hashCode() {
return Listener1.class.hashCode();
}
}
class Listener2 implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("in listener 2");
AbstractButton button = (AbstractButton) e.getSource();
button.removeActionListener(new Listener2());
button.addActionListener(new Listener1());
}
@Override
public boolean equals(Object obj) {
return obj instanceof Listener2;
}
@Override
public int hashCode() {
return Listener2.class.hashCode();
}
}
话虽如此,我不建议您这样做,而是通过setAction(...)
交换AbstractActions。
编辑2
我不认真读你的问题是个白痴。如果这是你的目标:
我正在努力确保&#34;播放器VS播放器&#34;一旦游戏开始,按钮就会被禁用:
然后,您只需将按钮或其操作设置为禁用即可。即,
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class DisableAButton extends JPanel {
private JButton disableMeButton1 = new JButton("Disable Me 1");
private JButton disableMeButton2 = new JButton(new DisableMe2Action("Disable Me 2"));
public DisableAButton() {
disableMeButton1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
AbstractButton buttonSource = (AbstractButton) e.getSource();
JOptionPane.showMessageDialog(buttonSource, "DisableMe1 ActionListener!");
buttonSource.setEnabled(false);
}
});
add(disableMeButton1);
add(disableMeButton2);
}
private static void createAndShowGui() {
DisableAButton mainPanel = new DisableAButton();
JFrame frame = new JFrame("DisableAButton");
frame.setDefaultCloseOperation(JFrame.DISPOSE_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();
}
});
}
}
class DisableMe2Action extends AbstractAction {
public DisableMe2Action(String name) {
super(name);
}
@Override
public void actionPerformed(ActionEvent e) {
JComponent source = (JComponent) e.getSource();
JOptionPane.showMessageDialog(source, "DisableMe2 Action!");
setEnabled(false);
}
}
答案 1 :(得分:1)
您应该使用相同的实例来调用添加和删除。 因此,将听众存储在一个字段中