有人可以帮我找出为什么我的画布没有显示在我的 JavaFX 应用程序中吗?

问题描述 投票:0回答:1

我的大学教授布置了这个作业,以在课堂上开始一个新主题。只是一个简单的 GUI,应该显示一个图表。我们的教授准备了 3 个文件:

功能画布

package Aufgabe1.jfx;

import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;

final class FunctionCanvas extends Canvas
{
    private double c1 = 1, d1 = 0, c2 = 1, d2 = 0;

    void setFunctionParameters(double c1, double d1, double c2, double d2)
    {
        this.c1 = c1;
        this.d1 = d1;
        this.c2 = c2;
        this.d2 = d2;
    }

    FunctionCanvas() {}

    private static final float v = 244f / 255;
    private static final Color backGroundColor = Color.color(0, 0, 0);
    private static final int yOffset = 20;

    void drawFunctionCurve() {
        GraphicsContext gc = getGraphicsContext2D();
        //float v = 244f / 255;
        gc.setFill(backGroundColor);
        gc.fillRect(0, 0, getWidth(), getHeight());

        double h = this.getHeight() - 2 * yOffset;
        int xOffset = 40;
        double w = this.getWidth() - 2 * xOffset;
        double yZero = yOffset + h / 2;
        gc.setFill(Color.BLACK);
        gc.fillText("f(x)", xOffset - 30, yOffset);
        gc.fillText("0", xOffset - 25, yZero + 5);
        gc.fillText("2\u03c0", xOffset + w - 5, yZero - 5);
        gc.setLineWidth(1.0);
        gc.setStroke(Color.GRAY);
        gc.strokeLine(xOffset, yOffset, xOffset, yOffset + h);
        gc.strokeLine(xOffset, yZero, xOffset + w, yZero);
        gc.setLineWidth(1.5);
        gc.setStroke(Color.INDIANRED);
        for (int x = 0; x < w; x++) {
            int y = (int) ((h / 2) * sinCosFunc(x * 2 * Math.PI / w));
            gc.strokeLine(xOffset + x, yZero - y, xOffset + x, yZero - y);
        }
    }

    private double sinCosFunc(double x)
    {
        return Math.sin(c1 * x + d1) * Math.cos(c2 * x + d2);
    }
}

功能曲线

package Aufgabe1.jfx;

import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;

public class FunctionCurve extends Application {
    public FunctionCurve() { }
    @Override
    public void start(Stage stage) throws Exception {
        int width = 670;
        int height = 520;
        //Written by me
        FXMLLoader loader = new FXMLLoader(getClass().getResource("1gui.fxml"));
        Parent root = loader.load();
        Scene scene = new Scene(root, width, height);
        stage.setTitle(this.getClass().getSimpleName());
        stage.setScene(scene);
        stage.centerOnScreen();
        stage.show();

    }
}

主要

package Aufgabe1.jfx;

final class Main
{
    private Main() {}

    public static void main(String[] args)
    {
        javafx.application.Application.launch(FunctionCurve.class, args);
    }
}

我已经创建了 FXML 文件并尽我所能编写了控制器:

FXML

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

<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<SplitPane dividerPositions="0.08892617449664429" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" orientation="VERTICAL" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/17.0.2-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Aufgabe1.jfx.Controller">
  <items>
    <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0">
         <children>
            <HBox prefHeight="48.0" prefWidth="597.0">
               <children>
                  <Label prefHeight="25.0" prefWidth="25.0" text="c1">
                     <padding>
                        <Insets left="5.0" right="5.0" />
                     </padding>
                  </Label>
                  <Spinner editable="true" prefHeight="10.0" prefWidth="50.0" />
                  <Label prefHeight="25.0" prefWidth="25.0" text="d1">
                     <padding>
                        <Insets left="5.0" right="5.0" />
                     </padding>
                  </Label>
                  <Spinner editable="true" prefHeight="10.0" prefWidth="50.0" />
                  <Label prefHeight="25.0" prefWidth="25.0" text="c2">
                     <padding>
                        <Insets left="5.0" right="5.0" />
                     </padding>
                  </Label>
                  <Spinner editable="true" prefHeight="10.0" prefWidth="50.0" />
                  <Label prefHeight="25.0" prefWidth="25.0" text="d2">
                     <padding>
                        <Insets left="5.0" right="5.0" />
                     </padding>
                  </Label>
                  <Spinner editable="true" prefHeight="10.0" prefWidth="50.0" />
                  <Button mnemonicParsing="false" text="Button">
                     <HBox.margin>
                        <Insets left="5.0" right="5.0" />
                     </HBox.margin>
                  </Button>
                  <Button mnemonicParsing="false" text="reset">
                     <HBox.margin>
                        <Insets left="5.0" right="5.0" />
                     </HBox.margin>
                  </Button>
               </children>
            </HBox>
         </children></AnchorPane>
      <AnchorPane fx:id="_canvas" prefHeight="600.0" prefWidth="400.0" />
  </items>
</SplitPane>

控制器

package Aufgabe1.jfx;

import javafx.fxml.FXML;
import javafx.scene.layout.AnchorPane;

public class Controller {

    @FXML
    private AnchorPane _canvas ;

    // called by the FXML loader after the labels declared above are injected:
    public void initialize() {
        FunctionCanvas c = new FunctionCanvas();
        _canvas.setPrefWidth(400);
        _canvas.setPrefHeight(300);
        _canvas.getChildren().add(c);
        c.drawFunctionCurve();

    }
}

我几乎尝试了在网上遇到的所有解决方案,但是每当我运行应用程序时,带有图形的画布都不会显示。我正在使用 IntelliJ IDEA,如果这可能重要的话......

java user-interface javafx canvas fxml
1个回答
0
投票

Canvas
不是一个可调整大小的节点,从 javafx.scene.layout
package 文档中详细介绍的 JavaFX 布局机制的意义上来说。

特别是:

另一方面,不可调整大小的节点类没有一致的调整大小 API,因此在布局期间不会由其父级调整大小。应用程序必须通过在每个实例上设置适当的属性来确定不可调整大小的节点的大小。这些类返回 min、pref 和 max 的当前布局边界,并且

resize()
方法变为无操作。

这意味着简单地调整包含画布的

AnchorPane
的大小(通过设置其首选宽度和高度)不会影响画布的大小。相反,如上面的文档中所述,您“必须通过在每个实例上设置适当的属性来确定不可调整大小的节点[画布]的大小”。画布的 “适当属性” 只是
width
height

所以你只需要

public class Controller {

    @FXML
    private AnchorPane canvasContainer ;

    // called by the FXML loader after the labels declared above are injected:
    public void initialize() {
        FunctionCanvas c = new FunctionCanvas();
        c.setWidth(400);
        c.setHeight(300);
        canvasContainer.getChildren().add(c);
        c.drawFunctionCurve();

    }
}
© www.soinside.com 2019 - 2024. All rights reserved.