3

JavaFX 2.2で鮮明で不透明なヘアラインを描画するための最良の方法は何ですか?

ドキュメントによると、そのうちの1つはヘアラインstrokeWidth0.0dなりますが、まったく表示されません。値> 0.0d and <1.0dはかなり細かい線を示していますが、不透明な動作も示していません。ある線が別の線を切断するとき、交差する点は他の線よりも明るくなります(ある程度の透明度のある線からこの動作が期待されます)。最後に、1.0d数ピクセル幅の白い線を描画します。

これが私のテストコードです。

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

1 に答える 1

3

snapToPixelをtrueに設定して、親のペインなどのRegionサブクラスを使用できます。

さらに、座標系のノードのドキュメントを参照してください。

デバイスのピクセルレベルでは、整数座標がコーナーにマッピングされ、ピクセル間の亀裂とピクセルの中心が整数ピクセル位置の中間点に表示されます。すべての座標値は浮動小数点数で指定されるため、座標はこれらのコーナー(浮動小数点値が正確な整数値の場合)またはピクセル上の任意の場所を正確に指すことができます。たとえば、(0.5、0.5)の座標は、ステージの左上のピクセルの中心を指します。同様に、寸法が10 x 10の(0、0)の長方形は、ステージの左上のピクセルの左上隅から10番目のスキャンラインの10番目のピクセルの右下隅まで広がります。その長方形内の最後のピクセルのピクセル中心は、座標(9.5、9.5)になります。

Shapeのドキュメントも参照してください。

ほとんどのノードには整数変換のみが適用される傾向があり、整数座標を使用して定義されることもよくあります。この一般的なケースでは、直線のエッジを持つ形状の塗りつぶしは、整数のデバイス座標に該当するピクセル間の亀裂と整列し、ピクセル全体を自然に覆う傾向があるため、鮮明になる傾向があります。一方、デフォルトのストローク属性では、デフォルトのストローク幅が1.0座標であり、正確に1つのデバイスピクセルにマップされることが多く、ストロークがシェイプの境界にまたがる必要があることを指定しているため、同じ形状をストロークすると、輪郭がぼやけることがよくあります。 、境界線のいずれかの側に半分落ちます。多くの一般的な形状の境界線は整数座標に直接収まる傾向があり、それらの整数座標は整数のデバイス位置に正確にマッピングされることが多いため、境界線は形状の境界線の両側のピクセルの行と列を50%カバーする傾向がありますどちらか一方を100%カバーするのではなく。したがって、塗りつぶしは通常鮮明ですが、ストロークはあいまいなことがよくあります。

これらのあいまいなアウトラインを回避するための2つの一般的な解決策は、より多くのピクセルを完全にカバーするより広いストロークを使用することです(通常、スケール変換が有効になっていない場合、ストローク幅2.0でこれを実現します)、またはStrokeType.INSIDEまたはStrokeType.OUTSIDEストロークのいずれかを指定しますスタイル-デフォルトの単一ユニットストロークを、図形の境界のすぐ内側または外側の完全なピクセル行または列の1つにバイアスします。

したがって、snapToPixelではないグループまたはリージョンにノードを残す場合は、Shapeドキュメントの上記の手順に従うことができます。

サンプルコードは次のとおりです。

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

線種サンプル

于 2012-08-09T16:24:01.887 に答える