Button StringProperty和Switch语句Javafx

Button StringProperty和Switch语句Javafx,button,javafx,properties,switch-statement,listener,Button,Javafx,Properties,Switch Statement,Listener,我的大脑快要爆炸了。我对java非常陌生,到目前为止我是自学成才的,但我真的很想让这段代码发挥作用。我也不是最善于理解java文档的人 我试图创建一个gameloop,用户可以通过单击按钮自由遍历switch语句 但是,以前调用gameloop方法时,它使用当前设置运行代码,而不允许我使用按钮遍历switch语句 我认为这是因为我的“choice”变量没有附加操作侦听器(因为侦听器会让程序坐在该项上,等待发生什么事情?)。不幸的是,我的选择变量是字符串变量,您不能将actionlistener附

我的大脑快要爆炸了。我对java非常陌生,到目前为止我是自学成才的,但我真的很想让这段代码发挥作用。我也不是最善于理解java文档的人

我试图创建一个gameloop,用户可以通过单击按钮自由遍历switch语句

但是,以前调用gameloop方法时,它使用当前设置运行代码,而不允许我使用按钮遍历switch语句

我认为这是因为我的“choice”变量没有附加操作侦听器(因为侦听器会让程序坐在该项上,等待发生什么事情?)。不幸的是,我的选择变量是字符串变量,您不能将actionlistener附加到字符串变量。 现在,我尝试使用StringProperty类创建一个string对象,以便能够将动作侦听器附加到它

但现在我甚至不知道如何在switch语句中使用StringProperty,我只是觉得我走错了方向

我想完成的事情有意义吗? 有谁能帮我创建一个gameloop,用户可以通过点击按钮自由遍历switch语句? ♥♥♥!

这是我的密码:

控制器:

package sample;

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import java.net.URL;
import java.util.ResourceBundle;
import static java.lang.System.out;

public class Controller implements Initializable {

    public String question;
    public StringProperty choice = new SimpleStringProperty(this, "choice", "");

    // this code starts when the XML file is loaded.
    @Override
    public void initialize(URL location, ResourceBundle resources) {
        question = "0";
        gameloop();

    } public String getChoice() {
        return choice.get();
    }

    public StringProperty choiceProperty() {
        return choice;
    }

    public void setChoice(String choice) {
        this.choice.set(choice);
    }
    // public String choice = "";

    public Controller() {
    }

    // Here are the buttons trying to add an actionlistener to the choice object.
    // Maybe wrong path to go
    @FXML
    public void button1() {
        choiceProperty().addListener((v, oldValue, newValue) ->{setChoice("c1");});


    }

    @FXML
    public void button2() {
        choiceProperty().addListener((v, oldValue, newValue) ->{setChoice("c2");});
        out.println(choice); //think this prints out where it is stored in the memory

    }

    @FXML
    public void button3() {
        choiceProperty().addListener((v, oldValue, newValue) ->{setChoice("c3");});
        out.println(choice);

    }

    //this block of code does not work because of the switch (choice) statement.
    //Where "c1","c2","c3" have incompatible a type error.
    public void gameloop() {
        switch (question) {
            case "0":
                switch (choice) {
                    case "c1":
                        out.println("you chose 1");
                        question = "1";
                        break;
                    case "c2":
                        out.println("you chose 2");
                        break;
                    case "c3":
                        out.println("you chose 3");
                        break;
                }
            case "1":
                switch (choice) {
                    case "c1":
                        out.println("you chose a");
                        question = "0";
                        break;
                    case "c2":
                        out.println("you chose b");
                        break;
                    case "c3":
                        out.println("you chose c");
                        break;
                }
        }
    }
}
FXML:


主要内容:


在按钮事件处理程序中注册侦听器是毫无意义的。使用侦听器修改其侦听的属性更糟糕。将属性作为
开关的参数传递
甚至不会编译

在这种情况下,进行此操作的最小修改是在
initialize
方法中注册一个侦听器,从该侦听器调用
gameloop
方法,并使用存储在属性中的值作为开关的参数

@Override
public void initialize(URL location, ResourceBundle resources) {
    question = "0";
    gameloop();

    choiceProperty().addListener((observable, oldValue, newValue) -> gameloop());
}

...

@FXML
private void button1() {
    setChoice("c1");
}

...

public void gameloop() { 
    switch (question) {
        case "0":
            switch (choice.get()) {
                ...
            }
        ...
    }
}

但是请注意,这样会得到大量重复的代码。最好拿出一个数据结构来存储游戏数据,而不是硬编码

例如

