Search code examples
javajavafxgridpane

Getting X and Y values of a gridpane with HBoxes in every row


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());
        
    }
    
}

Solution

  • 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+"]");
    });