简体   繁体   English

我该如何实现ActionListener?

[英]How Can I implement an ActionListener to this?

I have this code that I am trying to modify in order to add a menu bar with 'file' etc. Adding them has been no issue, adding their listeners is proving to be an issue. 我要修改此代码,以添加带有“文件”等的菜单栏。添加它们已经不是问题,添加其侦听器被证明是一个问题。 Whenever I try to use the syntax fileMenu1.addActionListener(this); 每当我尝试使用语法fileMenu1.addActionListener(this); I get the error "Cannot use this in a static context". 我收到错误消息“无法在静态上下文中使用它”。 Any suggestions? 有什么建议么? I believe I am close to finishing this. 我相信我即将完成这项工作。 This is a multi class program. 这是一个多类程序。 Will put others if needed 如果需要的话会放别人的

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


public class BingoMain extends JFrame implements ActionListener { //I ADDED THE LISTENER HERE

    private static final int ROWS = 5;
    private static final int COLS = 5;
    private static final int MAX_BINGO = 15 * COLS;     //15*5 = 75. Max number of bingo numbers
    private static JMenuItem fileMenu1 = new JMenuItem("Play");
    private static JMenuItem fileMenu2 = new JMenuItem("Quit");
    /**
     * @param args
     *
     */
    public static void main (String[] args)  {

        //Ask for how number of players, take the input, parse it, create that many bingo cards
        String players = JOptionPane.showInputDialog(null, "How many players? (1 to 5 players)");
        int playerNums= Integer.parseInt(players);

        JFrame myBingoGUI=new JFrame(); //frame
        myBingoGUI.setSize(900, 400);
        myBingoGUI.setLocation(100, 100);
        myBingoGUI.setTitle("BINGO");
        myBingoGUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Container myContentPane = myBingoGUI.getContentPane();

        JMenuBar bar = new JMenuBar();  //create menu bar
        JMenu fileMenu = new JMenu("File"); //create the file item in the bar

        bar.add(fileMenu);

        fileMenu.add(fileMenu1);
        fileMenu.add(fileMenu2);
        myBingoGUI.setJMenuBar(bar);

        fileMenu1.addActionListener(this);     //ERROR!
        fileMenu2.addActionListener(this);     //Same error

        myContentPane.setLayout(new GridLayout(0, playerNums));

        BingoCard[] cards = new BingoCard[playerNums];
        for (int i = 0; i < cards.length; i++) {
            cards[i] = new BingoCard("Card " + (i + 1), COLS, ROWS, MAX_BINGO / COLS);
            BingoGUI bingoCard = new BingoGUI();
            cards[i].addListener(bingoCard);
            myContentPane.add(bingoCard);
        }

        myBingoGUI.setVisible(true);

        System.out.println(cards[0]);   //print the cards on the console
        System.out.println();
        /*
         *   Play the game:   
         */
        boolean winner = false;     //default false value for every player
        while (!winner) {
           String error = "";
            int calledValue = -1;
            int calledColumn=-1;
            do {
               String calledNumber = JOptionPane.showInputDialog(null, error + " Enter a BINGO call:");
                error = "";
                calledColumn = -1;
                calledValue = -1;


                /*
                 *   The first character of the input string is converted to a column number between 0 and 4
                 */
                if (Character.toUpperCase(calledNumber.charAt(0))=='B') calledColumn=0;
                if (Character.toUpperCase(calledNumber.charAt(0))=='I') calledColumn=1;
                if (Character.toUpperCase(calledNumber.charAt(0))=='N') calledColumn=2;
                if (Character.toUpperCase(calledNumber.charAt(0))=='G') calledColumn=3;
                if (Character.toUpperCase(calledNumber.charAt(0))=='O') calledColumn=4;
                if (calledColumn < 0) {
                    error = "Called Column '" + Character.toUpperCase(calledNumber.charAt(0)) + "' must be on the BINGO card";      //if first character is not a B, I, N, G, O show message
                } else {    //error catching
                    /*
                     *  The remainder of the input string is converted to an integer
                     */
                    //try catch block to catch any illegal numerical values (A legal column with an illegal value within the range will still be accepted)
                    try {
                        calledValue = Integer.parseInt(calledNumber.substring(1,calledNumber.length()));
                        if (calledValue < 1 || calledValue > MAX_BINGO) {
                            error = "Value not legal " + calledValue + " (1 <= value <= " + MAX_BINGO + ")";    //error if <0 or >75 is input, values dont exist in Bingo
                        }
                    } catch (NumberFormatException nfe) {
                        error = "Illegal number " + calledNumber.substring(1,calledNumber.length());    //error if format is wrong (i.e B9g or N5t) cant mix letters with numbers
                    }
                }
            } while (error.length() != 0);
            /*
             *   The array of called numbers is updated to show the number has been called.
             */
            for (BingoCard card : cards) {
                if (card.called(calledColumn, calledValue)) {       
                    winner = true;
                }
            }
            if (winner) {
                for (BingoCard card : cards) {
                    JOptionPane.showInputDialog(null, "BINGO");
                    card.gameOver();
                }
            }
            System.out.println(cards[0]);
            System.out.println();

        } // while

    } // main

}

