我可以将2D变换应用于JavaFX 8 Canvas上的形状吗?

时间:2015-06-12 15:39:33

标签: java javafx javafx-8

我将之前在Swing中完成的类移植到JavaFX 8.它显示的UI元素看起来像一个模拟电压表,半圆圈被一组" tic标记包围#34;定期。在Swing版本中,该类是JPanel的扩展,并且在paintComponent(Graphics g)中绘制了tic标记,如下所示:

private Line2D ticLine = new Line2D.Float(0, LINE_ROOT_Y, TIC_LENGTH, LINE_ROOT_Y);

public void paintComponent(Graphics g)
   {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g;

      // Draw tic marks
      if (ticCount > 0)
      {
         g2.draw(ticLine); // First tic

         AffineTransform ticTrans = new AffineTransform();
         // Draw all additional tics rotated around half circle
         for (int i = 1; i < ticCount; i++)
         {
            ticTrans.rotate(Math.toRadians(ticGap),
                 METER_MIDDLE, METER_BASE_Y);
            g2.draw(ticTrans.createTransformedShape(ticLine));
         }
      }
   }

这很好。

现在使用JavaFX我正在使用扩展VBox的类。它包含2个堆叠的Canvas对象。其中一个将绘制静态元素,如半圆和tic标记,另一个用于定期移动的仪表线。在第一个Canvas上,我希望使用类似于Swing版本的循环来轻松地重新绘制半圆周围的额外位置的ticCount#中的第一个tic标记。所以我尝试了以下编译和运行但只绘制了第一个标记:

// Called from the constructor:
MeterGC = MeterCanvas.getGraphicsContext2D();
Line ticLine = new Line(0, LINE_ROOT_Y, TIC_LENGTH, LINE_ROOT_Y);

// Draw tic marks
if (ticCount > 1)
{
   MeterGC.setStroke(Color.GRAY);
   MeterGC.setLineWidth(BASIC_LINE_WIDTH);
   MeterGC.strokeLine(ticLine.getStartX(), ticLine.getStartY(), 
                      ticLine.getEndX(), ticLine.getEndY());

   Rotate ticTrans = new Rotate(Math.toRadians(ticGap), METER_MIDDLE, METER_BASE_Y);
   for (int i = 1; i < ticCount; i++)
   {
      ticLine.getTransforms().add(ticTrans);
      MeterGC.strokeLine(ticLine.getStartX(), ticLine.getStartY(), 
                         ticLine.getEndX(), ticLine.getEndY());
    }
}

尝试变换这样的Shape对象可能只在绘制到场景而不是在Canvas上时起作用。或者我必须在&#34; ticLine.getTransforms()之后做一些事情.add(ticTrans)&#34;行让他们申请到该行。我至少关闭了吗?或者有更好的方法来做我在这里尝试的事情吗?

2 个答案:

答案 0 :(得分:1)

你做错了什么

在示例代码中,您将变换应用于xAxis.setEnabled(false)对象(您从未显示过)。

如何解决

在画布上划线之前,您需要set the transform on the canvas GraphicsContext

示例代码

有关示例,请参阅:

Line

答案 1 :(得分:0)

这是我修改过的for-loop,它完美无缺。注意到在JavaFX中不再需要将Rotate中的角度转换为弧度也是使其工作的关键。

for (int i = 1; i < ticCount; i++)
{
   Rotate ticTrans = new Rotate(ticGap * i, METER_MIDDLE, METER_BASE_Y);
   MeterGC.setTransform(ticTrans.getMxx(), ticTrans.getMyx(), ticTrans.getMxy(),
                        ticTrans.getMyy(), ticTrans.getTx(), ticTrans.getTy());
   MeterGC.strokeLine(ticLine.getStartX(), ticLine.getStartY(), 
                      ticLine.getEndX(), ticLine.getEndY());
}