我在大学的教授给我布置了这个作业(job),在课堂上开始一个新话题.只是一个简单的图形用户界面,应该显示图表.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 draw功能曲线() {
        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 功能曲线 extends Application {
    public 功能曲线() { }
    @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 主要
{
    private 主要() {}

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

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

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.控制器">
  <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 控制器 {

    @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.draw功能曲线();

    }
}

我几乎try 过我在网上遇到的所有解决方案,但每当我运行应用程序时,带有图形的画布都不会显示.我正在与TLR IDEA合作,如果这可能有关系的话..

推荐答案

package 做cumentation for javafx.scene.layout中详细描述的PFA布局机制的意义上来说,Canvas不是一个可调整大小的 node .

特别是:

另一方面,不可调整大小的 node 类没有一致的MIDI API,因此它们的父类不会在布局期间调整大小.应用程序必须通过在每个实例上设置适当的属性来建立不可调整大小的 node 的大小.这些类返回其当前的min、RST和max布局边界,并且resize()方法变得不操作.

这意味着简单地初始化包含画布的AnchorPane(通过设置其首选的宽度和高度)不会对画布的大小产生影响.相反,正如上面的文档中所述,您"must establish the size of non-resizable nodes [the canvas] by setting appropriate properties on each instance".画布上的"appropriate properties"只是widthheight.

所以你只需要

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

    }
}

顺便说一句,请注意,您基本上可以在FML中完成所有这些:不需要修改控制器中的场景图.而不是

      <AnchorPane fx:id="_canvas" prefHeight="600.0" prefWidth="400.0" />

        <AnchorPane>
            <FunctionCanvas fx:id="c" width="400" height="300" />
        </AnchorPane>

(您需要将<?import Aufgabe1.jfx.FunctionCanvas?>添加到FML序言中),然后在控制器中您需要的只是

public class Controller {

    @FXML
    private FunctionCanvas c ;

    public void initialize() {
        c.drawFunctionCurve();
    }
}

Java相关问答推荐

使用json参数通过单击jSP文件中的按钮来运行server时出现问题

是否可以从@ TrustMapping中删除特定方法的基路径?

JPackage-results已安装-如何添加系统属性?

Android视图覆盖不阻止点击它后面的控件

为什么BasicComboBoxRenderer在文本不存在或文本为空的情况下设置两次文本?

调用引发泛型异常的泛型方法时出现编译错误

测试期间未执行开放重写方法

Java流传输一个列表并创建单个对象

按属性值从流中筛选出重复项

对字符串长度进行排序,但颠倒了顺序(最长字符串在前)

尽管通过中断请求线程死亡,但线程仍将继续存在

Spring Boot中的应用程序.properties文件中未使用的属性

是否有一个Java Future实现可以在池繁忙时在调用者线程中执行?

在线程Java中调用Interrupt()之后调用Join()

RestTemplate Bean提供OkHttp3ClientHttpRequestFactory不支持Spring Boot 3中的请求正文缓冲

为什么创建Java动态代理需要接口参数

将基于实例编号的对象列表拆分为新的对象列表

java21预览未命名的符号用于try-with-resources

如何从指定某些字段的父对象创建子对象

在不带instanceof或switch的java中记录模式