【问题标题】:Only the newest javafx button object works只有最新的 javafx 按钮对象有效
【发布时间】:2023-01-12 04:42:51
【问题描述】:

我试图通过创建一个新窗口和按钮等来创建一个“克隆”自身的程序。我的问题是只有最新创建的按钮起作用。以前制作的窗口只会产生一个错误,而不是一个窗口。

HelloController.java

package com.example.vboxes;

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Screen;
import javafx.stage.Stage;

import java.io.IOException;
import java.util.Random;

import static javafx.stage.StageStyle.DECORATED;

public class Controller
{
    public static Random rand = new Random();
    public static Rectangle2D bounds = Screen.getPrimary().getVisualBounds();
    public HelloApplication hello = new HelloApplication();
    public VBox[] boxes = new VBox[99999];
    public Scene[] scenes = new Scene[99999];
    public Stage[] stages = new Stage[99999];
    public static int i = 0;
    @FXML
    private VBox box;
    @FXML
    public Button button;
    @FXML
    private Label text;
    @FXML
    protected void onClick() throws IOException
    {
        boxes[i] = new VBox();
        scenes[i] = new Scene(hello.loader.load(), 320, 240);
        stages[i] = new Stage(DECORATED);
        stages[i].setScene(scenes[i]);
        stages[i].setTitle("Dont click too many!");
        stages[i].show();
        double x = bounds.getMinX() + (bounds.getWidth() - scenes[i].getWidth());
        double y = bounds.getMinY() + (bounds.getHeight() - scenes[i].getHeight());
        stages[i].setX(rand.nextDouble(x));
        stages[i].setY(rand.nextDouble(y));
        System.out.println(i);
        i++;
    }
}

HelloApplication.java

package com.example.vboxes;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.io.IOException;

public class HelloApplication extends Application
{
    public FXMLLoader loader = new FXMLLoader(getClass().getResource("hello-view.fxml"));

    @Override
    public void start(Stage stage) throws IOException
    {
        Scene scene = new Scene(loader.load(), 320, 240);
        stage.setTitle("Don't exit!");
        stage.setScene(scene);
        stage.show();
    }
    public static void main(String[] args)
    {
        launch();
    }
}

你好-view.fxml

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

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.VBox?>

<?import javafx.scene.control.Button?>
<VBox fx:id="box" alignment="CENTER" spacing="20.0" xmlns:fx="http://javafx.com/fxml"
      fx:controller="com.example.vboxes.HelloController">
    <padding>
        <Insets bottom="20.0" left="20.0" right="20.0" top="20.0"/>
    </padding>

    <Label fx:id="text"/>
    <Button fx:id="buttons" text="Click me and more will appear!" onAction="#onClick"/>
</VBox>

HelloController.java

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>VBOXES</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>VBOXES</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <junit.version>5.8.2</junit.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>17.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>17.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-web</artifactId>
            <version>17.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-media</artifactId>
            <version>17.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.controlsfx</groupId>
            <artifactId>controlsfx</artifactId>
            <version>11.1.1</version>
        </dependency>
        <dependency>
            <groupId>com.dlsc.formsfx</groupId>
            <artifactId>formsfx-core</artifactId>
            <version>11.3.2</version>
            <exclusions>
                <exclusion>
                    <groupId>org.openjfx</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>net.synedra</groupId>
            <artifactId>validatorfx</artifactId>
            <version>0.2.1</version>
            <exclusions>
                <exclusion>
                    <groupId>org.openjfx</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.kordamp.ikonli</groupId>
            <artifactId>ikonli-javafx</artifactId>
            <version>12.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.kordamp.bootstrapfx</groupId>
            <artifactId>bootstrapfx-core</artifactId>
            <version>0.4.0</version>
        </dependency>
        <dependency>
            <groupId>eu.hansolo</groupId>
            <artifactId>tilesfx</artifactId>
            <version>11.48</version>
            <exclusions>
                <exclusion>
                    <groupId>org.openjfx</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.github.almasb</groupId>
            <artifactId>fxgl</artifactId>
            <version>17</version>
            <exclusions>
                <exclusion>
                    <groupId>org.openjfx</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.10.1</version>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>0.0.8</version>
                <executions>
                    <execution>
                        <!-- Default configuration for running with: mvn clean javafx:run -->
                        <id>default-cli</id>
                        <configuration>
                            <mainClass>com.example.vboxes/com.example.vboxes.HelloApplication</mainClass>
                            <launcher>app</launcher>
                            <jlinkZipName>app</jlinkZipName>
                            <jlinkImageName>app</jlinkImageName>
                            <noManPages>true</noManPages>
                            <stripDebug>true</stripDebug>
                            <noHeaderFiles>true</noHeaderFiles>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

