I am experimenting with the JavaFX Canvas and noticed strange output when filling polygons. It seems to be related to whether or not a clip is applied. This minimal(-ish) test case reproduces the problem for me on MacOS JDK1.8.0_05. With the CLIP flag set to false, the output is what I expect. Changing CLIP to true triggers the bug (the polygon fill shows two shades of gray for me, instead of one):
import static javafx.application.Application.launch;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
// A test case showing a polygon fill on JavaFX canvas. The fill should have
// a single color, but when clipping is enabled the fill is corrupted and
// shows more than one shade of gray.
public class TestCase extends Application {
// change this flag to TRUE and the shape fill is corrupted
// at least for me on MacOS JDK 1.8.0_05
private static final boolean CLIP = false;
// based on ResizableCanvas:
// http://dlemmermann.wordpress.com/2014/04/10/javafx-tip-1-resizable-canvas/
static class TestCanvas extends Canvas {
public TestCanvas() {
widthProperty().addListener(evt -> draw());
heightProperty().addListener(evt -> draw());
}
private void draw() {
double width = getWidth();
double height = getHeight();
GraphicsContext gc = getGraphicsContext2D();
gc.save();
gc.clearRect(0, 0, width, height);
if (CLIP) {
gc.beginPath();
gc.rect(0, 0, 600, 400);
gc.closePath();
gc.clip();
}
gc.translate(300.0, 100.0);
gc.beginPath();
gc.moveTo(-112.82283020019531,203.73513793945312);
gc.lineTo(-254.63790893554688,30.293907165527344);
gc.lineTo(45.6809196472168,27.10471534729004);
gc.lineTo(230.38345336914062,177.9417724609375);
gc.closePath();
gc.setFill(Color.rgb(184,184,184,0.4));
gc.fill();
gc.setStroke(Color.RED);
gc.stroke();
gc.restore();
}
@Override
public boolean isResizable() {
return true;
}
@Override
public double prefWidth(double height) {
return getWidth();
}
@Override
public double prefHeight(double width) {
return getHeight();
}
}
@Override
public void start(Stage stage) throws Exception {
TestCanvas canvas = new TestCanvas();
StackPane stackPane = new StackPane();
stackPane.setPrefSize(600, 400);
stackPane.getChildren().add(canvas);
// Bind canvas size to stack pane size.
canvas.widthProperty().bind(
stackPane.widthProperty());
canvas.heightProperty().bind(
stackPane.heightProperty());
stage.setScene(new Scene(stackPane));
stage.setTitle("Test Case");
stage.show();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
import static javafx.application.Application.launch;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
// A test case showing a polygon fill on JavaFX canvas. The fill should have
// a single color, but when clipping is enabled the fill is corrupted and
// shows more than one shade of gray.
public class TestCase extends Application {
// change this flag to TRUE and the shape fill is corrupted
// at least for me on MacOS JDK 1.8.0_05
private static final boolean CLIP = false;
// based on ResizableCanvas:
// http://dlemmermann.wordpress.com/2014/04/10/javafx-tip-1-resizable-canvas/
static class TestCanvas extends Canvas {
public TestCanvas() {
widthProperty().addListener(evt -> draw());
heightProperty().addListener(evt -> draw());
}
private void draw() {
double width = getWidth();
double height = getHeight();
GraphicsContext gc = getGraphicsContext2D();
gc.save();
gc.clearRect(0, 0, width, height);
if (CLIP) {
gc.beginPath();
gc.rect(0, 0, 600, 400);
gc.closePath();
gc.clip();
}
gc.translate(300.0, 100.0);
gc.beginPath();
gc.moveTo(-112.82283020019531,203.73513793945312);
gc.lineTo(-254.63790893554688,30.293907165527344);
gc.lineTo(45.6809196472168,27.10471534729004);
gc.lineTo(230.38345336914062,177.9417724609375);
gc.closePath();
gc.setFill(Color.rgb(184,184,184,0.4));
gc.fill();
gc.setStroke(Color.RED);
gc.stroke();
gc.restore();
}
@Override
public boolean isResizable() {
return true;
}
@Override
public double prefWidth(double height) {
return getWidth();
}
@Override
public double prefHeight(double width) {
return getHeight();
}
}
@Override
public void start(Stage stage) throws Exception {
TestCanvas canvas = new TestCanvas();
StackPane stackPane = new StackPane();
stackPane.setPrefSize(600, 400);
stackPane.getChildren().add(canvas);
// Bind canvas size to stack pane size.
canvas.widthProperty().bind(
stackPane.widthProperty());
canvas.heightProperty().bind(
stackPane.heightProperty());
stage.setScene(new Scene(stackPane));
stage.setTitle("Test Case");
stage.show();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}