如何为我的JavaFX Application添加一个reset / restart按钮以重置场景?

时间:2019-07-14 01:44:42

标签: java javafx

我即将完成我的第一个JavaFX应用程序,它只不过是带有GUI的简单计算工具而已。该程序执行以下操作:

  • 打印两个随机生成的整数
  • 让我插入这两个数字的分数
  • 打印声明我的插入式答案是否正确

但是,我没有设法弄清楚如何实现“重置”或“重启”按钮,以避免每次都关闭程序。

这是我的代码:

package sample;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;


import java.io.InputStream;

public class Game extends Application implements EventHandler<ActionEvent> {

    private Button button;

    @Override
    public void start(Stage primaryStage) throws Exception {
        primaryStage.setTitle("Pot Odds Trainer");

        Class<?> genericClass = this.getClass();
        InputStream input1 = genericClass.getResourceAsStream("img/chipsGREEN.png");
        InputStream input2 = genericClass.getResourceAsStream("img/chipsREDsmall.png");
        InputStream input3 = genericClass.getResourceAsStream("img/01ACE.png");
        InputStream input4 = genericClass.getResourceAsStream("img/01ACE.png");
        InputStream input5 = genericClass.getResourceAsStream("img/chipsBLUE03small.png");
        InputStream input6 = genericClass.getResourceAsStream("img/chipsGREENstack.png");

        Image image1 = new Image(input1);
        ImageView imageView1 = new ImageView(image1);
        Image image2 = new Image(input2);
        ImageView redChips = new ImageView(image2);
        Image image3 = new Image(input3);
        ImageView imageView3 = new ImageView(image3);
        Image image4 = new Image(input4);
        ImageView imageView4 = new ImageView(image4);
        Image image5 = new Image(input5);
        ImageView blueChipsStack = new ImageView(image5);
        Image image6 = new Image(input6);
        ImageView greenChipStack = new ImageView(image6);

        Button buttonRotate = new Button("Rotate");
        buttonRotate.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                double value = imageView1.getRotate();
                imageView1.setRotate(value + 30);
            }
        });

        button = new Button("Text of Button");

        Button buttonRestart = new Button("Restart");
        buttonRestart.setOnAction((ActionEvent event) -> {
            ((Node) (event.getSource())).getScene().getWindow().hide();
        });

        button.setOnAction(this);

        GridPane gridPane = new GridPane();
        gridPane.setHgap(10);
        gridPane.setVgap(10);
        gridPane.setGridLinesVisible(false);

        int potSizeValue = Potsize.getPotSize();
        int betSizeValue = Potsize.getBetSize();
        int stackSizeValue = Potsize.getStackSize();

        Potsize potsize = new Potsize(potSizeValue);
        Potsize betsize = new Potsize(betSizeValue);
        Potsize stacksize = new Potsize(stackSizeValue);

        Label potsizeText = new Label("Der Pot liegt bei: ");
        Label betsizeText = new Label("Ein Call beträgt: ");
        Label stacksizeText = new Label("Dein Stack liegt bei: ");

        Label potOddsLabel = new Label("Pot Odds:");
        Label textConfirm = new Label();

        Button submitButton = new Button("Submit");
        TextField potOddsTextField = new TextField();
        potOddsTextField.setMaxWidth(50);
        submitButton.setOnAction(e ->
                {
                    textConfirm.setText(MyMath.checkOdds(potOddsTextField.getText(), (double) betSizeValue / (potSizeValue + betSizeValue)));
                }
        );

        Label potsizeLabel = new Label(potsize.toString());
        Label stacksizeLabel = new Label(stacksize.toString());
        Label betsizeLabel = new Label(betsize.toString());

        gridPane.add(button, 0, 0, 1, 1);
        gridPane.add(buttonRotate, 2, 3, 1, 1);
        gridPane.add(imageView1, 0, 2, 1, 1);
        gridPane.add(imageView3, 4, 3, 1, 1);
        gridPane.add(imageView4, 5, 3, 1, 1);
        gridPane.add(potsizeText, 4, 5, 2, 1);
        gridPane.add(betsizeText, 4, 6, 2, 1);
        gridPane.add(stacksizeText, 4, 7, 2, 1);
        gridPane.add(potsizeLabel, 6, 5, 2, 1);
        gridPane.add(betsizeLabel, 6, 6, 2, 1);
        gridPane.add(stacksizeLabel, 6, 7, 2, 1);
        gridPane.add(blueChipsStack, 8, 5, 1, 1);
        gridPane.add(redChips, 8, 6, 1, 1);
        gridPane.add(greenChipStack, 8, 7, 1, 1);
        gridPane.add(potOddsLabel, 4, 8, 2, 1);
        gridPane.add(potOddsTextField, 6, 8, 2, 1);
        gridPane.add(submitButton, 8, 8, 1, 1);
        gridPane.add(textConfirm, 4, 9, 2, 1);
        gridPane.add(buttonRestart, 4, 11, 2, 1);


        Scene scene = new Scene(gridPane, 650, 550);
        scene.getStylesheets().add(Main.class.getResource("css/styles.css").toExternalForm());

        primaryStage.setScene(scene);
        primaryStage.show();

    }

    @Override
    public void handle(ActionEvent event) {
        if (event.getSource() == button) {
            System.out.println("Ooooooo test");

        }
    }


}
This is my Main Class:

