JavaFX Array of Buttons that Dissapear when clicked - arrays

We're trying to make an array of buttons that will dissappear when theyre clicked on. The problem is that we get an out of bounds error no matter which button we click on. If we click button(1,3) we would like just that button to dissappear (by using the remove function).
This is our current code:
public class Main extends Application {
public static void main(String[] args) {
System.out.println("Start of JavaFX");
launch(args);
System.out.println("End of JavaFX");
}
//--module-path "/Users/jonathan/Documents/JavaFX/javafx-sdk-15.0.1/lib" --add-modules
javafx.controls,javafx.fxml
private int width = 10;
private int height = 10;
private int i;
private int j;
private StackPane[][] stk = new StackPane[width][height];
Button[][] button = new Button[width][height];
Label[][] lbl = new Label[width][height];
#Override public void start(Stage primaryStage) {
GridPane gridPane = new GridPane();
for (i = 0 ; i <= width-1 ; i++) {
for (j = 0 ; j <= height-1 ; j++) {
//System.out.println(i + "," + j);
button[i][j] = new Button();
lbl[i][j] = new Label();
button[i][j].setText("B");
lbl[i][j].setText("X");
stk[i][j] = new StackPane(lbl[i][j],button[i][j]);
gridPane.add(stk[i][j], i, j, 1, 1);
button[i][j].setOnAction(e -> buttonClick(i,j));
}
}
Scene scene = new Scene(gridPane);
primaryStage.setScene(scene);
primaryStage.show();
}
public void buttonClick(int i, int j) {
System.out.println(i + "," + j);
stk[i][j].getChildren().remove(button[i][j]);
}
}

The problem is you probably deliberately bypassed the warning "variable used in lambda expression should be final or effectively final" in the for-loop when directly creating the variable in it. Making it final above this loop caused the problem.
Now the i and j index just keeps changing until your last iteration in the for-loop (which is 10, 10). Every button uses that same variables, instead of creating a new independent variable for each individual button.
The solution is to create a new (final) variable for each button:
Code (notice how you now can create the variables "i" and "j" in the for-loop):
for (int i = 0 ; i <= width-1 ; i++) {
for (int j = 0 ; j <= height-1 ; j++) {
button[i][j] = new Button();
lbl[i][j] = new Label();
button[i][j].setText("B");
lbl[i][j].setText("X");
stk[i][j] = new StackPane(lbl[i][j],button[i][j]);
final int indexI = i; // _SOLUTION_
final int indexJ = j; // _SOLUTION_
gridPane.add(stk[i][j], i, j, 1, 1);
button[i][j].setOnAction(e -> buttonClick(indexI,indexJ)); // _SOLUTION_
}
}
Running the application:
Output when clicking a few buttons, notice how "10,10" is no longer printed:

Related

How can I check for equality within a row, amongst all indexes?

