JavaFX 2中行的确切尺寸是多少? [英] What are a line's exact dimensions in JavaFX 2?

查看:52
本文介绍了JavaFX 2中行的确切尺寸是多少?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm wondering about a line's exact width in JavaFX 2.1.

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

Creating a straight line starting at point (10;10) and ending at point (20;10) should have an expected width of 10px. When reading the line's width a value of 11px is returned. When starting the attached example and making a screenshot you'll see - at a higher zoom level - the line has a width of 12px and a height of 2px.

使用LineBuilder没有任何区别.我事件尝试应用其他StrokeType失败.

Using a LineBuilder does not make any difference. I event tried to apply a different StrokeType without success.

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

Creating a square with a side length of 10 returns the expected width of 10px.

  1. 为什么line.getBoundsInLocal().getWidth()返回的值与我在渲染结果(屏幕截图)中看到的值不同?
  2. 为什么在创建线和面时在宽度上有区别?
  1. Why does line.getBoundsInLocal().getWidth() return different values from those I see in the rendered result (screenshot)?
  2. Why is there a difference concerning width when creating lines and polygons?

示例:

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

推荐答案

认为线本身没有任何表面积,它无限细.线的唯一尺寸来自笔划.

Think of the line itself as having no surface area whatsoever, it is infinitely thin. The only dimensions for the line come from the stroke.

当StrokeType为已输入,而StrokeLineCap为 SQUARE (默认值),则该线所占的面积来自在所有方向上围绕该线均匀地应用笔划宽度的一半.

When the StrokeType is CENTERED and the StrokeLineCap is SQUARE (the default values), then the area taken by the the line comes from evenly applying half the stroke width around the line in all directions.

在您的示例中,您将在整数坐标处绘制描边为1的水平线. JavaFX 坐标系统就是这样的整数角映射到像素之间的线.当您显示带有整数坐标的水平线时,该线本身与该线两侧的两个垂直像素的一半交叉,最终变成灰色阴影的抗锯齿线,而不是黑色线仅阴影一个垂直像素.此外,在行末端应用SQUARE的StrokeLineCap表示笔划超出了行的端点,超出了笔划宽度的一半.这样最终会在行尾两侧的两对像素中为每个像素的四分之一着色.

In your example, you are drawing a horizontal line with a stroke of 1 at an integer co-ordinate. The JavaFX co-ordinate system is such that integer corners map to the lines between pixels. When you display a horizontal line with integer co-ordinates, the line itself crosses half of the two vertical pixels on either side of the line and ends up as a gray shaded antialiased line rather than a black line shading only one vertical pixel. Additionally, the StrokeLineCap of SQUARE applied at the line ends means that the stroke extends beyond the end points of the line by half the stroke width. This ends up shading a quarter of each pixel in the two pairs of pixels on either side of the line ends.

通过将线的坐标偏移半个像素,可以绘制线,以使其在一行沿每个像素的中间落下并且线描边延伸时,对垂直像素的单行进行着色到每个像素的顶部和底部边缘.此外,将线帽设置为对接而不是正方形意味着线的阴影区域不会超出线的末端.

By offsetting the co-ordinates of the line by half a pixel, the line can be drawn such that it shades a single row of vertical pixels as now the line is falling along the middle of each pixel and the line stroke is extending to the top and bottom edges of each pixel. Additionally, setting the line cap to butt rather than square means that the shaded area for the line will not extend beyond the ends of the line.

以下是一些示例代码来演示这一点.在示例中,只有最后一行完全完全阴影了10个像素,没有更多.这也是唯一在边框中具有10个宽度和整数坐标的线.

Here is some sample code to demonstrate this. In the sample, only the last line completely shades exactly 10 pixels and no more. It is also the only line which has a width of 10 and integer co-ordinates in it's bounding box.

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]

这篇关于JavaFX 2中行的确切尺寸是多少?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