使用内部带有 'wait()' 的 JavaFX 创建任务
Creating a Task with JavaFX with a 'wait()' inside
我使用 javafx,我有一个 TextField 和一个 Button,当按下按钮时,它会将 TextField 中写入的内容保存在一个字符串中。我想要创建的是一种标记暂停的方法,同时等待按钮被按下。
我有一个名为 pause.java 的 class,我试图在按下按钮的事件中放置一个 obj.wait();
和一个 notifyAll();
,但是 window 在此期间无法访问,我无法按下按钮或在 TextField 中输入任何内容。
所以我发现是把obj.wait();
放在一个task里面,然后不知道为什么直接break out了wait
这是我的 pause.java
package net.jpajavafx;
import java.util.logging.*;
import javafx.concurrent.Task;
public class pause {
Logger logger = Logger.getLogger(pause.class.getName());
MainController obj = new MainController();
public void waitinput() {
Task<Void> sleeper = new Task<Void>() {
@Override
protected Void call() throws Exception {
synchronized (obj) {
try {
String write = "Waiting for input...";
logger.log(Level.INFO, write);
obj.wait();
logger.log(Level.INFO, "Done");
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
};
new Thread(sleeper).start();
}
}
我如何修改它以使其等待,同时仍然可以访问 GUI?
这是我针对问题简化的代码:
AlbumManager.java,我的主要是
package net.jpajavafx;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.*;
import javafx.application.*;
import javafx.fxml.FXMLLoader;
public class AlbumManager extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("Main.fxml"));
Scene scene = new Scene(root);
primaryStage.setTitle("Album Manager");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
MainController.java:
package net.jpajavafx;
import javafx.event.ActionEvent;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.fxml.FXML;
import java.util.logging.*;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
public class MainController {
@FXML
private TextArea textarea;
@FXML
private TextField textfield;
Variablesstoring stock = new Variablesstoring();
public void ok(ActionEvent event) {
String getValue = textfield.getText();
stock.setEntrystr(getValue); //here i have something to put in an Int, I put it aside to reduce the length
textfield.setText("");
notifyAll();
}
public void startprogram() {
int etat = 0;
int run = 1;
while (run == 1) {
textarea.setText("1: launch method");
pause.waitinput(); // here I want to wait for an input
etat = stock.getEntrystr();
switch (etat) {
case 1:
//runs a method
break;
default:
break;
}
}
}
}
您必须 start another thread using a Runnable,这样您的 UI 线程就不会在 save-operation 完成时被阻塞。
您可以通过在按钮上放置一个侦听器来实现此目的,当单击该按钮时,该侦听器将在新线程上启动 save-operation。
将侦听器添加到启动新线程的按钮的代码如下所示:
//Creating the mouse event handler
EventHandler<MouseEvent> eventHandler = new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent e) {
MainController controller = new MainController();
controller.start();
}
};
//Registering the event filter
button.addEventFilter(MouseEvent.MOUSE_CLICKED, eventHandler);
您发布的代码实际上没有任何作用。您对 waitinput()
的调用仅记录和调用 wait()
。 wait()
不是您想要的,因为此操作旨在暂停线程直到收到通知,而不是在单独的线程中执行任务。删除 obj.wait()
,并添加一个在单击按钮时调用您的日志记录方法的侦听器。另外,去掉 while-loop。 EventHandler 将在后台处理事件。
真的不清楚你在这里想要实现什么需要一个单独的线程:所有单独的线程似乎都试图做的是等到按钮被按下,然后执行一些代码。 JavaFX 中的事件管理系统已经提供了该功能(对于任何 UI 工具包也是如此):只需执行事件处理程序中的代码。
(顺便说一句,您对 wait()
的使用是不正确的,如果您修复该问题,线程将永远不会唤醒,因为您没有在您调用的同一对象上调用 notifyAll()
正在呼叫 wait()
.)
您可以通过
轻松实现您似乎想做的事情
package net.jpajavafx;
import javafx.event.ActionEvent;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.fxml.FXML;
import java.util.logging.*;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
public class MainController {
@FXML
private TextArea textarea;
@FXML
private TextField textfield;
Variablesstoring stock = new Variablesstoring();
public void ok(ActionEvent event) {
String getValue = textfield.getText();
stock.setEntrystr(getValue); //here i have something to put in an Int, I put it aside to reduce the length
textfield.setText("");
processInput();
}
public void processInput() {
int etat = stock.getEntrystr();
switch (etat) {
case 1:
//runs a method
break;
default:
break;
}
}
}
我使用 javafx,我有一个 TextField 和一个 Button,当按下按钮时,它会将 TextField 中写入的内容保存在一个字符串中。我想要创建的是一种标记暂停的方法,同时等待按钮被按下。
我有一个名为 pause.java 的 class,我试图在按下按钮的事件中放置一个 obj.wait();
和一个 notifyAll();
,但是 window 在此期间无法访问,我无法按下按钮或在 TextField 中输入任何内容。
所以我发现是把obj.wait();
放在一个task里面,然后不知道为什么直接break out了wait
这是我的 pause.java
package net.jpajavafx;
import java.util.logging.*;
import javafx.concurrent.Task;
public class pause {
Logger logger = Logger.getLogger(pause.class.getName());
MainController obj = new MainController();
public void waitinput() {
Task<Void> sleeper = new Task<Void>() {
@Override
protected Void call() throws Exception {
synchronized (obj) {
try {
String write = "Waiting for input...";
logger.log(Level.INFO, write);
obj.wait();
logger.log(Level.INFO, "Done");
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
};
new Thread(sleeper).start();
}
}
我如何修改它以使其等待,同时仍然可以访问 GUI?
这是我针对问题简化的代码:
AlbumManager.java,我的主要是
package net.jpajavafx;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.*;
import javafx.application.*;
import javafx.fxml.FXMLLoader;
public class AlbumManager extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("Main.fxml"));
Scene scene = new Scene(root);
primaryStage.setTitle("Album Manager");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
MainController.java:
package net.jpajavafx;
import javafx.event.ActionEvent;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.fxml.FXML;
import java.util.logging.*;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
public class MainController {
@FXML
private TextArea textarea;
@FXML
private TextField textfield;
Variablesstoring stock = new Variablesstoring();
public void ok(ActionEvent event) {
String getValue = textfield.getText();
stock.setEntrystr(getValue); //here i have something to put in an Int, I put it aside to reduce the length
textfield.setText("");
notifyAll();
}
public void startprogram() {
int etat = 0;
int run = 1;
while (run == 1) {
textarea.setText("1: launch method");
pause.waitinput(); // here I want to wait for an input
etat = stock.getEntrystr();
switch (etat) {
case 1:
//runs a method
break;
default:
break;
}
}
}
}
您必须 start another thread using a Runnable,这样您的 UI 线程就不会在 save-operation 完成时被阻塞。
您可以通过在按钮上放置一个侦听器来实现此目的,当单击该按钮时,该侦听器将在新线程上启动 save-operation。 将侦听器添加到启动新线程的按钮的代码如下所示:
//Creating the mouse event handler
EventHandler<MouseEvent> eventHandler = new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent e) {
MainController controller = new MainController();
controller.start();
}
};
//Registering the event filter
button.addEventFilter(MouseEvent.MOUSE_CLICKED, eventHandler);
您发布的代码实际上没有任何作用。您对 waitinput()
的调用仅记录和调用 wait()
。 wait()
不是您想要的,因为此操作旨在暂停线程直到收到通知,而不是在单独的线程中执行任务。删除 obj.wait()
,并添加一个在单击按钮时调用您的日志记录方法的侦听器。另外,去掉 while-loop。 EventHandler 将在后台处理事件。
真的不清楚你在这里想要实现什么需要一个单独的线程:所有单独的线程似乎都试图做的是等到按钮被按下,然后执行一些代码。 JavaFX 中的事件管理系统已经提供了该功能(对于任何 UI 工具包也是如此):只需执行事件处理程序中的代码。
(顺便说一句,您对 wait()
的使用是不正确的,如果您修复该问题,线程将永远不会唤醒,因为您没有在您调用的同一对象上调用 notifyAll()
正在呼叫 wait()
.)
您可以通过
轻松实现您似乎想做的事情package net.jpajavafx;
import javafx.event.ActionEvent;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.fxml.FXML;
import java.util.logging.*;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
public class MainController {
@FXML
private TextArea textarea;
@FXML
private TextField textfield;
Variablesstoring stock = new Variablesstoring();
public void ok(ActionEvent event) {
String getValue = textfield.getText();
stock.setEntrystr(getValue); //here i have something to put in an Int, I put it aside to reduce the length
textfield.setText("");
processInput();
}
public void processInput() {
int etat = stock.getEntrystr();
switch (etat) {
case 1:
//runs a method
break;
default:
break;
}
}
}