JavaFX 2中的行的确切尺寸是多少?

时间:2012-08-09 10:54:41

标签: javafx-2

我想知道JavaFX 2.1中一行的确切宽度。

从点(10; 10)开始并在点(20; 10)结束时创建一条直线的预期宽度应为10px。读取线宽时,返回值11px。 在启动附加示例并制作屏幕截图时,您将看到 - 在更高的缩放级别 - 该行的宽度为12像素,高度为2像素。

使用LineBuilder没有任何区别。我的活动试图应用不同的StrokeType但没有成功。

创建边长为10的正方形将返回预期的10px宽度。

  1. 为什么line.getBoundsInLocal().getWidth()会返回与我在渲染结果中看到的值不同的值(屏幕截图)?
  2. 创建线条和多边形时,为什么宽度有差异?
  3. 示例:

    import javafx.application.Application;
    import javafx.scene.Group;
    import javafx.scene.Scene;
    import javafx.scene.shape.Line;
    import javafx.scene.shape.Polygon;
    import javafx.stage.Stage;
    
    public class ShapeWidthDemo extends Application {
        @Override
        public void start(Stage stage) throws Exception {
            Group root = new Group();
    
            int startX = 10;
            int startY = 10;
            int length = 10;
    
            Line line = new Line(startX, startY, startX + length, startY);
            System.out.println("line width: " + line.getBoundsInLocal().getWidth());
            //->line width: 11.0
            System.out.println("line height: " + line.getBoundsInLocal().getHeight());
            //->line height: 1.0
            root.getChildren().add(line);
    
            int startY2 = startY + 2;
    
            Polygon polygon = new Polygon(
                startX, startY2,
                startX + 10, startY2, 
                startX + 10, startY2 + 10, 
                startX, startY2 + 10);
            System.out.println("polygon width: " + polygon.getBoundsInLocal().getWidth());
            //->polygon width: 10.0
            System.out.println("polygon height: " + polygon.getBoundsInLocal().getHeight());
            //->polygon height: 10.0
            root.getChildren().add(polygon);
    
            stage.setScene(new Scene(root, 100, 100));
            stage.show();
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    

2 个答案:

答案 0 :(得分:2)

1)线的终点由StrokeLineCap控制 因此,使用默认笔划宽度,您可以通过

获得“所需”值
line.setStrokeType(StrokeType.CENTERED);
line.setStrokeLineCap(StrokeLineCap.BUTT);
... that the line has a width of 12px and a height of 2px.

如果应用StrokeType.OUTSIDE AND NOT StrokeLineCap.BUTT,您可以获得这些值。然而,高度仍然是2px,甚至改变了笔画属性。那太奇怪了..

2)由于多边形的笔触值默认为NULL。通过将其设置为polygon.setStroke(Color.RED);,笔划将呈现。

答案 1 :(得分:1)

认为线条本身没有任何表面区域,它无限薄。该线的唯一尺寸来自中风。

当StrokeType为CENTERED且StrokeLineCap为SQUARE(默认值)时,该线所占的面积来自于在所有方向上均匀地应用线条周围一半的笔触宽度。

在您的示例中,您在整数坐标处绘制一个行程为1的水平线。 JavaFX co-ordinate system使得整数角映射到像素之间的线。当您显示带有整数坐标的水平线时,线本身会穿过线两侧的两个垂直像素的一半,最终会变成灰色阴影的抗锯齿线而不是黑色线,只有一个垂直像素。此外,应用于线端的SQUARE的StrokeLineCap意味着笔划延伸超出线的端点一半的笔划宽度。这最终会遮挡线端两侧的两对像素中每个像素的四分之一。

通过将线的坐标偏移半个像素,可以绘制线条,使其遮蔽单行垂直像素,因为现在线条沿着每个像素的中间落下并且线条笔划正在延伸到每个像素的顶部和底部边缘。此外,将线帽设置为对接而不是方形意味着线的阴影区域不会延伸到线的末端之外。

以下是一些示例代码来演示这一点。在示例中,只有最后一行完全遮蔽了10个像素,而不是更多。它也是唯一一条宽度为10的线和它的边界框中的整数坐标。

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.shape.Line;
import javafx.scene.shape.StrokeLineCap;
import javafx.stage.Stage;

public class LineBounds extends Application {
  public static void main(String[] args) { launch(args); }
  @Override public void start(Stage stage) throws Exception {
    double startX = 10;
    double startY = 10;
    double length = 10;

    Line lineSpanningPixelsSquareEnd = new Line(startX, startY, startX + length, startY);
    System.out.println("lineSpanningPixels (square) bounding box: " + lineSpanningPixelsSquareEnd.getBoundsInLocal());

    startX = 10;
    startY = 20;
    length = 10;

    Line lineSpanningPixelsButtEnd = new Line(startX, startY, startX + length, startY);
    lineSpanningPixelsButtEnd.setStrokeLineCap(StrokeLineCap.BUTT);
    System.out.println("lineSpanningPixels (butt) bounding box:   " + lineSpanningPixelsButtEnd.getBoundsInLocal());

    startX = 10;
    startY = 29.5;
    length = 10;

    Line lineOnPixelsSquareEnd = new Line(startX, startY, startX + length, startY);
    System.out.println("lineOnPixels (square) bounding box:       " + lineOnPixelsSquareEnd.getBoundsInLocal());

    startX = 10;
    startY = 39.5;
    length = 10;

    Line lineOnPixelsButtEnd = new Line(startX, startY, startX + length, startY);
    lineOnPixelsButtEnd.setStrokeLineCap(StrokeLineCap.BUTT);
    System.out.println("lineOnPixels (butt) bounding box:         " + lineOnPixelsButtEnd.getBoundsInLocal());

    stage.setScene(
      new Scene(
        new Group(
          lineSpanningPixelsSquareEnd, lineSpanningPixelsButtEnd, lineOnPixelsSquareEnd, lineOnPixelsButtEnd
        ), 100, 100
      )
    );
    stage.show();
  }
}

示例程序的输出是:

lineSpanningPixels (square) bounding box: BoundingBox [minX:9.5, minY:9.5, minZ:0.0, width:11.0, height:1.0, depth:0.0, maxX:20.5, maxY:10.5, maxZ:0.0]
lineSpanningPixels (butt) bounding box:   BoundingBox [minX:10.0, minY:19.5, minZ:0.0, width:10.0, height:1.0, depth:0.0, maxX:20.0, maxY:20.5, maxZ:0.0]
lineOnPixels (square) bounding box:       BoundingBox [minX:9.5, minY:29.0, minZ:0.0, width:11.0, height:1.0, depth:0.0, maxX:20.5, maxY:30.0, maxZ:0.0]
lineOnPixels (butt) bounding box:         BoundingBox [minX:10.0, minY:39.0, minZ:0.0, width:10.0, height:1.0, depth:0.0, maxX:20.0, maxY:40.0, maxZ:0.0]

line bounds sample program output