如何在保持矩形背景颜色

时间:2016-11-04 00:19:58

标签: css image javafx

我有一个国际象棋棋盘,我正试图在棋盘上添加棋子。板上的每个点都是一个矩形,所以我认为添加片段的最佳方法是将ImagePattern添加到每个获取片段的Rectangle中。我遇到的问题是当我将一个ImagePattern添加到一个Rectangle时,它会使该Rectangle的背景变为白色,尽管在添加ImagePattern之前颜色是什么。所以我的问题是,在添加ImagePattern后,有没有办法保留Rectangle的背景颜色? 出于演示目的,我的代码只添加了一块电路板。

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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

不,您不能使用Rectangle多次填充。从理论上讲,你可以使用具有多个背景的Region,但这可能是一个坏主意。如果你没有把它们作为自己的节点,那么你很可能至少想要这些部分的一些以下功能,这些功能是行不通的:

  • 将一个片段从一个字段拖到另一个字段
  • 动画动作

我建议使用StackPane并将棋盘放在后台并在其上放置Pane以放置棋子。只需使用ImageView s即可获得作品。

示例:

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

}