我的大脑即将爆炸。我是java的新手,到目前为止自学成才,但我真的想让这段代码工作。我也不是最了解java文档的人。
我正在尝试创建一个游戏循环,用户可以通过单击按钮自由遍历switch语句。
但是,之前,当我的gameloop方法被调用时,它使用当前设置运行代码,而不让我使用按钮来遍历switch语句。
我认为这是因为我的“选择”变量没有附加动作监听器(因为监听器会使程序坐在项目上,等待某事发生?)。不幸的是,我的选择变量是一个String变量,你不能将actionlistener附加到String变量。 现在我尝试使用StringProperty类创建一个字符串对象,以便能够将动作侦听器附加到它。
但现在我甚至不知道如何将StringProperty与switch语句一起使用,我只是觉得我在错误的轨道上。
我想要完成的是否有意义? 有人可以帮我创建一个游戏循环,用户可以通过单击按钮自由遍历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:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.effect.*?>
<?import javafx.scene.image.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
<children>
<BorderPane layoutX="163.0" layoutY="82.0" prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: black;" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<bottom>
<GridPane BorderPane.alignment="CENTER">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Button fx:id="button1" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#button1" onMouseClicked="#button1" style="-fx-background-color: black; -fx-border-color: grey;" text="Button" textFill="WHITE" />
<Button fx:id="button2" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#button2" style="-fx-background-color: black; -fx-border-color: grey;" text="Button" textFill="WHITE" GridPane.rowIndex="1" />
<Button fx:id="button3" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#button3" style="-fx-background-color: black; -fx-border-color: grey;" text="Button" textFill="WHITE" GridPane.rowIndex="2" />
</children>
</GridPane>
</bottom>
<center>
<TextArea fx:id="textArea" editable="false" prefHeight="200.0" prefWidth="200.0" promptText="..." style="-fx-border-color: grey;" wrapText="true" BorderPane.alignment="CENTER" />
</center>
<top>
<Label fx:id="label" text="Chapter 1" textFill="WHITE" BorderPane.alignment="CENTER" />
</top>
<left>
<ImageView fx:id="image1" fitHeight="75.0" fitWidth="75.0" pickOnBounds="true" preserveRatio="true" BorderPane.alignment="CENTER" />
</left>
<right>
<ImageView fx:id="image2" fitHeight="75.0" fitWidth="75.0" pickOnBounds="true" preserveRatio="true" BorderPane.alignment="CENTER" />
</right></BorderPane>
</children>
</AnchorPane>
主:
package sample;
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 {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 800, 500));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
答案 0 :(得分:1)
在按钮事件处理程序中注册侦听器是无稽之谈。使用侦听器来修改他们听到的属性更糟糕。传递属性作为switch
的参数甚至都不会编译。
在这种情况下,进行此项工作的最小修改是在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()) {
...
}
...
}
}
但请注意,您将以这种方式获得大量重复代码。最好提出一种数据结构来存储游戏数据,而不是硬编码一切。
E.g。
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);
}
}
...
<Button fx:id="button1" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#button" style="-fx-background-color: black; -fx-border-color: grey;" text="Button" textFill="WHITE" />
<Button fx:id="button2" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#button" style="-fx-background-color: black; -fx-border-color: grey;" text="Button" textFill="WHITE" GridPane.rowIndex="1" />
<Button fx:id="button3" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#button" style="-fx-background-color: black; -fx-border-color: grey;" text="Button" textFill="WHITE" GridPane.rowIndex="2" />
...
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);