sockets - 当我调用新方法时,JavaFX FadeTransition 结束其他 SetVisbilities 停止工作
问题描述
我想在我的应用程序的窗格中创建一个 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使这相当容易做到;这里一个Task
应该足够了。
这是一个使用Task
. 我还使用了“尝试资源”来确保正确关闭需要关闭的所有内容。
@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();
}
推荐阅读
- jenkins - Jenkins Pipeline:如何在超时时打印挂起进程的堆栈跟踪?
- c - GDB 通过 step 深入系统调用的问题
- ios - 未调用 preferredScreenEdgesDeferringSystemGestures
- node.js - SSL 安全连接是否可以在没有浏览器调用的情况下使用?
- php - TYPO3:Extbase 模型中的性能
- python - 将替换字符串 lambda 应用于 python 中的所有行
- javascript - u"'' 值的日期格式无效。它必须是 YYYY-MM-DD 格式我需要它是 MM-DD-YYYY
- r - 使用 Phoenix 将 R 连接到 Hadoop 的问题
- shell - 如何将 Jenkins 凭据传递给 Dockerfile/Shell?
- uwp - 我无法在 codedui 中选择 UWP ListView 项目