无法停止线程 Midway 和重新启动添加节点线程。
这就是我得到的
这就是我需要的,每当我按下 刷新按钮
时,我就一遍又一遍地想要这样的东西干净的屏幕和重新启动(例如,A到N顺序正确)
为什么?,所以我可以在刷新之前选择其他列表。
背景故事 (忽略) 从一个月开始,我正在JavaFX上做一个小项目,但是这个问题困扰着我。我做了研究,试图找出答案,但是什么也没有。如果有人在正确的道路上引导我,我将非常感激。请突出显示此问题,以便其他人不必浪费太多时间
我有JavaFX控制器
@FXML public FlowPane flow_panel;
MyPlatform mp = new MyPlatform(); // A class that implements Runnable
Thread t;
boolean first_time_click = true; // To check Whether i clicked '1st' time or 'second' time
@FXML
private void Refresh_Btn(ActionEvent event)
{
System.out.println("Refresh btn");
t = new Thread(mp); //Creating Thread object
if(first_time_click == true) { first_time_click = false;
MyPlatform.stop = false; //Thread object.Stop, When false do nothing
flow_panel.getChildren().clear(); // cleaning screen
System.out.println("Start Thread");
t.setDaemon(true);
t.start(); //Start Thread
} else if(first_time_click == false){ first_time_click = true;
MyPlatform.stop = true; //Exist loop
t.interrupt(); // I thought 't.interrupt()' it work but nothing
System.out.println("Stop Thread");
flow_panel.getChildren().clear(); // cleaning screen
MyPlatform.stop = false; //Thread object.Stop, When false do nothing
t.setDaemon(true);
t.start(); //Start Thread
System.out.println("Stoped Thread Started again");
}
}
然后我有一个名为MyPlatform的类,该类实现Runnable
import javafx.application.Platform;
import javafx.scene.control.Button;
import setups.WindowSetupConfig;
public class MyPlatform implements Runnable
{
public static boolean stop = false;
@Override
public void run()
{
for (String name : ListOfNames.getlist())
{
if(stop) // Exit for loop if true
{
break;
}
Platform.runLater(new Runnable()
{
@Override
public void run()
{
Button btn = new Button("Button : "+name);
System.out.println(name);
//Adding that button to FlowPane
WindowSetupConfig.getController().flow_panel.getChildren().add(btn);
}
});
try {
Thread.sleep(1000); // Wait for 1 sec, Controlling speed
} catch (InterruptedException e) { // try catch it needed for some reason
e.printStackTrace();
}
}
}
}
我有一个字符串列表。原本该列表将有500多个名字
import java.util.ArrayList;
public class ListOfNames
{
private static ArrayList<String> list_of_names ;
public ListOfNames()
{
list_of_names = new ArrayList<>();
list_of_names.add("A");
list_of_names.add("B");
list_of_names.add("C");
list_of_names.add("D");
list_of_names.add("E");
list_of_names.add("F");
list_of_names.add("G");
list_of_names.add("H");
list_of_names.add("I");
list_of_names.add("J");
list_of_names.add("K");
list_of_names.add("L");
list_of_names.add("M");
list_of_names.add("N");
}
public static ArrayList<String> getlist() {
return list_of_names;
}
}
每当我按下 刷新按钮时,我想停止向流面板添加点头的线程中途。
使用 flow_panel.getChildren()。clear(); 清洁FlowPane 然后从列表的开头重新开始
特别是 -停止 清洁 -重新启动
如果可以通过服务或任务做任何事情,那都很好
答案 0 :(得分:2)
我没有阅读您所有的代码,但是我将给出有关如何取消和“重新启动” Task
的一般说明。
首先,请勿使用suspend
的{{1}},stop
或resume
方法;他们被淘汰是有原因的。
与所有后台任务一样,取消操作需要所述后台任务开发人员的配合。该任务必须在适当的时间检查它是否已被取消并做出相应的反应。通常,这是通过查询当前Thread
的中断状态来完成的,但是Thread
类从Task
继承了易于使用的isCancelled
方法。
模拟长期运行的示例:
FutureTask
您可以使用public class MyTask extends Task<Void> {
@Override
protected Void call() throws Exception {
for (int i = 0; i < 10_000; i++) {
if (isCancelled()) {
break;
}
updateMessage(Integer.toString(i));
Thread.sleep(1L);
updateProgress(i, 10_000);
}
return null;
}
}
界面的Task
方法取消cancel
。注意循环的每次迭代中Worker
的检查;调用isCancelled
方法时,cancel
将尽早停止。另外,调用Task
(或Worker.cancel()
)将中断Future.cancel(true)
,这意味着任何可中断的操作(例如Thread
)都将抛出Thread.sleep
。
您可以通过观察InterruptedException
的属性或添加事件处理程序来对Task
成功,失败或被取消做出反应。
Task
您可以在这些回调中进行清理并根据需要执行 new MyTask task = new MyTask();
task.setOnSucceeded(event -> handleSucceededTask());
task.setOnFailed(event -> handleFailedTask());
task.setOnCancelled(event -> handleCancelledTask());
。请注意,您必须启动新的Task
,因为Task
是一次性使用的。
答案 1 :(得分:0)
我找到了解决问题的方法。现在我的问题是有没有更好的方法来达到相同的结果 因为我正在发黄,这意味着我做错了方法
Luncher.java
package project;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Luncher extends Application
{
@Override
public void start(Stage primaryStage) {
try {
Parent root = FXMLLoader.load(getClass().getResource("Window.fxml"));
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
System.err.println("Luncher Failed !" +e);
}
}
public static void main(String[] args)
{
launch(args);
}
}
Controller.java
package project;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.layout.FlowPane;
public class Controller implements Initializable
{
@FXML
public FlowPane flowPane;
//A class that implements Runable, So i can start a thead there
private MyRunableClass my_run_class;
private Thread t; //Thread object
@Override
public void initialize(URL location, ResourceBundle resources)
{
new ListOfNames(); //Init list of names and creating Array list, In real program i will get this list from database
my_run_class = new MyRunableClass(this);
}
@FXML
void clear_Button(ActionEvent event)
{
flowPane.getChildren().clear();
}
@FXML
void start_Button(ActionEvent event)
{
t = new Thread(my_run_class);
t.start();
}
@FXML
void stop_Button(ActionEvent event) {
t.suspend(); ///NOT WORKING???????? any way to stop running thread
}
private boolean firstTime_thread_running = true; // To check Whether i clicked '1st' time or 'second' time
@FXML
void refresh_Button(ActionEvent event)
{
if(firstTime_thread_running == false){
//Stop
// my_run_class.stop = true; //Exist loop
t.suspend();
System.out.println("Suspend");
} else
{
firstTime_thread_running = false;
}
//Clean
flowPane.getChildren().clear(); // cleaning screen
System.out.println("Screen clear");
//Restart , well.. at least that what i want
t = new Thread(my_run_class);
t.setDaemon(true);
t.start(); //Start Thread
System.out.println("Stoped Thread Started again");
}
}
MyRunableClass.java
package project;
import javafx.application.Platform;
import javafx.scene.control.Button;
public class MyRunableClass implements Runnable
{
private Controller controller;
public MyRunableClass(Controller controller)
{
//Getting FXML Controller
this.controller = controller;
}
// public boolean stop = false;
@Override
public void run()
{
for (String name : ListOfNames.getlist())
{
// if(stop) // Exit for loop if true
// {
// break;
// }
Platform.runLater(new Runnable()
{
@Override
public void run()
{
Button btn = new Button("Button : "+name);
System.out.println(name);
controller.flowPane.getChildren().add(btn);
}
});
try {
Thread.sleep(1); // Wait for half sec this time
} catch (InterruptedException e) { // try catch it needed for some reason
e.printStackTrace();
}
}
}
}
ListOfNames.java
package project;
import java.util.ArrayList;
public class ListOfNames
{
private static ArrayList<String> list_of_names ;
public ListOfNames()
{
list_of_names = new ArrayList<>();
list_of_names.add("A");
list_of_names.add("B");
list_of_names.add("C");
list_of_names.add("D");
list_of_names.add("E");
list_of_names.add("F");
list_of_names.add("G");
list_of_names.add("H");
list_of_names.add("I");
list_of_names.add("J");
list_of_names.add("K");
list_of_names.add("L");
list_of_names.add("M");
list_of_names.add("N");
list_of_names.add("O");
list_of_names.add("P");
list_of_names.add("Q");
list_of_names.add("R");
list_of_names.add("S");
list_of_names.add("T");
list_of_names.add("U");
list_of_names.add("V");
list_of_names.add("W");
list_of_names.add("X");
list_of_names.add("Y");
list_of_names.add("Z");
}
public static ArrayList<String> getlist() {
return list_of_names;
}
}
Window.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.FlowPane?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="413.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="project.Controller">
<children>
<FlowPane fx:id="flowPane" layoutX="2.0" layoutY="61.0" prefHeight="352.0" prefWidth="600.0" style="-fx-border-color: #000000; -fx-border-insets: 1.1; -fx-border-width: 5;" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="61.0" />
<Button layoutX="405.0" layoutY="14.0" mnemonicParsing="false" onAction="#stop_Button" prefHeight="39.0" prefWidth="80.0" text="Stop" />
<Button layoutX="313.0" layoutY="14.0" mnemonicParsing="false" onAction="#start_Button" prefHeight="39.0" prefWidth="80.0" text="Star" />
<Button layoutX="497.0" layoutY="14.0" mnemonicParsing="false" onAction="#clear_Button" prefHeight="39.0" prefWidth="80.0" text="Clean" />
<Button layoutX="40.0" layoutY="14.0" mnemonicParsing="false" onAction="#refresh_Button" prefHeight="39.0" prefWidth="109.0" text="Refresh" />
</children>
</AnchorPane>