Reputation: 27
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);
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
}
Upvotes: 0
Views: 121
Reputation: 347332
Basically this
has no context within a static
method as there is no "this
" available.
Instead, you need to the instance of the class that implements ActionListener
, which, oddly, you never create.
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
.
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...
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
Updated
As pointed out by @peeskillet, there doesn't appear to be an implementation actionPerformed
in your code example. 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...
Upvotes: 1
Reputation: 16308
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();
}
}
Upvotes: 0
Reputation: 5614
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. You have to create an instance of your BingoMain
class, and pass an instance of that class in.
Upvotes: 0
Reputation: 94499
The code should make an instance of BingoMain
. The main
method is static
which means it is not associated with any instance of the class. The keyword static
indicates the method, field, etc is associated with the class itself and not instances of the class. 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.
public static void main (String[] args) {
/* Omitted*/
BingoMain main = new BingoMain();
fileMenu1.addActionListener(main); //NO ERROR!
/* Omitted*/
}
Upvotes: 2