I'm lost and don't know where to begin. I'm testing the following condition, L=W=H on Package1's method and I want to call it into the Class Runtime's main method.
I created an array of objects already. But after that, I don't know how to utilize it or even if I have to. Again I'm completely lost!...thanks for your help.
I feel as if Coding is a young man's world!, Damn you Marine Corps!
public class Package1
{
double length;
double width;
double height;
Package1(double a,double b, double c)
{
length=a;
width=b;
height=c;
}
public void isCube()
{
if(length==width && width==height)
System.out.println("The box is a cube.");
else
System.out.println("Box is not a cube. ");
}
public class Runtime{
public static void main(String[] args){
Package1[] boxes = new Package1[rows];
for(int j = 0; j < boxes.length; j++)
{
boxes[j] = new Package1(arr[j][0], arr[j][1], arr[j][2]);
}
}
}
Like this.
for(int j = 0; j < boxes.length; j++)
{
boxes[j] = new Package1(arr[j][0], arr[j][1], arr[j][2]);
boxes[j].isCube(); // this is the line that you need
}
Any element in an array can be accessed by passing the index of the item into the brackets. For instance boxes[0] is the first element in the array. boxes[ boxes.length - 1 ] is the last element in the array.

get position of 2D array of JLabels

First post here but long time reader, been searching through but cant find a post that exactly helps my problem.
I am trying to create 2D grid of JLabels with mouselisteners and retrieve the X / Y position of the clicked JLabel but cant find a way to do it. I have tried a few ways I found out on this site but nothing is working.
currently I have the following....
pcenter.setLayout(new GridLayout(game.getXSize(), game.getYSize()));
pcenter.setBorder(new EmptyBorder(8,8,8,8));
pcenter.setPreferredSize(new Dimension((game.getXSize() * 30), (game.getYSize() * 30)));
gamegrid = new JLabel[game.getXSize()][game.getYSize()];
for ( int i = 0; i < game.getXSize(); i++) {
for (int j = 0; j < game.getYSize(); j++) {
gamegrid[i][j] = new JLabel();
gamegrid[i][j].setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
gamegrid[i][j].addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
}
});
pcenter.add(gamegrid[i][j]);
}
}
'game' is an object that houses a 2D array of objects for which i want to pass in the same co-ordinates of the JLabel clicked. E.G clicking on gamegrid[2][5] will contact game.plots[2][5].
whenever i try and make a variable to store 2 and 5 it wants to make the method FINAL, and if I put the method inside the MouseAdapter() it wants to make 'i' or 'j' FINAL.
please help :) thanks in advance.
Just figured it out! I'll post here just encase someone else would like to know.
I created 3 other variables in the class:
private static Object source;
private static int currentX, currentY;
then the current MouseListener, where it is now, I added the following:
for ( int i = 0; i < game.getXSize(); i++) {
for (int j = 0; j < game.getYSize(); j++) {
gamegrid[i][j] = new JLabel();
gamegrid[i][j].setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
gamegrid[i][j].addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
source = e.getSource(); //added this to get the mouseevent object.
XYsource(); // this is a method to turn the object source
into X and Y coords.
}
});
pcenter.add(gamegrid[i][j]);
}
}
and finally the following method to turn the Object source into the X and Y co-ordinates
public static void XYsource() {
int maxX = game.getXSize();
int maxY = game.getYSize();
for(int i = 0; i < maxX; i++) {
for(int j = 0; j < maxY; j++){
if (gamegrid[i][j] == source) {
currentX = i;
currentY = j;
}
}
}
updateXY(); // this is just a method to set text on the screen showing
the X and Y coordinates to test the MouseListener
}

Array of text don't fade out until the last one is appended

I want to make a group of array fade out until the last array in this group was appended. for example, I use append to create zoog[0], zoog[1], zoog[2], and I want these three objects not fadeout until zoog[2] is created and wait for a second, the same situation with zoog[3], zoog[4],zoog[5], these three objects don't fadeout until zoog[5] is created. But now what I can do is make each object fadeout as soon as it is created.
Zoog[]zoog = new Zoog[1];
float count=0;
int xpos =0;
int ypos =0;
String message="haha";
int ntextsize = 20;
int nopacity =200;
int thistime = 0;
int thiscount = 0;
//Zoog zoog;
void setup() {
size(400, 400);
xpos = int(random(width/2-200, width/2+40));
ypos = int(random(height/2, height/2-40));
zoog[0] = new Zoog(xpos,ypos,message,nopacity);
}
void draw(){
background(255,255,255);
for(int i=0; i<zoog.length; i++){
// if(millis()-thistime>4000){
// zoog[i].disappear();
// }
zoog[i].jiggle();
zoog[i].display();
}
}
void mousePressed(){
count = count + 1;
// int thiscount = 0;
if(count%3 ==0){
xpos=int(random(30, width-30));
ypos=int(random(10, height-10));
}
else{
ypos = ypos+50;
// thiscount = thiscount +1;
// thistime = millis();
// }
}
nopacity = int(random(100,255));
// text(message, xpos, ypos);
Zoog b = new Zoog(xpos,ypos,message,nopacity);
zoog =(Zoog[]) append(zoog,b);
}
Zoog class
class Zoog {
int x;
int y;
String thatmessage;
int opaci =0;
Zoog(int xpo, int ypo, String thismessage, int opa) {
x = xpo;
y = ypo;
thatmessage = thismessage;
opaci = opa;
}
void jiggle() {
x = x+int(random(-2, 2));
y = y+int(random(-2, 2));
}
void display() {
fill(0, opaci);
text(thatmessage, x, y);
print("x position is "+ x);
print("y position is "+y);
}
void disappear() {
for (int j=0; j<255; j++) {
opaci = opaci -j;
}
}
}
If I understand correctly you want to make 3 zoogs and then start fading those three out until they're gone. If this is correct there are a couple of ways I'd go about doing this.
First, I wouldn't use an array especially if you're dynamically updating the amount inside it. If you want to do that I'd use, arraylists. Here's the javadocs reference. Basically you'd initialize an arraylist of Zoogs and put the zoog.add(new Zoog...) in the mousepressed. The good thing about arraylists is that they have a number of member functions that can help you manipulate them. For instance, you can check the size of the arraylist in your draw function instead of the time. Once you're above 3 start fading the first 3 out until they're dead (using a Zoog member function to say they're dead). You can check that "isDead" member function in your draw loop and remove the correct dead Zoog while in your for loop.
Here's a rough implementation, assuming you created an isDead function in your Zoog class that just returns whether the opacity is greater than 0:
void Draw()
{
for (Zoog zoog : zoogs) //for each statement simplifying the code -
//says for each Zoog in zoogs do
{
zoog.jiggle();
zoog.display();
}
if(zoogs.size() >= 3) {
for(int i = 0; i < 3; i++) {
zoogs.get(i).disappear();
}
}
if (zoogs.get(0).isDead() && zoogs.get(1).isDead() && zoogs.get(2).isDead()) {
zoogs.remove(2);
zoogs.remove(1);
zoogs.remove(0);
}
}
This is by no means a perfect example but it shows how to remove 3 zoogs at a time by lessening their opacity and checking whether they are dead. If you're clicking a million times then it will take a while for each chain of three to die.

