首页 > 解决方案 > JavaFX和Controller,如何根据来自服务器的消息改变场景?

问题描述

我创建了一个测验应用程序,它是一个多客户端服务器应用程序(TCP)。服务器向客户端发送消息,并根据消息客户端遵循某些指令。这与 Swing 配合得非常好。但是我想使用 Scene Builder 将应用程序实现到 JavaFX。

我创建了不同的 fxml 文件,以便我可以有不同的场景。我已经创建了一个方法(loadUI(String fxmlFile))在 Controller 类中,它允许我通过按一下按钮来交换场景。我已经对其进行了测试并且它可以工作。

当我们从服务器向客户端(在控制器中)发送消息时,消息循环并且场景不会交换。

每当我调用 loadUI 时,控制器类是否会以某种方式实例化?

这是我的控制器类:

public class Controller implements Runnable {

Socket socket = new Socket("localhost", 56565); // 172.20.201.169
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
Thread thread = new Thread(this);

@FXML
private Button altButton1 = new Button();
@FXML
private Button altButton2 = new Button();
@FXML
private Button altButton3 = new Button();
@FXML
private Button altButton4 = new Button();

@FXML
private Button continueButton = new Button();

List<Button> buttons = new ArrayList<>();

public Controller() throws IOException {
    System.out.println("Constructor");
    thread.start();
}


public void listOfButtons() {
    buttons.add(altButton1);
    buttons.add(altButton2);
    buttons.add(altButton3);
    buttons.add(altButton4);
}

public void handleAnswers(ActionEvent event) {
    listOfButtons();
    Button temp = (Button) event.getSource();

    if (event.getSource().equals("Peter")) {
        temp.getStyleClass().add("button_right");
    } else {
        temp.getStyleClass().add("button_wrong");
        for (Button button : buttons) {
            if (button.getText().equals("Peter")) {
                button.getStyleClass().add("button_right");
                break;
            }
        }
    }

    for (Button button : buttons) {
        button.setDisable(true);
        button.setOpacity(1);
    }
    continueButton.setVisible(true);
    System.out.println(temp.getText());
}

/**
 * Method swaps Scene
 *
 * @param fxmlFile
 * @throws IOException
 */
public void loadUI(String fxmlFile) throws IOException {

    Parent root = FXMLLoader.load(getClass().getResource(fxmlFile));
    Scene tempScene = new Scene(root);

    ObservableList<Window> windows = Stage.getWindows();

    for (Window window : windows) {
        System.out.println(window);
    }

    Stage window = (Stage) windows.get(0);
    window.setScene(tempScene);
    window.show();
}

public void continueToNextQuestion() {

    continueButton.setVisible(false);

    for (Button button : buttons) {
        button.setDisable(false);
        button.getStyleClass().remove("button_wrong");
        button.getStyleClass().remove("button_right");
    }
}

public void continueFromWait() {
    try {
        loadUI("question.fxml");
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private void showTheMessageFromServer(String message) throws IOException {
    if (message.startsWith("Welcome")) {
        message = message.substring(message.indexOf(' '));
        if (message.contains("1")) {
            loadUI("category.fxml");
        } else {
            loadUI("wait.fxml");
        }
    } else {
        loadUI("question.fxml");
    }
}//showTheMessageFromTheServer

@Override
public void run() {
    Object obj;

    try {
        while ((obj = in.readObject()) != null) {
            if (obj instanceof Question) {
                Question question = (Question) obj;
                //   showTheQuestion(question);

            } else if (obj instanceof String) {
                String message = (String) obj;
                System.out.println(message);
                showTheMessageFromServer(message);

            } else if (obj instanceof Integer[]) {
                Integer[] points = (Integer[]) obj;
                // showThePoints(points);
            }
        }//while

    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }

}
}

这是我的主要课程:

public class Main extends Application {


@Override
public void start(Stage primaryStage) throws Exception {
    Parent root = FXMLLoader.load(getClass().getResource("question.fxml"));
    primaryStage.setTitle("QuizApp");
    primaryStage.setScene(new Scene(root, 800, 500));
    primaryStage.show();
    primaryStage.setResizable(false);
}


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

输出: 构造函数欢迎: 玩家 1 构造函数欢迎: 玩家 2 构造函数欢迎: 玩家 1 构造函数欢迎: 玩家 2 构造函数欢迎: 玩家 1

标签: multithreadingjavafxserverclientfxml

解决方案


推荐阅读