我尝试创建一个按钮数组,每个按钮都起作用,但我无法弄清楚如何将按钮数组链接到 hello-view.fxml

【问题讨论】:

  • 你能发布你的HelloController吗? (您改为发布了 pom.xml。)
  • 或者 Controller 类应该是 HelloController 类?
  • 无论如何,这段代码有很多错误。如果您尝试按同一个按钮两次,难道不会出现异常吗?您最终会尝试使用相同的FXMLLoader,但您不能这样做,因为当根已设置时您无法重新加载。当您不知道将要有的数字时,为什么要使用数组而不是列表?您从未使用过的 boxes 数组的用途是什么? (事实上​​ ,您为什么认为您需要跟踪所有场景和窗口?您始终可以从相关控制器访问它们。)
  • 此外,阵列并没有像您认为的那样工作。每一个控制器有自己的所有数组副本,如果在与该控制器对应的 UI 中按下按钮,则每个数组中只有一个元素会被初始化。根本不清楚这段代码应该做什么。

标签: java javafx


【解决方案1】:

我真的不明白你写的很多代码的目的。如果您只是希望控制器能够重新加载相同的 FXML,您可以在按钮处理程序中完全这样做。

如果您尝试使用同一个按钮两次,您编写的代码就会失败。原因是每个控制器实例都有一个对 HelloApplication 类实例的引用,并通过该引用访问该对象公开的 FXMLLoader 实例。

(顺便说一句,实例化 Application 类总是错误的。)

因此,如果您按同一个按钮两次,您将尝试在同一个 FXMLLoader 实例上调用 load(...) 两次,这将不起作用,至少对于您的设置而言,因为 FXMLLoader 无法加载您的 FXML 文件当根已设置时(它将来自先前调用load())。 (您可能可以通过在加载器上调用 setRoot(null) 来解决这个问题,但是 FXMLLoader 根本就不是设计为以这种方式使用的。)

这是 Application 类的工作版本:

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.io.IOException;

public class HelloApplication extends Application
{

    @Override
    public void start(Stage stage) throws IOException
    {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("hello-view.fxml"));
        Scene scene = new Scene(loader.load(), 320, 240);
        stage.setTitle("Don't exit!");
        stage.setScene(scene);
        stage.show();
    }
    public static void main(String[] args)
    {
        launch();
    }
}

然后你在控制器中所需要的就是

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Screen;
import javafx.stage.Stage;

import java.io.IOException;
import java.util.Random;

import static javafx.stage.StageStyle.DECORATED;

public class HelloController
{
    private static final Random rand = new Random();

    // As things stand, you don't actually need any of the @FXML-annotated fields:
//    @FXML
//    private VBox box;
//    @FXML
//    private Button button;
//    @FXML
//    private Label text;

    @FXML
    protected void onClick() throws IOException
    {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("hello-view.fxml"));
        int width = 320 ;
        int height = 240 ;
        Scene scene = new Scene(loader.load(), width, height);
        Stage stage = new Stage(DECORATED);
        stage.setScene(scene);
        stage.setTitle("Dont click too many!");
        Rectangle2D bounds = Screen.getPrimary().getBounds();
        double x = bounds.getMinX() + (bounds.getWidth() - width);
        double y = bounds.getMinY() + (bounds.getHeight() - height);
        stage.setX(rand.nextDouble(x));
        stage.setY(rand.nextDouble(y));
        stage.show();
    }
}

如果你想避免第二次对 FXML 的位置进行硬编码,你可以将它注入到控制器中:

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Screen;
import javafx.stage.Stage;

import java.io.IOException;
import java.net.URL;
import java.util.Random;

import static javafx.stage.StageStyle.DECORATED;

public class HelloController
{
    private static final Random rand = new Random();

    @FXML
    private URL location;
    @FXML
    protected void onClick() throws IOException
    {
        FXMLLoader loader = new FXMLLoader(location);
        int width = 320 ;
        int height = 240 ;
        Scene scene = new Scene(loader.load(), width, height);
        Stage stage = new Stage(DECORATED);
        stage.setScene(scene);
        stage.setTitle("Dont click too many!");
        Rectangle2D bounds = Screen.getPrimary().getBounds();
        double x = bounds.getMinX() + (bounds.getWidth() - width);
        double y = bounds.getMinY() + (bounds.getHeight() - height);
        stage.setX(rand.nextDouble(x));
        stage.setY(rand.nextDouble(y));
        stage.show();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-13
    • 2022-06-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多