java - 如何修复JavaFX中值发生变化的错误?

标签 java debugging javafx

我在 JavaFX 中遇到了一个小错误,需要帮助。我想在用户可以选择的范围内生成一个随机数。我选择了一个 slider ,并在用户更改它时获取 Controller 中的值并将其设置为随机数的范围。但是,当我开始检查某些用户输入是否高于或低于该数字时,界限将返回到 100(这是用户不更改 slider 时的默认值)。这是一些代码:

主要:

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

public class Main extends Application {
    public static Stage pStage;

    public static Parent root1;
    public static Parent root2;
    public static Parent root3;

    public static Scene scene1;
    public static Scene scene2;
    public static Scene scene3;

    public Main() {
    }

    @Override
    public void start(Stage stage) throws Exception {

        pStage = stage;

        root1 = FXMLLoader.load(getClass().getResource("scene1.fxml"));
        root2 = FXMLLoader.load(getClass().getResource("scene2.fxml"));
        root3 = FXMLLoader.load(getClass().getResource("scene3.fxml"));


        scene1 = new Scene(root1);
        scene2 = new Scene(root2);
        scene3 = new Scene(root3);

        stage.setScene(scene1);
        stage.show();

    }

    public static void main(String[] args) {
        launch(args);
    }
}

Controller :

import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.control.TextField;

public class Controller {

    GuessingGame guessingGame = new GuessingGame();
                    //Hier die Zufallszahl hinsetzen und auf 100 und drüben dann mit Setter und Getter abgreifen

    @FXML
    private TextField textfield;
    @FXML
    private Label countText;
    @FXML
    public Label notification;
    @FXML
    public Label textBetween;
    @FXML
    public Slider sliderSettings;

    int currentNumber;

    @FXML
    public void clickedOnExit() {
        System.exit(1);
    }
    @FXML
    public void clickedOnSettings() {
        Main.pStage.setScene(Main.scene3);
        System.out.println(guessingGame.getRandomBound());
    }
    @FXML
    public void sliderSetValue() {
        guessingGame.setRandomBound((int) sliderSettings.getValue());
        System.out.println(guessingGame.getRandomBound());
    }
    @FXML
    public void clickedBackToMenuSettings() {
        Main.pStage.setScene(Main.scene1);
        System.out.println(guessingGame.getRandomBound());
    }
    @FXML
    public void clickedOnPlay() {
        Main.pStage.setScene(Main.scene2);  //Beim wechsel zu szene 2 wird der wert wieder auf 100 gesetzt
        System.out.println(guessingGame.getRandomBound());
    }
    @FXML
    public void clickedBackToMenu() {
        Main.pStage.setScene(Main.scene1);
    }
    @FXML
    public void enteredTextfield() {

        System.out.println(guessingGame.getNumber());

        currentNumber = Integer.parseInt(textfield.getText());

        GuessingGame.Result checkNumber;

        checkNumber = guessingGame.evaluateEnteredNumber(currentNumber);

        if (checkNumber == GuessingGame.Result.HIGHER) {
            notification.setText("HIGHER");
        }
        ;
        if (checkNumber == GuessingGame.Result.LOWER) {
            notification.setText("LOWER");
        }
        ;
        if (checkNumber == GuessingGame.Result.EQUALS) {
            notification.setText("YOU GOT IT!");
            textBetween.setText("Congratulations! The number was: " + guessingGame.getNumber());
        }
        ;
        textfield.clear();
        countText.setText("" + guessingGame.getCounter());  //Gibts ihr eine bessere Lösung?
    }
}

游戏:

import java.util.Random;

public class GuessingGame {

    Random rand = new Random();

    private int number;
    private int counter;
    //Variable die maxhöhe der Zufallszahl am Anfang auf 100 Stand
    private int randomBound = 100;

    public enum Result {
        EQUALS, HIGHER, LOWER
    }

    //Random number muss noch implementiert werden, sodass sie im Bound steht
    public GuessingGame() {
        getNumberToGuess();             //Konstruktor
    }

    public int getNumberToGuess() {
        this.number = rand.nextInt(randomBound);                 //im bound muss der wert vom slide sein
        return number;
    }

    //Methode für das Spielgeschehen gibt Das Ergebnis wieder obs höher/tiefer/gleich ist
    public Result evaluateEnteredNumber(int enteredNumber) {
        Result result;

        counter++;

        if (number > enteredNumber) {
            result = Result.HIGHER;
        } else if (number < enteredNumber) {
            result = Result.LOWER;
        } else {
            result = Result.EQUALS;
        }
        return result;
    }


    //----------------------------------------------------//
    //Getter und Setter//

    //Setter und Getter für die Zufallszahl
    public void setNumber(int  newNumber) {
        this.number = newNumber;
    }
    public int getNumber() {
        return number;
    }
    //Setter und Getter für den Versuchzähler
    public void setCounter(int newCounter) {
        this.counter = newCounter;
    }
    public int getCounter() {
        return counter;
    }
    //Setter und Getter für Die maxhöhe der Zufallszahl
    public void setRandomBound(int newRandomBound) {
        randomBound = newRandomBound;
    }
    public int getRandomBound() {
        return randomBound;
    }
}

场景1:

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

        <?import javafx.scene.control.Button?>
        <?import javafx.scene.control.Label?>
        <?import javafx.scene.layout.AnchorPane?>
        <?import javafx.scene.text.Font?>


