温馨提示:本文翻译自stackoverflow.com,查看原文请点击:java - How to fix this bug in JavaFX that the value changes?
debugging java javafx

java - 如何修复JavaFX中值更改的错误?

发布于 2020-04-10 17:27:00

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

主要:

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

控制器:

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>

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

查看更多

提问者
Mindmax
被浏览
115
jayaram S 2020-02-02 05:53

因此,将此添加到您的控制器

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

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

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

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

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

无论哪种方式,都必须在控制器外部初始化GuessingGame并将其传入。

当然,您可以保留单个控制器模型,并将其传递给所有三个场景。但是,您将不会在fxml中配置操作。

希望这会有所帮助。