In my applet program I have the TextField declared in my public class header as:
TextField numbers [][] = new TextField[5][5];
I also have a button that is supposed to clear all the textboxes when clicked.
Right now I basically have this:
JButton b = new JButton("Clear");
b.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
numbers.setText("");
}
});
But I'm getting an error: "Cannot invoke setText(null) on the array type TextField[][]"
How can I fix this?
Key lesson here: read the error message critically as it is telling you exactly what is wrong.
"Cannot invoke setText(null) on the array type TextField[][]"
You're treating the numbers variable as if it's a single TextField and it's not, and so you can't call setText(...) on it -- rather it's a 2D array of objects. A solution is to think of how you interact with any similar 2-d array, how do you call methods on each item held within the array: use nested for loops to iterate through the array.
for (int i = 0; i < numbers.length; i++) {
for (int j = 0; j < numbers[i].length; j++) {
numbers[i][j].setText("");
}
}
Also, change TextField to JTextField so that you're using all Swing components:
// change type from TextField to JTextField
JTextField numbers [][] = new JTextField[5][5];
Related
I am trying to give each JButton from a 10 x 10 button layout (so 100 buttons) each unique name or ID or number so I can call them later. I made an ArrayList because that's what some other person did.
public ArrayList<JButton> myList;
//Some other code
for(int row = 0; row < 10; row++)
{
for(int col = 0; col < 10; col++)
{
button = new JButton();
button.addActionListener( al );
myList.add(button);
for(JButton button : myList)
button.setText("");
panel_1.add(button);
}
}
The program compiles but it doesn't run. It's showing error at
myList.add(button);
It's a null pointer exception apparently.
but I don't know why. Is it not adding the buttons to the ArrayList? Also how do I give each button a unique name or string?
The program compiles but it doesn't run. It's showing error at
The ArrayList is null because you didn't create an ArrayList object.
The code should be:
private ArrayList<JButton> myList = new ArrayList<JButton>();
Also how do I give each button a unique name or string?
There is no need to give the button a unique name. Its unique name is the "index" used to access the JButton in the ArrayList.
You probably don't even need the ArrayList.
Normally you add an ActionListener to the button. Then you can just use the getSource() method of the ActionEvent to get the reference to the button.
I would like to create a minesweeper game. Firstly, this will work on buttons. I think I will work on two dimensional array, and there will be like boolean array that will present where are bombs, for example if booleanArray[0][4] is true, there is a bomb.
Now, how can I implement this in my buttons? I can set Names on these buttons, and then if I click some button, then I will get the name from this div. For example when i click first button, i will get "00" name, then i will get first letter "0" and second letter "0" and parse it to int. And this will be the indexes from my previous booleanArray, in this case it will be booleanArray[0][0].
So, can I do this another, better way, instead of that?
This is the way I will be creating the buttons:
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
JButton button = new JButton("");
button.setPreferredSize(new Dimension(50, 50));
button.setName(Integer.toString(i) + Integer.toString(j));
}
}
EDIT
I will have a two dimensional Array, that will reflect my buttons:
and now, how can I check if I hit the bomb after I click for example in the first button?
Just hold a two dimensional array of buttons,
JButton[][] myButtons = new JButton[10][10];
which you use to draw them and they all call the same method with their value
for (int x=0; x<10; x++){
for (int y=0; y<10; y++){
myButtons[x][y] = new JButton("0");
//add to page, or do it elsewhere
myButtons[x][y].addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
selectionButtonPressed(x,y);
}
});
}
}
Then a call to yout method selectionButtonPressed() will tell you what button has been pressed, you can take action and even make changes to the button with myButtons[x][y].whatever()
That is one way but you should create the String of the name by using something like:
button.setName(i + ":" j);
This will make it easier to parse out the two values as you can just use the String.split(...) method.
Another option might be to create a HashTable with the JButton as the key and then use a Point object (representing the row/column) as the value Object of the HashTable. Then you just use the get(...) method of the HashMap to retrieve the Point for the clicked button.
Another option is to extend JButton and add two parameters (row, column) when creating the button. Then you also add getRow() and getColumn() methods.
Either of this approaches will keep the logic simple and you only need to create a single ActionListener to be used by all the buttons.
So I have numbered JLabels declared like so (In the class)
OP_1
OP_2
OP_3
etc..
And I have a number and a string.
What I want is that when, for example, the number is 2. I want to change the label text to the content of the string. This is part of a method that is supposed to take a string, put it into the last available JLabel, and then increment the number.
I am very confused, and help would be appreciated.
Here I created an array of JLabels and a method, updateNextLabel(String), which will update the next JLabel with whatever you enter for str.
public class Example {
static int count = 0; //Create a count
static JLabel[] array = new JLabel[3]; //Create an array to hold all three JLabels
public static void main(String[] args) {
//Set the default text for each JLabel
array[0] = new JLabel("This is OP1");
array[1] = new JLabel("This is OP2");
array[2] = new JLabel("This is OP3");
//Here is an example if you wanted to use a for-loop to update the JLabels
for (int x = 0; x < array.length; x++) {
updateNextLabel("This is the new text for OP" + (count + 1));
System.out.println(array[x].getText());
}
}
public static void updateNextLabel(String str) {
array[count].setText(str);
count++;
}
}
Instead of / additional to naming your labels by specific names you can later match them on, I'd think a Map of JLabels with Strings or Integers as keys might be a better approach:
Map<String,JLabel> labelMap = new HashMap<String,JLabel>();
labelMap.put("1", OP_1);
labelMap.put("2", OP_2);
This will allow later access of "The label for key 2" as well as "list me all that labels and find the one with text 2" as well
I'm trying to make randomized JTextField's yellow by using Arrays. I've only managed to make 1 textfield yellow, and then white after 1 sec at each click. What I want to do is when you press the button the first randomized Textfield get yellow and then white. And when you press the second time the first randomzied textfield AND the seconds will turn yellow and then White and so on.. The array works as you can see I Printing it and when you press the button it prints all the randomized numbers in order.
The problem is that JTextField can't handle int's, and it apparently have to be "Final" so it makes it very hard to make multiply JTextField's yellow. I pasted my arrays to you so that you can get a better understanding what I'm trying to do. Does anyone know the solution?
//my Arrays
JTextField[] boxes = new JTextField[9]; //Array for the textfields
int[] clicked = new int[100];
int clickAmount = 0;
//At startup it fills the boxes array with the textfield:
boxes[0] = textfield1;
boxes[1] = textfield2;
boxes[2] = textfield3;
boxes[3] = textfield4;
boxes[4] = textfield5;
boxes[5] = textfield6;
boxes[6] = textfield7;
boxes[7] = textfield8;
boxes[8] = textfield9;
public void timePaus (final JTextField textfield) {
new Timer(1000, new ActionListener() {
public void actionPerformed (ActionEvent e) {
textfield.setBackground(Color.white);
// stop the timer
((Timer) e.getSource()).stop();
}
}).start();
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { //Button
int randomint = this.randomBox(); //Finds a number between 0-8
final JTextField ThatTextfield = boxes[randomint]; //Puts a textfield into an array
clicked[clickAmount] = randomint+1; //adds textfield number into an array
clickAmount++;
ThatTextfield.setBackground(Color.yellow); //make choosen textfield yellow
for (int i = 0; i < clickAmount; i++)
{
timePaus(ThatTextfield); //make choosen textfield white after 1 sec
System.out.println(clicked[i]);
}
}
Considerations:
Place your JTextFields in an ArrayList<JTextField>, but create them in a for loop for the sake of avoiding unnecessary repetation.
When you want to randomize the ArrayList, call Collections.shuffle(myTextFieldList) on your List of JTextFields.
Give your class an int maxIndex field.
In your Swing timer, iterate through the now randomized List of JTextFields, displaying each one up to the value held by the maxIndex and not above the size of the List.
Increment the maxIndex in the timer.
Alternatively, you could create two more ArrayList<JTextField>, one to shuffle the collected text fields. Then remove the 0th JTextField from this list in your button's listener, and place it into the other ArrayList, and then iterate through the 2nd ArrayList's JTextfield in your Timer.
I'm having a little trouble building the grids for a Battleship game for my Java class. So far, I can easily make a for loop to add JPanel or JButton objects to the JFrame. However, my issue is that I'll need to use those Panels or Buttons again when playing the game (such as clicking on a button to see if your opponent put a ship on that square, et cetera). Is there a simple way in Java to initialize reference variables for a LOT of objects? Or will I have to declare all of them individually?
You could try a multi dimensional array of JPanels (or any other object). Create an array with the same size as your grid. The line below initializes an array with 5 rows and 5 columns.
JPanel[][] battleField = new JPanel[5][5];
Use nested for loops to create the panels in the array.
for (int rowIndex = 0; rowIndex < battleField.length; rowIndex++)
{
for (int cellIndex = 0; cellIndex < battleField[rowIndex]; cellIndex++)
{
battleField[rowIndex][cellIndex] = new JPanel();
}
}
If you want to reference the battleField array later on you would just make it into a instance variable.
For a battleship game, you most likely want to retrieve the location of a button after is has been clicked. You can create a hashtable using your buttons as keys and the point it is located at as a value.
HashMap<JButton, Point> buttonMap = new HashMap<JButton, Point>();
for (int x = 0; x < COLUMNS; x++)
{
for (int y = 0; y < ROWS; y++)
{
JButton btn = new JButton();
btn.addActionListener(this);
buttonMap.put(btn, new Point(x, y));
//then add the button to your container
}
}
The in your actionPerformed method you can convert the button to the point it is located at like this.
JButton btn = (JButton)actionEvent.getSource();
Point p = buttonMake.get(btn);
Of course you will need to properly handle error conditions such as source not being a button or the button not being in the map...
You can always extend JButton to keep track of the info you need. A simple example:
class MyButton extends JButton{
private MyGameInfo mygameInfo;
private int buttonId;
//More fields....
//Getters/Setters
}
Then instead of creating and adding JButton objects to your layout, create MyButton objects(which is also a JButton so your layout will not be effected) and use its extra functionality for your game logic.
For reference, here is a related matching game that uses a grid of buttons. This related answer demonstrates the application of the Model–View–Controller pattern to a simple game.