The code should make an instance of BingoMain . 该代码应成为BingoMain的实例。 The main method is static which means it is not associated with any instance of the class. main方法是static ,这意味着它不与该类的任何实例关联。 The keyword static indicates the method, field, etc is associated with the class itself and not instances of the class. 关键字static表示方法,字段等与类本身相关联,而不与类的实例相关联。 The code incorrectly assumes that the static main method can refer to an instance of the class itself, which is not possible since its static. 该代码错误地假定static main方法可以引用类本身的实例,这是不可能的,因为它是静态的。

 public static void main (String[] args)  {
        /* Omitted*/
        BingoMain main = new BingoMain();
        fileMenu1.addActionListener(main);     //NO ERROR!

        /* Omitted*/
}

Basically this has no context within a static method as there is no " this " available. 基本上,在static方法中this没有上下文,因为没有“ this ”可用。

Instead, you need to the instance of the class that implements ActionListener , which, oddly, you never create. 相反,您需要实现ActionListener的类的实例,奇怪的是,您从未创建过。

You create a class using... 您使用...创建一个类

public class BingoMain extends JFrame implements ActionListener {...

But you create the main frame using... 但是您使用...创建主框架

JFrame myBingoGUI=new JFrame(); //frame

Which is a better approach, but defeats the purpose of extending from JFrame . 这是一种更好的方法,但无法实现从JFrame扩展的目的。

Instead, I would recommend removing the extends JFrame portion and create an constructor to initialise the main program and then add it to the frame... 相反,我建议删除extends JFrame部分,并创建一个构造函数以初始化主程序,然后将其添加到框架中。

For example... 例如...

public class BingoMain implements ActionListener { //I ADDED THE LISTENER HERE

    private static final int ROWS = 5;
    private static final int COLS = 5;
    private static final int MAX_BINGO = 15 * COLS;     //15*5 = 75. Max number of bingo numbers
    private JMenuItem fileMenu1 = new JMenuItem("Play");
    private JMenuItem fileMenu2 = new JMenuItem("Quit");

    public BingoMain() {

        //Ask for how number of players, take the input, parse it, create that many bingo cards
        String players = JOptionPane.showInputDialog(null, "How many players? (1 to 5 players)");
        int playerNums= Integer.parseInt(players);

        JFrame myBingoGUI=new JFrame(); //frame
        myBingoGUI.setSize(900, 400);
        myBingoGUI.setLocation(100, 100);
        myBingoGUI.setTitle("BINGO");
        myBingoGUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Container myContentPane = myBingoGUI.getContentPane();

        JMenuBar bar = new JMenuBar();  //create menu bar
        JMenu fileMenu = new JMenu("File"); //create the file item in the bar

        bar.add(fileMenu);

        fileMenu.add(fileMenu1);
        fileMenu.add(fileMenu2);
        myBingoGUI.setJMenuBar(bar);

        fileMenu1.addActionListener(this);     //ERROR!
        fileMenu2.addActionListener(this);     //Same error
        //...
    }

    /**
     * @param args
     *
     */
    public static void main (String[] args)  {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                BingoMain main = new BingoMain();
            }
        });

    } // main

}

Try and avoid static variables where you might want to use multiple instances of the variables 在可能要使用多个变量实例的地方,尝试避免使用static变量

Updated 更新

As pointed out by @peeskillet, there doesn't appear to be an implementation actionPerformed in your code example. 正如@peeskillet指出的那样,您的代码示例中似乎没有执行actionPerformed This could simply be an oversight on your part, or the next problem you will incur... 这可能只是您的疏忽,否则将引发下一个问题。

Make sure you add 确保您添加

@Override
public void actionPerformed(ActionEvent evt) {
}

To your class and import java.event.ActionEvent to your imports as well... 对于您的类,也import java.event.ActionEvent到您的导入中...

    fileMenu1.addActionListener(this);     //ERROR!
    fileMenu2.addActionListener(this);     //Same error

The main method is a static method, and there is no this in a static context. main方法是静态方法,在静态上下文中没有this方法。 You have to create an instance of your BingoMain class, and pass an instance of that class in. 您必须创建BingoMain类的实例,然后传入该类的实例。

You should probably build your interface in the constructor of the class like: 您可能应该在类的构造函数中构建接口,例如:

public class BingoMain extends JFrame implements ActionListener {
    public BingoMain() {
        // code to build your UI 
        fileMenu1.addActionListener(this);
        // some more code
    }

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM