[英]Using removeActionListener but not removing - JAVA
我已经创建了Tic-Tac-Toe游戏的一部分,并且我试图确保一旦开始游戏,“ Player VS Player”按钮将被禁用。 我对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());
}
}
}
}
问题是,这不会禁用按钮
我的代码有几个问题,但是就您的问题而言,有两个主要问题:
addActionListener(this)
。 话虽如此,我试图避免使我的GUI“视图”类实现侦听器接口。 setAction(...)
方法交换JButton AbstractActions。 可以将AbstractAction视为类固醇上的ActionListener,因为它们可以执行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
我是个白痴,没有认真阅读您的问题。 如果这是您的目标:
并且我正在尝试确保在游戏开始后禁用“玩家VS玩家”按钮:
然后,您所需要做的就是设置按钮或禁用其“操作” 。 即
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);
}
}
您应该使用同一实例来调用添加和删除。 因此将听众存储在一个字段中
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.