在JavaFX画布上绘制形状

4

假设我有一些形状,比如:

Shape s1 = new Rectangle(10, 10);
Shape s2 = new Circle(10);

等等,您想在画布上绘制它们。在Swing中,可以通过Graphics2D.draw(Shape shape)方法实现,但我在JavaFX GraphicsContext中没有看到相应的方法。在JavaFX中是否有类似的方法呢?

1个回答

8

我不确定直接在画布上绘制对象是否可行,但可以直接在舞台节点上绘制,例如这个例子

package javafx8_shape;

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

    /**
     *
     * @web java-buddy.blogspot.com
     */
    public class JavaFX8_Shape extends Application {
    
        @Override
        public void start(Stage primaryStage) {
            Group root = new Group();
            Scene scene = new Scene(root, 500, 500, Color.BLACK);
    
            //Filled rectangle
            Rectangle rect1 = new Rectangle(10, 10, 200, 200);
            rect1.setFill(Color.BLUE);
            
            //Transparent rectangle with Stroke
            Rectangle rect2 = new Rectangle(60, 60, 200, 200);
            rect2.setFill(Color.TRANSPARENT);
            rect2.setStroke(Color.RED);
            rect2.setStrokeWidth(10);
            
            //Rectangle with Stroke, no Fill color specified
            Rectangle rect3 = new Rectangle(110, 110, 200, 200);
            rect3.setStroke(Color.GREEN);
            rect3.setStrokeWidth(10);
            
            root.getChildren().addAll(rect1, rect2, rect3);
    
            primaryStage.setTitle("java-buddy.blogspot.com");
            primaryStage.setScene(scene);
            primaryStage.show();
        }
    
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            launch(args);
        }
    
    }

然而,Canvas API 通常是通过方法调用绘制形状、矩形等的方式。因此,简要概括一下,您甚至可以将矩形对象绘制到其他节点上,比如一个 HBOX:

HBox root =  new HBox(rectangle);  

但是将它绘制到画布上通常是这样完成的:
         gc.setFill(Color.WHITESMOKE);
         gc.fillRect(gc.getCanvas().getLayoutX(),      
         gc.getCanvas().getLayoutY(), 
         gc.getCanvas().getWidth(), 
         gc.getCanvas().getHeight());
         gc.setFill(Color.GREEN);
         gc.setStroke(Color.BLUE);

最好的替代方法是开发一些方法,将您的对象传递给这些方法,然后使用API根据您的对象的尺寸在画布上绘制...
private void drawRectangle(GraphicsContext gc,Rectangle rect){
   gc.setFill(Color.WHITESMOKE);
   gc.fillRect(rect.getX(),      
               rect.getY(), 
               rect.getWidth(), 
               rect.getHeight());
   gc.setFill(Color.GREEN);
   gc.setStroke(Color.BLUE);
}

我觉得最好的方法是将你的画布添加到一个StackPane中,然后也将你的矩形等内容添加到StackPane上,从而实现重叠...这样你就可以将任何节点添加到JavaFX中,并仍然控制它的位置等属性,这是我想到的解决方法,而不需要像上面那样使用样板代码。如果你想要一个可行的方法来在画布上获取图像或技术上的覆盖,请参考这个例子:https://dev59.com/morda4cB1Zd3GeqPNocV - D3181
我记得在JavaFX的早期版本中,大部分绘图都是使用他们自己的脚本语言完成的,这种语言类似于Java,感觉很奇怪!但我猜想他们的计划是使用形状类等来定义新控件和画布上的性能优化API,或许原因可以追溯到编译器优化,如果方法调用可以在运行时更有效地进行优化,而不是尝试从对象中获取信息等...但我同意拥有这种能力是有用的。无论如何,祝你项目好运 :) - D3181
1
实际上,矩形和形状类包含许多方法,如果您要绘制大量形状的实例,则可能会降低性能。https://docs.oracle.com/javase/8/javafx/api/javafx/scene/shape/Rectangle.html拥有所有这些方法可能是它们存在的原因,如果您防止创建所有这些方法只是为了在画布上绘制一个矩形,则性能将更好,因为它们可能主要与ui dev相关,例如拖动等,在每个游戏中都不会有用,因此在内存中拥有100个正方形对象是浪费的。 - D3181
1
你可以使用pane.snapshot()方法。将你的形状添加到pane中,然后获取快照并在画布上绘制它。 快照也可以被缓存。Pane必须在舞台上。你可以将它放在x:-9999,y:-9999。 - Igor Bloom
1
最后的代码片段中应该删除 return gc; - bugybunny
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接