当我调用新方法时,JavaFX FadeTransition 结束其他 SetVisbilities 停止工作
JavaFX FadeTransition end other SetVisbilities stop working when I call a new method
我想在我的应用程序的窗格中创建一个 FadeTransition。此外,通过此 FadeTransition,我将窗格内某些 JavaFX 的可见性设置为 false,以使它们消失。它工作正常,但是,当我在 FadeTransition 之后调用另一个我命名为 waitForResponse(event) 的方法时,它就停止工作了。我不知道为什么。
如果我评论 waitForResponse(event),FadeTransitions 将再次开始工作。
我认为可能是 waitForResponse(event) 中的 Socket 和 InputStreamReader 有问题,但我测试了将其取出并在该方法中制作另一个基本的东西仍然不起作用。
我进行了其他测试,发现如果我在其后放置任何 bufferedReader、其他循环或决策结构,FadeTransition 和其他可见性更改将不起作用。
我只想制作一个加载屏幕,以防止用户在加载完成之前点击任何地方。
这是代码:
public class LoadingScreenController implements Initializable {
// Socket que vai ser utilizado nos vários métodos para conversar com o servidor
private Socket cliente;
// PrintWriter que vai ser utilizado pelos vários métodos e vai passar o
// argumento para o switch case
private PrintWriter pr;
private InputStreamReader in;
private BufferedReader bf;
private String option;
private String response;
@FXML
private Button refreshButton;
@FXML
private ImageView loadingGif;
@FXML
private Label txtLabel;
@FXML
private AnchorPane rootPane;
public String getOption() {
return option;
}
public void setOption(String option) {
this.option = option;
}
@Override
public void initialize(URL url, ResourceBundle rb) {
}
@FXML
private void makeFadeInTransition() {
FadeTransition fadeTransition = new FadeTransition(Duration.seconds(1), loadingGif);
fadeTransition.setFromValue(0.0);
fadeTransition.setToValue(1.0);
fadeTransition.play();
}
@FXML
private void onRefreshButtonAction(ActionEvent event) {
if (option == null) {
throw new IllegalStateException("Entity was null");
}
refreshButton.setVisible(false);
refreshButton.setDisable(true);
txtLabel.setVisible(false);
makeFadeInTransition();
sendOptionToServer(event);
}
@FXML
private void sendOptionToServer(ActionEvent event) {
try {
cliente = new Socket("localhost", 3322);
pr = new PrintWriter(cliente.getOutputStream());
in = new InputStreamReader(cliente.getInputStream());
bf = new BufferedReader(in);
pr.println(option);
pr.flush();
waitForReponse(event, bf);
} catch (IOException e) {
e.printStackTrace();
}
}
private void waitForReponse(ActionEvent event, BufferedReader bf) throws IOException {
response = bf.readLine();
switch (response) {
case "a":
Utils.currentStage(event).close();
break;
}
}
}
您的 sendOptionToServer(...)
方法,尤其是您的 waitForResponse(...)
方法,包含阻止执行直到完成(即直到您收到服务器响应)的阻塞调用。由于您在 FX 应用程序线程上 运行 这些,因此您会阻止该线程在这些调用完成之前执行其正常工作。这意味着它不会更新 UI 或处理任何用户事件,直到您收到并处理来自服务器的响应。
您应该将对阻塞方法的调用放在后台线程中,以允许 FX 应用程序线程同时进行。 javafx.concurrent
API makes this reasonably easy to do; here a Task
应该足够了。
这是一个使用 Task
的版本。我还使用了“try with resources”来确保所有需要关闭的东西都正确关闭了。
@FXML
private void sendOptionToServer(ActionEvent event) {
Task<String> serverCommunicationTask = new Task<>() {
@Override
protected String call() throws Exception {
try (
Socket cliente = new Socket("localhost", 3322);
PrintWriter pr = new PrintWriter(cliente.getOutputStream());
BufferedReader bf = new BufferedReader(new InputStreamReader(cliente.getInputStream()));
) {
pr.println(option);
pr.flush();
return bf.readLine();
}
}
};
serverCommunicationTask.setOnSucceeded(event -> {
if ("a".equals(serverCommunicationTask.getValue())) {
rootPane.getScene().getWindow().hide();
}
});
serverCommunicationTask.setOnFailed(event -> {
event.getException().printStackTrace();
// handle exception...
});
Thread thread = new Thread(serverCommunicationTask);
thread.setDaemon(true);
thread.start();
}
我想在我的应用程序的窗格中创建一个 FadeTransition。此外,通过此 FadeTransition,我将窗格内某些 JavaFX 的可见性设置为 false,以使它们消失。它工作正常,但是,当我在 FadeTransition 之后调用另一个我命名为 waitForResponse(event) 的方法时,它就停止工作了。我不知道为什么。 如果我评论 waitForResponse(event),FadeTransitions 将再次开始工作。 我认为可能是 waitForResponse(event) 中的 Socket 和 InputStreamReader 有问题,但我测试了将其取出并在该方法中制作另一个基本的东西仍然不起作用。 我进行了其他测试,发现如果我在其后放置任何 bufferedReader、其他循环或决策结构,FadeTransition 和其他可见性更改将不起作用。 我只想制作一个加载屏幕,以防止用户在加载完成之前点击任何地方。
这是代码:
public class LoadingScreenController implements Initializable {
// Socket que vai ser utilizado nos vários métodos para conversar com o servidor
private Socket cliente;
// PrintWriter que vai ser utilizado pelos vários métodos e vai passar o
// argumento para o switch case
private PrintWriter pr;
private InputStreamReader in;
private BufferedReader bf;
private String option;
private String response;
@FXML
private Button refreshButton;
@FXML
private ImageView loadingGif;
@FXML
private Label txtLabel;
@FXML
private AnchorPane rootPane;
public String getOption() {
return option;
}
public void setOption(String option) {
this.option = option;
}
@Override
public void initialize(URL url, ResourceBundle rb) {
}
@FXML
private void makeFadeInTransition() {
FadeTransition fadeTransition = new FadeTransition(Duration.seconds(1), loadingGif);
fadeTransition.setFromValue(0.0);
fadeTransition.setToValue(1.0);
fadeTransition.play();
}
@FXML
private void onRefreshButtonAction(ActionEvent event) {
if (option == null) {
throw new IllegalStateException("Entity was null");
}
refreshButton.setVisible(false);
refreshButton.setDisable(true);
txtLabel.setVisible(false);
makeFadeInTransition();
sendOptionToServer(event);
}
@FXML
private void sendOptionToServer(ActionEvent event) {
try {
cliente = new Socket("localhost", 3322);
pr = new PrintWriter(cliente.getOutputStream());
in = new InputStreamReader(cliente.getInputStream());
bf = new BufferedReader(in);
pr.println(option);
pr.flush();
waitForReponse(event, bf);
} catch (IOException e) {
e.printStackTrace();
}
}
private void waitForReponse(ActionEvent event, BufferedReader bf) throws IOException {
response = bf.readLine();
switch (response) {
case "a":
Utils.currentStage(event).close();
break;
}
}
}
您的 sendOptionToServer(...)
方法,尤其是您的 waitForResponse(...)
方法,包含阻止执行直到完成(即直到您收到服务器响应)的阻塞调用。由于您在 FX 应用程序线程上 运行 这些,因此您会阻止该线程在这些调用完成之前执行其正常工作。这意味着它不会更新 UI 或处理任何用户事件,直到您收到并处理来自服务器的响应。
您应该将对阻塞方法的调用放在后台线程中,以允许 FX 应用程序线程同时进行。 javafx.concurrent
API makes this reasonably easy to do; here a Task
应该足够了。
这是一个使用 Task
的版本。我还使用了“try with resources”来确保所有需要关闭的东西都正确关闭了。
@FXML
private void sendOptionToServer(ActionEvent event) {
Task<String> serverCommunicationTask = new Task<>() {
@Override
protected String call() throws Exception {
try (
Socket cliente = new Socket("localhost", 3322);
PrintWriter pr = new PrintWriter(cliente.getOutputStream());
BufferedReader bf = new BufferedReader(new InputStreamReader(cliente.getInputStream()));
) {
pr.println(option);
pr.flush();
return bf.readLine();
}
}
};
serverCommunicationTask.setOnSucceeded(event -> {
if ("a".equals(serverCommunicationTask.getValue())) {
rootPane.getScene().getWindow().hide();
}
});
serverCommunicationTask.setOnFailed(event -> {
event.getException().printStackTrace();
// handle exception...
});
Thread thread = new Thread(serverCommunicationTask);
thread.setDaemon(true);
thread.start();
}