公共类控制器{
私人游戏数据;
@FXML
私人按钮按钮1、按钮2、按钮3;
专用按钮[]按钮;
@FXML
私有void初始化(){
按钮=新按钮[]{button1,button2,button3};
}
公共无效setGameData(GameData GameData){
this.gameData=gameData;
gameData.questionProperty().addListener((可观察、旧值、新值)->setQuestion(新值));
setQuestion(gameData.getQuestion());
}
私人问题(问题){
System.out.println(question.getText());
用于(按钮b:按钮){
b、 setVisible(假);
}
对于(inti=0,max=Math.min(buttons.length,question.getChoices().size());i
。。。
...
fxmloader=newfxmloader(getClass().getResource(“sample.fxml”);
父根=loader.load();
映射问题=新HashMap();
问题。提出(0,新问题(“0”),
新选择(1,“1”),
新选择(0,“2”),
新选择(0,“3”)
));
问题。提出(1,新问题(“1”),
新选择(0,“a”),
新选择(1,“b”),
新选择(1,“c”)
));
GameData数据=新GameData(0,问题);
loader.getController().setGameData(数据);

在我目前的知识水平上,这对我来说是一个很大的收获,但我一定会把它分解,并感谢您的时间和努力!非常感谢你!
@Override
public void initialize(URL location, ResourceBundle resources) {
    question = "0";
    gameloop();

    choiceProperty().addListener((observable, oldValue, newValue) -> gameloop());
}

...

@FXML
private void button1() {
    setChoice("c1");
}

...

public void gameloop() { 
    switch (question) {
        case "0":
            switch (choice.get()) {
                ...
            }
        ...
    }
}
public class GameData {

    private final ReadOnlyObjectWrapper<Question> question;

    public ReadOnlyObjectProperty<Question> questionProperty() {
        return question.getReadOnlyProperty();
    }

    public Question getQuestion() {
        return question.get();
    }

    private final Map<Integer, Question> questions;

    public Map<Integer, Question> getQuestions() {
        return questions;
    }

    public GameData(int initialQuestion, Map<Integer, Question> questions) {
        this.questions = questions;
        this.question = new ReadOnlyObjectWrapper(questions.get(initialQuestion));
    }

    public void activateChoice(Choice choice) {
        question.set(questions.get(choice.getNextQuestion()));
    }
}
public class Question {

    private final String text;

    public String getText() {
        return text;
    }

    public Question(String text, Choice... choices) {
        this.text = text;
        this.choices = Collections.unmodifiableList(new ArrayList(Arrays.asList(choices)));
    }

    private final List<Choice> choices;

    public List<Choice> getChoices() {
        return choices;
    }

}
public class Choice {

    private final String text;
    private final int nextQuestion;

    public Choice(int nextQuestion, String text) {
        this.text = text;
        this.nextQuestion = nextQuestion;
    }

    public String getText() {
        return text;
    }

    public int getNextQuestion() {
        return nextQuestion;
    }

}
public class Controller {

    private GameData gameData;

    @FXML
    private Button button1, button2, button3;

    private Button[] buttons;

    @FXML
    private void initialize() {
        buttons = new Button[]{button1, button2, button3};
    }

    public void setGameData(GameData gameData) {
        this.gameData = gameData;
        gameData.questionProperty().addListener((observable, oldValue, newValue) -> setQuestion(newValue));
        setQuestion(gameData.getQuestion());
    }

    private void setQuestion(Question question) {
        System.out.println(question.getText());
        for (Button b : buttons) {
            b.setVisible(false);
        }

        for (int i = 0, max = Math.min(buttons.length, question.getChoices().size()); i < max; i++) {
            Button b = buttons[i];
            Choice c = question.getChoices().get(i);
            b.setUserData(c);
            b.setText(c.getText());
            b.setVisible(true);
        }
    }

    @FXML
    private void button(ActionEvent evt) {
        Node source = (Node) evt.getSource();
        Choice choice = (Choice) source.getUserData();

        out.println("You've chosen " + choice.getText());

        gameData.activateChoice(choice);
    }

}
FXMLLoader loader = new FXMLLoader(getClass().getResource("sample.fxml"));
Parent root = loader.load();

Map<Integer, Question> questions = new HashMap<>();

questions.put(0, new Question("0",
        new Choice(1, "1"),
        new Choice(0, "2"),
        new Choice(0, "3")
));
questions.put(1, new Question("1",
        new Choice(0, "a"),
        new Choice(1, "b"),
        new Choice(1, "c")
));

GameData data = new GameData(0, questions);

loader.<Controller>getController().setGameData(data);