package sample;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.GridPane;
import javafx.scene.control.Button;
import javafx.stage.Stage;
import java.io.InputStream;
import java.util.concurrent.ThreadLocalRandom;

public class Main {
    public static void main(String[] args) {

        Game game = new Game();
        game.launch(Game.class, args);

    }
}
package sample;

import java.util.concurrent.ThreadLocalRandom;

public class Potsize {

    private int size;

    public Potsize(int size){
        this.size = size;
    }

    static public int getStackSize(){
        return (int)MyMath.round(ThreadLocalRandom.current().nextInt(100, 2500 + 1));
    }

    static public int getPotSize(){
        return (int)MyMath.round(ThreadLocalRandom.current().nextInt(100, 1000 + 1));
    }

    static public int getBetSize(){
        return (int)MyMath.round(MyMath.divide(getPotSize(),  ThreadLocalRandom.current().nextInt(2, 10 + 1)));
    }

    public void setPotSize(int size){
        this.size = size;
    }

    public void setBetSize(int size){
        this.size = size;
    }

    public void setStackSize(int size){
        this.size = size;
    }

    public String toString() {
        return ""+ size;
    }

}

我已经读过很多类似的问题,但不幸的是,到目前为止,没有一个问题对我有帮助。

目前,我在“ buttonRestart”上有一个ActionEvent,它关闭了我的程序-但是,那不是我想要的。我希望场景可以简单地重置/重新启动,以便进行“下一次尝试”。

有人可以帮助我吗?

非常感谢!

3 个答案:

答案 0 :(得分:2)

没有通用的方法可以轻松地做到这一点:代码可以例如在某些情况下,调用from collections import OrderedDict timeDict = my_dictionary() filename = 'name' t = [0, 1, 2] timeDict.add(filename, t) 并在当时无法防止GUI关闭。

在某些情况下,取决于代码,可以将阶段传递给Platform.exit方法:

start

start(primaryStage);

但是一般来说,我建议将场景中发生变化的事物重置为原始状态:

primaryStage.hide();
start(new Stage());

如果private Label potsizeLabel; private Label stacksizeLabel; private Label betsizeLabel; private void initPot() { int potSizeValue = Potsize.getPotSize(); int betSizeValue = Potsize.getBetSize(); int stackSizeValue = Potsize.getStackSize(); Potsize potsize = new Potsize(potSizeValue); Potsize betsize = new Potsize(betSizeValue); Potsize stacksize = new Potsize(stackSizeValue); potsizeLabel.setText(potsize.toString()); stacksizeLabel.setText(stacksize.toString()); betsizeLabel.setText(betsize.toString()); } @Override public void start(Stage primaryStage) throws Exception { ... buttonRestart.setOnAction((ActionEvent event) -> { // change node properites that could have been modified to their's original states imageView1.setRotate(0); textConfirm.setText(""); // redo Potsize thing initPot(); }); ... potsizeLabel = new Label(); stacksizeLabel = new Label(); betsizeLabel = new Label(); initPot(); ... } 类在静态成员中包含状态,则还需要重设此状态(但最好首先避免这种情况;请注意,这也可能会阻止第一种方法工作正常)。


我不确定Potsize类的职责,但是目前唯一的目的(忽略Potsize成员)似乎是将static转换为{{1 }},无需创建该类的实例;如果将int转换为包含十进制表示形式的字符串,则可以使用String。否则,Integer.toString(potSizeValue)方法就足够了。

答案 1 :(得分:1)

我看不到您的Potsize类,但我认为您必须重置此值

int potSizeValue = Potsize.getPotSize();
int betSizeValue = Potsize.getBetSize();
int stackSizeValue = Potsize.getStackSize();

Potsize potsize = new Potsize(potSizeValue);
Potsize betsize = new Potsize(betSizeValue);
Potsize stacksize = new Potsize(stackSizeValue);

然后在GridPane上刷新

gridPane.add(potsizeLabel, 6, 5, 2, 1);
gridPane.add(betsizeLabel, 6, 6, 2, 1);
gridPane.add(stacksizeLabel, 6, 7, 2, 1);

答案 2 :(得分:0)

前两个链接提供有关实现场景的刷新选项的StackOverflow源代码。最后一个链接涉及Oracle教程中的JavaFX多线程,如果您不想完全关闭JavaFX应用程序只是为了刷新场景,则可能需要考虑使用该选项。

单击重新启动应用程序。 How to restart a JavaFX application when a button is clicked

重新加载JavaFX应用程序 How to reload an Application in JavaFX?

如果场景位于包含主JavaFX应用程序的主线程中,则可能没有快速重新加载场景的解决方案。您应该创建一个新线程并将场景放置在该线程中,停止同一线程以根据需要更新场景,然后使用更新后的场景启动新线程。这是JavaFX的并发(多线程)链接。

JavaFX中的并发 https://docs.oracle.com/javase/8/javafx/interoperability-tutorial/concurrency.htm

P.S。顺便说一下,几个月前,我构建了几个JavaFX gui应用程序来获取用户文件信息并处理文件。我也想让应用程序保持打开状态,但是找不到Oracle资源。