javafx FXML绘制后画布为空 [英] javafx FXML Canvas empty after drawing

查看:277
本文介绍了javafx FXML绘制后画布为空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Intellij IDEA进行javafx FXML开发。我使用下面的代码来简单地绘制一个矩形。

  

public class Main extends Application {

@Override
public void start(Stage primaryStage)throws Exception {
Parent root = FXMLLoader.load(getClass .getResource(sample.fxml));
primaryStage.setTitle(Hello World);
primaryStage.setScene(new Scene(root,600,400));
primaryStage.show();
}


public static void main(String [] args){
launch(args);
}
}

Controller.java / p>

  public class Controller implements可初始化{
public Mat image;
@FXML public Canvas img = new Canvas(300,300);
public GraphicsContext gc = img.getGraphicsContext2D();
@FXML private void drawCanvas(ActionEvent event){
gc.setFill(Color.AQUA);
gc.fillRect(10,10,100,100);
}
@Override
public void initialize(URL location,ResourceBundle resources){
gc.setFill(Color.BLACK);
System.out.println(color set to black);
gc.fillRect(50,50,100,100);
System.out.println(draw rectangle);
}
}



我使用setFill()和fillRect Button OnAction和初始化方法。但它仍然不绘制矩形。



sample.fxml



 < BorderPane maxHeight = -  InfinitymaxWidth = -  InfinityminHeight = -  InfinityminWidth = -  InfinityprefHeight =400.0prefWidth =600.0xmlns =http:// javafx.com/javafx/8xmlns:fx =http://javafx.com/fxml/1fx:controller =sample.Controller> < top> < ToolBar prefHeight =40.0prefWidth =200.0BorderPane.alignment =CENTER> < items> < Button mnemonicParsing =falseonAction =#drawingCanvastext =draw/> < / items> < / ToolBar> < / top> < bottom> < AnchorPane prefHeight =41.0prefWidth =600.0BorderPane.alignment =CENTER> < children> < Label fx:id =colayoutX =14.0layoutY =9.0text =co/> < Label fx:id =rgblayoutX =144.0layoutY =13.0text =RGB/> < Label fx:id =zoomlayoutX =245.0layoutY =9.0text =zoom/> < / children> < / AnchorPane> < / bottom> < center> < ScrollPane fx:id =img_paneprefHeight =200.0prefWidth =200.0BorderPane.alignment =CENTER> < content> < Canvas fx:id =imgheight =286.0width =355.0/> < / content> < / ScrollPane> < / center>< / BorderPane>  

解决方案

这个论坛上有几个问题,但我无法通过快速搜索找到它们。



从不 初始化注释为 @FXML 的字段。 @FXML 的整个要点是该字段在加载FXML文件的过程中被初始化。



在类初始化器中,创建一个 Canvas ,然后将 gc 分配给其图形上下文:

  @FXML public Canvas img = new Canvas(300,300); 
public GraphicsContext gc = img.getGraphicsContext2D();然后,当您加载FXML文件时, FXMLLoader


$ b $ c>创建一个新的 Canvas ,如FXML所述,将新画布分配给字段 img 在场景图中的新画布(然后您在舞台上显示)。但是, gc 仍然是原始 Canvas 的图形上下文,您从不显示它。因此, gc 上的任何图形操作将永远无法实现。



您需要

  public class Controller implements可初始化{

@FXML private Canvas img;

private GraphicsContext gc;

@FXML private void drawCanvas(ActionEvent event){
gc.setFill(Color.AQUA);
gc.fillRect(10,10,100,100);
}

@Override
public void initialize(URL location,ResourceBundle resources){
gc = img.getGraphicsContext2D();
gc.setFill(Color.BLACK);
System.out.println(color set to black);
gc.fillRect(50,50,100,100);
System.out.println(draw rectangle);
}

}


I'm using Intellij IDEA for javafx FXML development. I used the following code to simply draw an rectangle. However, it never showed up.

Main.java

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 600, 400));
        primaryStage.show();
    }


    public static void main(String[] args) {
        launch(args);
    }
}

Controller.java

public class Controller implements Initializable {
public Mat image;
@FXML public Canvas img = new Canvas(300,300);
public GraphicsContext gc = img.getGraphicsContext2D();
@FXML private void drawCanvas(ActionEvent event) {
    gc.setFill(Color.AQUA);
    gc.fillRect(10,10,100,100);
}
@Override
public void initialize(URL location, ResourceBundle resources) {
        gc.setFill(Color.BLACK);
        System.out.println("color set to black");
        gc.fillRect(50, 50, 100, 100);
        System.out.println("draw rectangle");
    }
}

I used setFill() and fillRect() both in Button OnAction and initialize methods. But it still doesn't draw the rectangles.

sample.fxml

<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
   <top>
      <ToolBar prefHeight="40.0" prefWidth="200.0" BorderPane.alignment="CENTER">
        <items>
          <Button mnemonicParsing="false" onAction="#drawCanvas" text="draw" />
        </items>
      </ToolBar>
   </top>
   <bottom>
      <AnchorPane prefHeight="41.0" prefWidth="600.0" BorderPane.alignment="CENTER">
         <children>
            <Label fx:id="co" layoutX="14.0" layoutY="9.0" text="co" />
            <Label fx:id="rgb" layoutX="144.0" layoutY="13.0" text="RGB" />
            <Label fx:id="zoom" layoutX="245.0" layoutY="9.0" text="zoom" />
         </children>
      </AnchorPane>
   </bottom>
   <center>
      <ScrollPane fx:id="img_pane" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER">
         <content>
            <Canvas fx:id="img" height="286.0" width="355.0" />
         </content>
      </ScrollPane>
   </center>
</BorderPane>

解决方案

There are several questions like this on this forum, but I cannot find them with a quick search.

You should never initialize a field that is annotated @FXML. The whole point of @FXML is that the field is initialized during the process of loading the FXML file.

So in your class initializer, you create a Canvas and then assign gc to its graphics context:

@FXML public Canvas img = new Canvas(300,300);
public GraphicsContext gc = img.getGraphicsContext2D();

Then, when you load the FXML file, the FXMLLoader creates a new Canvas as described by the FXML, assigns that new canvas to the field img, and places the new canvas in the scene graph (which you then display in the stage). However, gc is still the graphics context of the original Canvas, which you never display. So any graphics operations on gc will never be realized.

You need

public class Controller implements Initializable {

    @FXML private Canvas img ;

    private GraphicsContext gc ;

    @FXML private void drawCanvas(ActionEvent event) {
        gc.setFill(Color.AQUA);
        gc.fillRect(10,10,100,100);
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        gc = img.getGraphicsContext2D();
        gc.setFill(Color.BLACK);
        System.out.println("color set to black");
        gc.fillRect(50, 50, 100, 100);
        System.out.println("draw rectangle");
    }

}

这篇关于javafx FXML绘制后画布为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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