-1

I have a script in JavaFX where I need to get the X and Y or the Row and Col values of a GridPane. Each grid has a HBox and the size of the HBox always varies as there are a random number of shapes in each HBox. I need to be able to get the value of the shapes in the HBox when I click on that specific grid. I tried setting each row and col to the event handler but that doesn't seem to work. Are there any easier ways to get each row and column value than manually adding the width of each HBox to the left of the cursor?

Here is my current code and output. (I added two images to show what I mean by random shapes in each HBox.)

Example Imagre 1:

enter image description here

Example Image 2: enter image description here

Thank you in advance.

//Circle objects, add them inside the circleArrary
for(col = 0; col < NUM_COL; col++) {
    for(row = 0; row < NUM_ROW; row++) {
        cardNum = queue.peek().getNumber();
        p = queue.peek().getPattern();
        colr = queue.peek().getColor();
        sh = queue.peek().getShape();
        attr = new DetermineCardAttributes(colr, p, sh);
        cards[col][row] = new HBox();
        cards[col][row].setSpacing(10);
        cards[col][row].setPadding(new Insets(10, 10, 10, 10));

        for(int i = 0; i < cardNum; i++) {
            inner = new Circle(30);
            inner.setFill(Color.WHITE);
            inner2 = new Circle(20);
            inner2.setFill(attr.getColor(colr));
            inner3 = new Circle(10);
            inner3.setFill(Color.WHITE);
            if(sh.equalsIgnoreCase("circle")) {
                inner.setRadius(50);
                inner2.setRadius(40);
                inner3.setRadius(30);
            }
            shape2 = attr.getShape(sh);
            shape2.setStrokeWidth(width);
            shape2.setLayoutX(3);
            shape2.setLayoutY(3);
            shape2.setStroke(attr.getColor(colr));
            shape2.setFill(attr.getFill(p));
            stack = new StackPane();
            if(!p.equalsIgnoreCase("stripe")) {
                cards[col][row].getChildren().addAll(shape2);
                holderCards[col][row] = queue.peek();
            } else {
                stack.getChildren().addAll(shape2,inner,inner2,inner3);
                cards[col][row].getChildren().addAll(stack);
                holderCards[col][row] = queue.peek();
            }
            cards[col][row].setAlignment(Pos.CENTER);
            cards[col][row].setOnMouseDragged(new MouseHandler());
        }
        canvas.add(cards[col][row], col, row);
        queue.poll();
    }
}
 private class MouseHandler implements EventHandler<MouseEvent>
{
    public void handle(MouseEvent event)
    {
        System.out.println(event.getX());
        
    }
    
}
apex
  • 37
  • 7
  • What do you actually mean *"get the row or col values"*? The variables `row` and `col` contain those values. – James_D Jul 01 '21 at 18:11
  • Hi james. I mean like the index of that each hbox is in so lets say its a 3x3 gridpane with an hbox in each grid. If my mouse is over the top left one I would like to get the 0,0 and then 1,0 for the next box, etc – apex Jul 01 '21 at 20:46
  • But you already have those values in the `row` and `col` variables in your loop. What more do you need? – James_D Jul 01 '21 at 20:47
  • Well the mouse handler function would have to return the value that the cursor is in and I'm not quite sure how to do that. In previous projects it was simple because each item in each grid was a set width or diameter but this is throwing me because I know the row and col have it but how to say which row and col the mouse is in – apex Jul 01 '21 at 20:58
  • Why don't you just pass the `row` and `col` to the mouse handler when you create it? It's really hard to understand what the problem is. – James_D Jul 01 '21 at 20:59
  • Actually I am still having trouble, what do you mean pass row and col to the handler. I need to figure out which row and col the cursor is in so Im not sure how passing the row and col to the handler would help – apex Jul 02 '21 at 00:49
  • I assume you need that information in the handler, no? So you have access to it when you handle the drag event. If that's not what you mean, you need to explain more clearly what you are trying to do. – James_D Jul 02 '21 at 01:12
  • Im trying to make it so that on the action of my mouse being clicked it will return the row and column of the grid that my mouse has clicked on. Lets say I click on a cell with the two circles in it, I want the mouse to return the row and column of that cell so that I can figure out what the attributes of that cell is – apex Jul 02 '21 at 01:57
  • I don’t understand what you mean by “return the row and column”. Handler methods are void - they don’t return anything (and you don’t call them anyway, so you’d never have access to a return value). If you just want the handler to have access to those values, what’s wrong with what I suggested - just pass the row and column to the handler. – James_D Jul 02 '21 at 02:07
  • Maybe if you post your handler class it would be clearer what you mean. – James_D Jul 02 '21 at 02:07
  • Ok I posted the handler class, If you would like I can also post an example of my handler class on a project I did before that got the row and col of each cell which contained a circle. This was easy because each row and col was as set width and never changed – apex Jul 02 '21 at 02:18
  • But what’s the problem with doing what I described? – James_D Jul 02 '21 at 02:22
  • Thank You very much, sorry I was just having trouble figuring out what you were describing. Personally I have never used a constructor inside a handler class so I was a little bit confused – apex Jul 02 '21 at 03:57

1 Answers1

0

I think I must be misunderstanding the question. Doesn't this do what you need?

private class MouseHandler implements EventHandler<MouseEvent> {

    private final int row ;
    private final int column ;

    MouseHandler(int column, int row) {
        this.row = row ;
        this.column = column ;
    }

    public void handle(MouseEvent event) {
        System.out.println("["+column+", "+row+"]");
    }
    
}

and

cards[col][row].setOnMouseDragged(new MouseHandler(col, row));

You can do the same with lambda expressions; you just need to make final copies of the variables:

final int r = row ;
final int c = col ;
cards[col][row].setOnMouseDragged(event -> {
    System.out.println("["+c+", "+r+"]");
});
James_D
  • 201,275
  • 16
  • 291
  • 322
  • This worked, I was confused because I never used a constructor in the handler class but thank you very much – apex Jul 02 '21 at 03:58