2016-11-04 27 views
0

我有一個國際象棋棋盤,我正在嘗試添加棋子到棋盤上。棋盤上的每個點都是矩形,所以我認爲添加棋子的最佳方式是將ImagePattern添加到每個獲得棋子的矩形。我遇到的問題是當我添加一個ImagePattern到一個Rectangle時,它會使該矩形的背景變白,儘管在添加ImagePattern之前顏色是什麼。所以我的問題是,有沒有辦法讓我在添加ImagePattern後保留Rectangle的背景顏色? 爲了演示的目的,我的代碼只添加了一塊板。如何添加一個ImagePattern矩形,同時仍然保持Rectangles背景顏色

public class ChessBoard extends Application { 
    GridPane root = new GridPane(); 
    final int size = 8; 

    public void start(Stage primaryStage) { 
    for (int row = 0; row < size; row++) { 
     for (int col = 0; col < size; col++) { 
      Rectangle square = new Rectangle(); 
      Color color; 

      if ((row + col) % 2 == 0) 
       color = Color.WHITE; 
      else 
       color = Color.BLACK; 

      square.setFill(color); 
      root.add(square, col, row); 
      if(row == 4 && col == 3){ 
       Image p = new Image("Peices/Black/0.png"); 
       ImagePattern pat = new ImagePattern(p); 
       square.setFill(pat); 
      } 



      square.widthProperty().bind(root.widthProperty().divide(size)); 
      square.heightProperty().bind(root.heightProperty().divide(size)); 
      square.setOnMouseClicked(e->{ 
       square.setFill(Color.BLUE); 
      }); 
     } 
    } 
    primaryStage.setScene(new Scene(root, 400, 400)); 
    primaryStage.show(); 
} 

    public static void main(String[] args) { 
    launch(args); 
    } 
} 

回答

0

我想你正在尋找與BlendMode完成的混合。例如:

Image p = new Image("Peices/Black/0.png"); 
ImagePattern pat = new ImagePattern(p); 
Rectangle r1 = new Rectangle(); 
r1.setX(50); 
r1.setY(50); 
r1.setWidth(50); 
r1.setHeight(50); 
r1.setFill(pat); 

Rectangle r = new Rectangle(); 
r.setX(50); 
r.setY(50); 
r.setWidth(50); 
r.setHeight(50); 
r.setFill(Color.BLUE); 
r.setBlendMode(BlendMode.ADD); 

據我所知,沒有直接的方法來實現這一點。
來源:https://docs.oracle.com/javase/8/javafx/api/javafx/scene/effect/BlendMode.html

0

不,您不能使用多於一個填充Rectangle。理論上你可以使用具有多種背景的Region,但這可能是一個壞主意。最有可能你會想至少有一些爲片以下的功能,這是行不通的,如果你不做出個自己的節點:

  • 拖動一塊從一個領域到另一個
  • 動畫移動

我建議使用StackPane,並把董事會在後臺把Pane在它上面放置件。只需使用ImageView即可。

實施例:

