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
}
Related
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:
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.
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.
I'm missing something fundamental here but I can't seem to find out what from all my research.
I have imported a csv file, split the string into floats, and now wish to connect all points to all other points with a line. My code is as follows:
String [] data;
void setup () {
size(300, 300);
background(255);
data = loadStrings("points.csv");
for (int i = 0; i < data.length; i++) {
String [] fields = split(data[i], ',');
float t = float(fields[0]);
float n = float(fields[1]);
float x = float(fields[2]);
float y = float(fields[3]);
ellipse(x, y, 10, 10);
line(x, y, x[i], y[i]);
}
}
The error message is "The type of expression must be an array type but it resolved to float"
I'm sure this is extremely basic but, I dont understand why x[i] or y[i] are not seen as an array type.
I would really appreciate any help with this. Many thanks in advance.
Sam
*UPDATE***
An exract from the points.csv file is as follows:
219185750 rabih_takkoush 20.88521 19.49821
219185716 MoustaphaAjram 100.870896 59.515259
219185709 jinanejghosh 56.886441 35.489087
219185557 MoustaphaAjram 34.870904 78.515243
219185555 Mohammad8Itani 12.8946 49.48179
What I am trying to accomplish is plotting the various geolocations (whereby col 3 = x, col 4 = y) and then connecting all points with all other points with a line.
The following script works plotting all locations specified in the array within the script:
float[] x = { 50, 100, 150, 200,20,20 };
float[] y = { 10, 30, 20, 250,20,90 };
void setup () {
size(300, 300);
background(255);
}
void draw() {
for (int i = 0; i < x.length; i++) {
ellipse(x[i], y[i], 10, 10);
for (int j = 0; j < x.length; j++) {
line(x[j], y[j], x[i], y[i]);
}
}
}
What I wish to do is do the same, but reading columns 3 and 4 of the csv file.
You're splitting your data into iteration-scoped floats, then you try to access them as if they're both floats as well as arrays in your line() call. Try this:
String[] data;
float[] x, y, t, n;
void setup () {
size(300, 300);
data = loadStrings("points.csv");
int len = data.length;
x = new float[len];
x = new float[len];
t = new float[len];
n = new float[len];
for (int i=0; i<len; i++) {
String line = data[i];
String[] fields = split(line, ',');
t[i] = float(fields[0]),
n[i] = float(fields[1]),
x[i] = float(fields[2]),
y[i] = float(fields[3]);
}
// don't put draw instructions in setup,
// put them in draw. if you want to run once,
// issue a noLoop() so that happens.
noLoop();
}
void draw() {
float prevx = x[0], prevy = y[0];
for (int i=0, last=x.length; i<last; i++) {
ellipse(x[i], y[i], 10, 10);
line(prevx,prevy, x[i],y[i]);
prevx=x[i];
prevy=y[i];
}
}
Now we're storing the data from CVS in linked arrays that we can access throughout the sketch, rather than throwing them away after setup().
ok so if you go with the first code you made, you only need to change a few things, here is what you can do:
float[] x;
float[] y;
string[] data;
void setup () {
size(300, 300);
background(255);
data = loadStrings("points.csv");
x = new float[data.length];
y = new float[data.length];
for (int i = 0; i < data.length; i++) {
String [] fields = split(data[i], ',');
float t = float(fields[0]);
float n = float(fields[1]);
float x = float(fields[2]);
float y = float(fields[3]);
}
}
void draw() {
for (int i = 0; i < x.length; i++) {
ellipse(x[i], y[i], 10, 10);
for (int j = 0; j < x.length; j++) {
line(x[j], y[j], x[i], y[i]);
}
}
}
As you can see nothing really new, it's a mix between your initial code and the one you made for the csv.
And actually you mainly needed to declare your x and y variables as float[] instead of just float. But also there were some changes to make in the loop.
In this code you load the data in your arrays first (exactly like you did by declaring array's values in your code, but this time you read these values from your file), and then call your draw method as before.
hope it works now
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.