<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
<children>
   <Button fx:id="exitButton" layoutX="505.0" layoutY="349.0" mnemonicParsing="false" onAction="#clickedOnExit" prefHeight="37.0" prefWidth="81.0" text="Exit" />
   <Button fx:id="playButton" layoutX="237.0" layoutY="163.0" mnemonicParsing="false" onAction="#clickedOnPlay" prefHeight="37.0" prefWidth="126.0" text="Play" />
   <Button fx:id="settingsButton" layoutX="237.0" layoutY="213.0" mnemonicParsing="false" onAction="#clickedOnSettings" prefHeight="37.0" prefWidth="126.0" text="Settings" />
   <Label layoutX="66.0" layoutY="14.0" prefHeight="117.0" prefWidth="469.0" text="GUESSING GAME">
      <font>
         <Font name="Arial Black" size="49.0" />
      </font>
   </Label>
</children>
</AnchorPane>

场景2

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
   <children>
      <Label layoutX="72.0" prefHeight="20.0" prefWidth="457.0" text="GUESSING GAME">
         <font>
            <Font name="Arial Black" size="48.0" />
         </font>
      </Label>
      <Label layoutX="72.0" layoutY="187.0" text="Your guess:">
         <font>
            <Font name="Arial" size="22.0" />
         </font>
      </Label>
      <Label layoutX="395.0" layoutY="187.0" text="Attempts:">
         <font>
            <Font name="Arial" size="22.0" />
         </font>
      </Label>
      <TextField fx:id="textfield" layoutX="197.0" layoutY="188.0" onAction="#enteredTextfield" prefHeight="25.0" prefWidth="66.0" />
      <Label fx:id="countText" layoutX="496.0" layoutY="188.0" text="0">
         <font>
            <Font name="Arial" size="22.0" />
         </font>
      </Label>
      <Label layoutX="48.0" layoutY="71.0" text="My number is a random number up to 100! Try to guess it!">
         <font>
            <Font name="Arial Black" size="16.0" />
         </font>
      </Label>
      <Label fx:id="notification" layoutX="221.0" layoutY="120.0" text="Type a number!">
         <font>
            <Font name="Arial Black" size="22.0" />
         </font>
      </Label>
      <Label fx:id="textBetween" layoutX="72.0" layoutY="272.0" prefHeight="26.0" prefWidth="356.0" text="Your number is between 0 and 100">
         <font>
            <Font name="Arial Black" size="17.0" />
         </font>
      </Label>
      <Button fx:id="backToMenu" layoutX="485.0" layoutY="361.0" mnemonicParsing="false" onAction="#clickedBackToMenu" text="Back to Menu" />
   </children>
</AnchorPane>

场景3:

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Slider?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
   <children>
      <Slider fx:id="sliderSettings" layoutY="200.0" max="1000.0" minorTickCount="4" onMouseReleased="#sliderSetValue" prefHeight="38.0" prefWidth="592.0" showTickLabels="true" showTickMarks="true" snapToTicks="true" value="100.0" />
      <Label layoutX="4.0" layoutY="117.0" prefHeight="47.0" prefWidth="592.0" text="How High can the number you want to guess be?">
         <font>
            <Font name="Arial Black" size="22.0" />
         </font>
      </Label>
      <Button fx:id="backToMenuSettings" layoutX="497.0" layoutY="361.0" mnemonicParsing="false" onAction="#clickedBackToMenuSettings" text="Back to Menu" />
   </children>
</AnchorPane>

现在的问题是:当您与 slider 交互时,随机绑定(bind)数字会发生变化,但是当您单击播放按钮时,随机绑定(bind)会回到 100,并且还会生成一个数字 100...而不是用户的数量决定拥有( slider )

最佳答案

因此将其添加到您的 Controller

 @FXML
public void initialize() {
    System.out.println(guessingGame);
}

在你的输出中你会注意到这一点

sample.GuessingGame@29794acb
sample.GuessingGame@6cc12f4f
sample.GuessingGame@757b7ff5

本质上,由于在 fxml 中为每个场景配置了相同的 Controller ,因此每个场景都将获得自己的实例,从而获得自己的 GuessingGame 实例。

有几种方法可以解决这个问题 - 我个人的建议是将 Controller 分开,因为 fxml Controller 可能很快就会失控。

无论哪种方式,都要在 Controller 外部初始化 GuessingGame 并将其传入。

当然,您可以保留单个 Controller 模型并将其传递到所有三个场景中。但是这样您就不会将操作配置到 fxml 中。

希望这有帮助。

关于java - 如何修复JavaFX中值发生变化的错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60019567/

相关文章:

java - Spring JPA 抽象类行为

java - 封闭实例不符合垃圾收集条件的解决方法

objective-c - 如何找出谁是方法或函数的调用者?

c++ - 调试 .DLL 注入(inject)问题 - 假定执行代码未被命中的断点

c - 使用 openssl 进行 Base64 解码的一个非常奇怪的错误

java - 如何为 TableView 使用自定义 cellFactories

java - 当OutputStream的write写入字节(内部)时,为什么InputStream的read返回int?

java - 诺基亚N97相关传感器Api和一些java逻辑

java - 明确新线程启动和停止的时间和地点

java - 类/监听器之间的通信