@Override 
public void start(Stage primaryStage) { 
    GridPane board = new GridPane(); 
    Region[][] fields = new Region[8][8]; 
    for (int i = 0; i < fields.length; i++) { 
     Region[] flds = fields[i]; 
     for (int j = 0; j < flds.length; j++) { 
      Region field = new Region(); 
      flds[j] = field; 
      field.setBackground(new Background(new BackgroundFill((i + j) % 2 == 0 ? Color.WHITE : Color.BLACK, CornerRadii.EMPTY, Insets.EMPTY))); 
     } 
     board.addRow(i, flds); 
    } 

    // use 1/8 of the size of the Grid for each field 
    RowConstraints rowConstraints = new RowConstraints(); 
    rowConstraints.setPercentHeight(100d/8); 
    ColumnConstraints columnConstraints = new ColumnConstraints(); 
    columnConstraints.setPercentWidth(100d/8); 

    for (int i = 0; i < 8; i++) { 
     board.getColumnConstraints().add(columnConstraints); 
     board.getRowConstraints().add(rowConstraints); 
    } 

    Pane piecePane = new Pane(); 
    StackPane root = new StackPane(board, piecePane); 

    NumberBinding boardSize = Bindings.min(root.widthProperty(), root.heightProperty()); 

    ImageView queen = new ImageView("https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/Chess_qdt45.svg/480px-Chess_qdt45.svg.png"); 
    DropShadow shadow = new DropShadow(BlurType.GAUSSIAN, Color.WHITE, 2, 1, 0, 0); 

    // drop shadow for black piece on black field 
    queen.setEffect(shadow); 

    // trigger move to topleft field on mouse click 
    queen.setOnMouseClicked(evt -> { 
     Node source = (Node) evt.getSource(); 
     TranslateTransition animation = new TranslateTransition(Duration.seconds(0.5), source); 
     Region targetRegion = fields[0][0]; 
     final PositionChangeListener listener = (PositionChangeListener) source.getUserData(); 
     listener.setField(null); 
     animation.setByX(targetRegion.getLayoutX() - source.getLayoutX()); 
     animation.setByY(targetRegion.getLayoutY() - source.getLayoutY()); 
     animation.setOnFinished(e -> { 
      source.setTranslateX(0); 
      source.setTranslateY(0); 
      listener.setField(targetRegion); 
     }); 
     animation.play(); 
    }); 

    PositionChangeListener changeListener = new PositionChangeListener(queen); 
    queen.setUserData(changeListener); 
    changeListener.setField(fields[4][3]); 

    // board size should be as large as possible but at most the min of the parent sizes 
    board.setPrefSize(Double.MAX_VALUE, Double.MAX_VALUE); 
    board.maxWidthProperty().bind(boardSize); 
    board.maxHeightProperty().bind(boardSize); 

    // same size for piecePane 
    piecePane.setPrefSize(Double.MAX_VALUE, Double.MAX_VALUE); 
    piecePane.maxWidthProperty().bind(boardSize); 
    piecePane.maxHeightProperty().bind(boardSize); 

    // add piece to piecePane 
    piecePane.getChildren().add(queen); 

    Scene scene = new Scene(root, 400, 400); 

    primaryStage.setScene(scene); 
    primaryStage.show(); 
} 

private static class PositionChangeListener implements ChangeListener<Bounds> { 

    private final ImageView piece; 

    public PositionChangeListener(ImageView piece) { 
     this.piece = piece; 
    } 

    private Region currentField; 

    public void setField(Region newRegion) { 
     // register/unregister listeners to bounds changes of associated field 
     if (currentField != null) { 
      currentField.boundsInParentProperty().removeListener(this); 
     } 
     currentField = newRegion; 
     if (newRegion != null) { 
      newRegion.boundsInParentProperty().addListener(this); 
      changed(null, null, newRegion.getBoundsInParent()); 
     } 
    } 

    @Override 
    public void changed(ObservableValue<? extends Bounds> observable, Bounds oldValue, Bounds newValue) { 
     // align piece with field 
     piece.setLayoutX(newValue.getMinX()); 
     piece.setLayoutY(newValue.getMinY()); 
     piece.setFitHeight(newValue.getHeight()); 
     piece.setFitWidth(newValue.getWidth()); 
    } 

} 
+0

感謝您的回答。我一直在爲此進行研究,但我不認爲自己能夠做到,但我只是想確保。我真的很喜歡你使用StackPane的建議,我會嘗試一下。 – theAnon

+0

fabian,我一直沒有搞亂這段代碼一段時間,我只是有一個快速的問題,如果我想添加一個MouseListener到每個單獨的廣場,並看看如果該廣場是一個合法的舉動某一塊,成爲添加監聽器的最佳地點?我一直在努力想象它在過去的幾天裏,沒有任何我已經嘗試似乎工作。順便謝謝你的這個例子,我已經從中學到了很多東西! – theAnon

相關問題