[英]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.