Array displaying images, need to make another method that takes a paramter NUM to order how many pictures are shown

I explained that horridly in the title, and I apologize, am very new to java and don't quite understand some of it yet.
Anyway,
My cat animation runs to the middle of the screen, scratches twice, then continues to run to the end, is there anyway to write a method that will take an INT NUM and make the cat scratch x amount of times? Not sure how to go about doing this.
Any help would be much appreciated
Here is my current code
/** Run the animation. */
public void nekoRun() {
moveIn();
scratch();
//scratch2(5);
moveOut();
}
/* Move Neko to the centre of the panel. */
private void moveIn() {
for (int i = 0; i < getWidth()/2; i+=10) {
xPos = i;
// swap images
if (currentImage == nekoPics[0])
currentImage = nekoPics[1];
else
currentImage = nekoPics[0];
repaint();
pause(150);
}
}
//neko stops and scratches in the middle of the panel twice
private void scratch() {
for (int i = 0; i < 10; i++) {
// Swap images.
currentImageIndex = nextImageList[currentImageIndex];
currentImage = nekoPics[currentImageIndex];
repaint();
pause(150);
}
}
//Neko runs to the end of the panel
private void moveOut() {
for (int i = xPos; i < getWidth(); i+=10) {
xPos = i;
// swap images
if (currentImage == nekoPics[0])
currentImage = nekoPics[1];
else
currentImage = nekoPics[0];
repaint();
pause(150);
}
}

NPC movement in the array

I am doing a an array game, below is my Board class, which paints the array and spawns 5 hunters at 11,11, my 'route1' method should be the one to move hunters around whenever the player moves, however my hunter.x and hunter.y stay 11 after each re-paint, how do I fix this?
public class Board {
public String emptyfield = "-";
public String [][]a2 = new String[12][12];
public Hunter hunters[] = new Hunter[5];
public void paint(){
int numHunters =5 ;
for (int i =0; i < numHunters; i ++){
hunters[i] = new Hunter(11,11,"H");
}
Player player = new Player();
for (int r = 0 ; r < a2.length; r++){
for (int c= 0; c <a2[r].length; c++){
a2 [r][c] = emptyfield;
a2[Player.x][Player.y] = Player.name;
for (int i = 0; i < numHunters; i++){
Hunter h = hunters[i];
a2[h.x][h.y]=h.name;
}
System.out.print(" "+a2[r][c]);
}
System.out.println("");
}
System.out.println(" Strength: "+Player.hp);System.out.println(" Score "+Player.score);
}
public void route1(){
Board board = new Board();
Hunter Hunter = new Hunter(11,11,"H");
Scanner in = new Scanner(System.in);
Random number = new Random(2);
int random = number.nextInt(2);
if(random ==1)
Hunter.x = Hunter.x -1;
else
Hunter.y = Hunter.y -1;
}
If I read this correctly, you are recreating all your hunters at position 11,11 each time you call paint.
public void paint(){
int numHunters =5 ;
for (int i =0; i < numHunters; i ++)
{
hunters[i] = new Hunter(11,11,"H");
}
This code is replacing your array of hunters each time paint is called, erasing any changes made later on in code. You need to move (new Hunter(11,11,"H") to somewhere that is only called once.

Resources