Cómo dibujar una rayita nítida y opaca en JavaFX 2.2?

¿Cuál es la mejor manera de dibujar una rayita nítida y opaca en JavaFX 2.2?

La documentación dice que con un strokeWidth de 0.0d será una rayita, pero simplemente no es visible en absoluto. Los valores > 0.0d and <1.0d muestran líneas que son bastante finas, pero que tampoco muestran un comportamiento opaco. Cuando una línea corta otra, los puntos de intersección son más claros que el rest de la línea (esperaría este comportamiento desde una línea con cierta transparencia). Finalmente, 1.0d dibuja una línea blanca con varios píxeles de ancho.

Ese es mi código de prueba:

 LineBuilder.create().startX(i*gridSize).startY(0).endX(i*gridSize).endY(height).smooth(false).stroke(Color.WHITE).strokeWidth(0.5d).fill(Color.WHITE).build(); 

Puede usar una subclase de Región , como un Panel para su Padre, con snapToPixel establecido en verdadero.

Además, consulte la documentación de Nodo en el sistema de coordenadas.

En el nivel de píxel del dispositivo, las coordenadas enteras se asignan a las esquinas y las grietas entre los píxeles y los centros de los píxeles aparecen en los puntos medios entre las ubicaciones de píxeles enteros. Como todos los valores de coordenadas se especifican con números de coma flotante, las coordenadas pueden apuntar con precisión a estas esquinas (cuando los valores de coma flotante tienen valores enteros exactos) oa cualquier ubicación en el píxel. Por ejemplo, una coordenada de (0.5, 0.5) apuntaría al centro del píxel superior izquierdo en el escenario. De forma similar, un rectángulo en (0, 0) con dimensiones de 10 por 10 abarcaría desde la esquina superior izquierda del píxel superior izquierdo en el escenario hasta la esquina inferior derecha del décimo píxel en la décima línea de exploración. El centro de píxeles del último píxel dentro de ese rectángulo estaría en las coordenadas (9.5, 9.5).

También vea la documentación de Shape :

La mayoría de los nodos tienden a tener solo traducciones enteras aplicadas a ellos y muy a menudo también se definen usando coordenadas enteras. En este caso común, los rellenos de formas con bordes en línea recta tienden a ser nítidos, ya que se alinean con las grietas entre los píxeles que caen en las coordenadas del dispositivo entero y, por lo tanto, tienden a cubrir naturalmente píxeles completos. Por otro lado, acariciar esas mismas formas puede conducir a contornos borrosos porque los atributos de caricia predeterminados especifican tanto que el ancho de trazo predeterminado es 1.0 coordenadas que a menudo se correlacionan exactamente con 1 píxel de dispositivo y también que el trazo debe colocarse sobre el borde de la forma , cayendo a la mitad a cada lado del borde. Dado que los bordes en muchas formas comunes tienden a caer directamente en coordenadas enteras y esas coordenadas enteras a menudo se asignan con precisión a ubicaciones de dispositivos enteros, los bordes tienden a dar como resultado una cobertura del 50% sobre las filas y columnas de píxeles a ambos lados del borde de la forma en lugar de una cobertura del 100% en uno u otro. Por lo tanto, los rellenos pueden ser crujientes, pero los trazos a menudo son borrosos.

Dos soluciones comunes para evitar estos contornos borrosos son utilizar trazos más amplios que cubran más píxeles por completo (generalmente, un ancho de trazo de 2,0 logrará esto si no hay transformaciones de escala en vigor) o especificar el trazo StrokeType.INSIDE o StrokeType.OUTSIDE estilos – que sesgará el trazo de la unidad individual predeterminada en una de las filas o columnas de píxeles completos dentro o fuera del borde de la forma.

Por lo tanto, si deja sus Nodos en un Grupo o Región que no hace snapToPixel, puede seguir las instrucciones anteriores de la documentación de Forma.

Aquí hay un código de muestra:

 import javafx.application.Application; import javafx.scene.*; import javafx.scene.layout.Pane; import javafx.scene.paint.Color; import javafx.scene.shape.Line; import javafx.scene.shape.LineBuilder; import javafx.scene.shape.StrokeType; import javafx.scene.text.Text; import javafx.stage.Stage; /** http://stackoverflow.com/questions/11886230/how-to-draw-a-crisp-opaque-hairline-in-javafx-2-2 */ public class LineWidths extends Application { public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) { Line fuzzyline = LineBuilder.create() .startX(5).startY(50) .endX(90).endY(50) .stroke(Color.BLACK).strokeWidth(1) .build(); Line hairline = LineBuilder.create() .startX(4.5).startY(99.5) .endX(89.5).endY(99.5) .stroke(Color.BLACK).strokeWidth(1) .build(); Line fatline = LineBuilder.create() .startX(5).startY(150) .endX(90).endY(150) .stroke(Color.BLACK).strokeWidth(1).strokeType(StrokeType.OUTSIDE) .build(); Pane snappedPane = new Pane(); Line insideline = LineBuilder.create() .startX(5).startY(25) .endX(90).endY(25) .stroke(Color.BLACK).strokeWidth(1) .build(); snappedPane.setSnapToPixel(true); snappedPane.getChildren().add(insideline); snappedPane.setPrefSize(100, 50); snappedPane.relocate(-0.5, 174.5); stage.setScene( new Scene( new Group( fuzzyline, hairline, fatline, snappedPane, new Text(10, 40, "fuzzyline"), new Text(10, 90, "hairline"), new Text(10, 140, "fatline"), new Text(10, 190, "snappedPane") ), 100, 250 ) ); stage.show(); } } 

Tipo de línea Muestra