JavaFX 在 fxml 中调整 Canvas 大小

标签 java html canvas javafx javafx-8

我正在尝试在 Javafx 中调整 Canvas 的大小。我正在使用场景生成器和 fxml。到目前为止,当用户单击 Canvas 时, Canvas 会变黑,而当我调整屏幕大小时并单击 Canvas 时,只有 Canvas 的原始大小变黑( Canvas 未调整大小)。我不确定如何解决这个问题。任何想法或解决方案都会有很大帮助。

代码:

Controller :

public class MainFXMLController implements Initializable
{

    @FXML
    private Canvas mainCanvas;

    @FXML

    public GraphicsContext gc;

    public void initGraphics()
    {
        gc = mainCanvas.getGraphicsContext2D();
    }

    public void drawClicked(MouseEvent me)
    {

        gc.clearRect(0, 0, mainCanvas.getWidth(), mainCanvas.getHeight());
        gc.setFill(Color.BLACK);
        gc.fillRect(0, 0, mainCanvas.getWidth(), mainCanvas.getHeight());
        System.out.println("Current mosue position: " + me.getX() + ":" + me.getY());
    }

    @Override
    public void initialize(URL url, ResourceBundle rb)
    {
        initGraphics();

    }  
}

Fxml:

<AnchorPane id="AnchorPane" prefHeight="600.0" prefWidth="750.0"  xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"  fx:controller="app.MainFXMLController">
 <children>
    <Canvas fx:id="mainCanvas" height="565.0" onMouseClicked="#drawClicked" width="750.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="35.0" />

主要 Java 文件:

public class DrawFx extends Application
{

    @Override
    public void start(Stage stage) throws Exception
    {
        Parent root = FXMLLoader.load(getClass().getResource("MainFXML.fxml"));

        Scene scene = new Scene(root);
        stage.setTitle("DrawFx");
        stage.getIcons().add(new Image("/icon/icon.png"));
        stage.setScene(scene);
        stage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args)
    {
        launch(args);
    }

}

最佳答案

首先是一些 Javadocs :)

A Canvas node is constructed with a width and height that specifies the size of the image into which the canvas drawing commands are rendered. All drawing operations are clipped to the bounds of that image.

因此每次用户调整窗口大小时,我们都需要更改 Canvas 的宽度,然后我们需要重新绘制 Canvas 。

让我们从向根布局添加一个 fx:id 开始。

<AnchorPane fx:id="anchorPane" prefHeight="600.0" prefWidth="750.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="app.MainFXMLController">
    <children>
        <Canvas fx:id="mainCanvas" height="565.0" onMouseClicked="#drawClicked" width="750.0"   AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="35.0"/>
    </children>
</AnchorPane>

下一步是向根布局添加一个更改监听器,它将新的高度和宽度设置到 Canvas ,然后重新绘制它。我们可以在 Controller 的 initialize() 中完成。

public class Controller implements Initializable {

    @FXML
    AnchorPane anchorPane;

    @FXML
    private Canvas mainCanvas;

    @FXML
    public GraphicsContext gc;

    public void initGraphics() {
        gc = mainCanvas.getGraphicsContext2D();
    }

    public void drawClicked() {
        gc.clearRect(0, 0, mainCanvas.getWidth(), mainCanvas.getHeight());
        gc.setFill(Color.BLACK);
        gc.fillRect(0, 0, mainCanvas.getWidth(), mainCanvas.getHeight());
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        initGraphics();

        anchorPane.prefWidthProperty().addListener((ov, oldValue, newValue) -> {
            mainCanvas.setWidth(newValue.doubleValue());
            drawClicked();
        });

        anchorPane.prefHeightProperty().addListener((ov, oldValue, newValue) -> {
            mainCanvas.setHeight(newValue.doubleValue());
            drawClicked();
        });
    }
}

我还没有为 reDraw() 创建新方法,因为您的 drawClicked() 没有做任何事情。但是,一旦更有意义,您可以将这两种方法分开。

最后一件事是将根布局的 prefWidthProperty()prefHeightProperty() 分别绑定(bind)到场景的宽度和高度。

public class Main extends Application {
    public static void main(String[] args) {
        launch(args);
    }
    @Override
    public void start(Stage stage) throws IOException {
        AnchorPane root = FXMLLoader.load(getClass().getResource("MainFXML.fxml"));

        Scene scene = new Scene(root);

        stage.setTitle("DrawFx");
        stage.setScene(scene);
        stage.show();

        root.prefWidthProperty().bind(scene.widthProperty());
        root.prefHeightProperty().bind(scene.heightProperty());
    }
}

关于JavaFX 在 fxml 中调整 Canvas 大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33534616/

相关文章:

javascript - KonvaJS - group.clip() 之后没有变压器更新

java - 为什么在 spring 3.1 和 hibernate 4 中找不到当前线程异常的这个 No Session

javascript - 动态调整高度

用于 SQL 更新语句的 Java 单工作线程

javascript - 在 html 选择元素中显示空值

jquery - 在元素的每个实例上更新 JQuery 变量

javascript - 如何动态调整 Flash CreateJS Canvas 元素动画的大小和居中

canvas - 查找在等距交错列系统中单击了哪个图 block

java - HttpSession 中的同步是否可行?

java - 如何通过maven编译classes排除注解