簡體   English   中英

JavaFX 在 fxml 中調整畫布大小

[英]JavaFX resize canvas in fxml

我正在嘗試在 Javafx 中調整畫布的大小。 我正在使用場景構建器和 fxml。 到目前為止,當用戶單擊畫布時,畫布變黑,當我調整屏幕大小並單擊畫布時,只有畫布的原始大小變黑(畫布未調整大小)。 我不知道如何解決這個問題。 任何想法或解決方案都會有很大幫助。

代碼:

控制器:

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

    }  
}

文件格式:

<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 :)

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>

下一步是向根布局添加一個更改偵聽器,它將為畫布設置新的高度和寬度,然后重新繪制它。 我們可以在控制器的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()分別綁定到場景的寬度和高度。

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

如果你想在 fxml 中調整畫布的大小並可能在之后重繪其內容,絕對最小集是這樣的:

test.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.canvas.Canvas?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.VBox?>

<VBox xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1"
      fx:controller="test.TestController">
  <children>
    <Pane fx:id="pane" VBox.vgrow="ALWAYS">
      <children>
        <Canvas fx:id="canvas" height="${pane.height}" width="${pane.width}"
                onWidthChange="#redraw" onHeightChange="#redraw" />
      </children>
    </Pane>
  </children>
</VBox>

TestController.java

package test;

import javafx.fxml.FXML;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;

public class TestController {
  @FXML
  private Canvas canvas;

  @FXML
  private void redraw() {
    double w=canvas.getWidth();
    double h=canvas.getHeight();
    GraphicsContext gc=canvas.getGraphicsContext2D();
    gc.clearRect(0, 0, w, h);
    gc.beginPath();
    gc.rect(10, 10, w-20, h-20);
    gc.stroke();
  }
}


包裝(它不是功能的一部分,只是為了完整性而提供)

Test.java

 package test; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.stage.Stage; public class Test extends Application { @Override public void start(Stage primaryStage) throws Exception { FXMLLoader loader=new FXMLLoader(getClass().getResource("test.fxml")); Parent root=loader.load(); primaryStage.setTitle("Test"); primaryStage.setScene(new Scene(root)); primaryStage.show(); } public static void main(String[] args) { launch(args); } }

test包用於允許模塊化魔術,

module-info.java

 module cnvtest { requires transitive javafx.graphics; requires javafx.fxml; opens test to javafx.fxml; exports test; }

並且真的沒有更多文件了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM