2017-04-22 28 views
0

我試圖用可拖動的棋子實現一個棋盤,如下所示。但是,我無法保持該片段被拖拽到其他節點的前面或下方。左和上似乎工作正常。如何將節點拖放到其他人面前(JavaFX 8)?

我試圖通過聲明StackPane第一個形成格子背景和所有之後纔是段解決這個問題,因爲我讀爪哇分配其中Node s的添加到其Parent基於該順序的z索引秒。這種方法如下所示。我也嘗試創建一個Group並將其添加到StackPaneImageView以便能夠使用toFront()。僅導致顯示的座標標籤。

我該如何實現功能?

這個方法創建了板:

public Parent chessBoard() { 
    GridPane board = new GridPane(); 
    StackPane[][] cells = new StackPane[8][8]; 

    // Create the board first 
    // (For dragging pieces to work correctly, draggable pieces must be 
    // added after the whole board, since z-index cannot be set explicitly 
    // in JavaFX. 
    for (int row = 0; row < 10; row++) { 
     for (int col = 0; col < 10; col++) { 
      // x and y in chess coordinate system (0-indexed) 
      int[] invertedY = {-1,7,6,5,4,3,2,1,0,-1}; 
      int x = col - 1; 
      int y = invertedY[row]; 

      // Coordinate labels 
      String[] abcLabels = {"A","B","C","D","E","F","G","H"}; 

      if (row == 9 || row == 0) { 
       if (col == 0 || col == 9) continue; 

       Label label = new Label(abcLabels[x]); 
       label.setTextAlignment(TextAlignment.CENTER); 
       board.add(label, col, row); 

       continue; 
      } else if (col == 0 || col == 9) { 
       Label label = new Label(Integer.toString(y + 1)); 
       board.add(label, col, row); 

       continue; 
      } 

      // Cell background color 
      Square square = game.getBoard().getSquare(x, y); 
      Color color = square.getColor() == ChessColor.BLACK 
        ? Color.PERU : Color.BLANCHEDALMOND; 

      StackPane cell = cells[y][x] = new StackPane(); 
      cell.setMaxSize(60, 60); 
      cell.setMinSize(60, 60); 
      cell.setBackground(new Background(
        new BackgroundFill(color, null, null))); 

      board.add(cell, col, row); 
     } 
    } 

    // Finally, add pieces to their respective cells 
    for (int y = 0; y < 8; y++) { 
     for (int x = 0; x < 8; x++) { 
      Square square = game.getBoard().getSquare(x, y); 
      Piece occupant = square.getOccupant(); 

      if (occupant != null) { 
       String path = "/resources/" + occupant + ".png"; 
       Image image = 
         new Image(getClass().getResourceAsStream(path)); 
       DraggablePieceIcon imageView = 
         new DraggablePieceIcon(image); 
       imageView.setManaged(false); 
       cells[y][x].getChildren().add(imageView); 
      } 
     } 
    } 



    return board; 
} 

該類使得拖動圖標:

public class DraggablePieceIcon extends ImageView { 
    private double mouseX; 
    private double mouseY; 

    public DraggablePieceIcon(Image image) { 
     super(image); 

     setOnMousePressed(event -> { 
      mouseX = event.getSceneX(); 
      mouseY = event.getSceneY(); 
     }); 

     setOnMouseDragged(event -> { 
      double deltaX = event.getSceneX() - mouseX; 
      double deltaY = event.getSceneY() - mouseY; 

      relocate(getLayoutX() + deltaX, getLayoutY() + deltaY); 

      mouseX = event.getSceneX(); 
      mouseY = event.getSceneY(); 
     }); 
    } 
} 

和這裏的我所看到的:

enter image description here

回答

1

你」重新從左到右逐行添加單元格。由於您將這些棋子添加到單元格中,單元格的後代將單元格的內容覆蓋在上方或同一行中的單元格中,並留在單元格中,並且將覆蓋所有其他單元格的內容。

爲了解決這個問題,你可以做一個拖動項目的父在GridPane最頂端的節點:

public DraggablePieceIcon(Image image) { 
    super(image); 

    setOnMousePressed(event -> { 
     mouseX = event.getSceneX(); 
     mouseY = event.getSceneY(); 

     // make cell containing this piece the top-most cell 
     this.getParent().toFront() 
    }); 

    ... 
} 

注意,該解決方案將要求您實現一些邏輯,使細胞的片兒,他們被移動並移動到這些單元的中心。否則一塊可能會被其他單元覆蓋,如果您稍後將這塊單元拖拽到該單元中...

另一種方法是使GridPane本身的塊兒童。無論如何,你都可以讓這些小塊獨立於細胞而被拖動;單元和塊之間的關聯對於模型(即在這種情況下是國際象棋規則的實現)而言並不重要,並且通常這些部分保持獨立。

相關問題