Initial project
This commit is contained in:
301
src/main/java/com/imyeyu/fx/task/RunAsync.java
Normal file
301
src/main/java/com/imyeyu/fx/task/RunAsync.java
Normal file
@@ -0,0 +1,301 @@
|
||||
package com.imyeyu.fx.task;
|
||||
|
||||
import javafx.concurrent.Service;
|
||||
import javafx.concurrent.Task;
|
||||
import com.imyeyu.java.bean.Callback;
|
||||
import com.imyeyu.java.bean.CallbackArg;
|
||||
import com.imyeyu.java.bean.CallbackReturn;
|
||||
|
||||
/**
|
||||
* 异步线程执行,常用的构建异步线程任务
|
||||
*
|
||||
* <pre>
|
||||
* // 快速构造
|
||||
* RunAsync.run(() -> {}); // 快速异步执行 {@link #run(Callback)}
|
||||
* RunAsync.run(() -> {}, () -> {}); // 快速异步回调 {@link #run(Callback, Callback)}
|
||||
* RunAsync.run(() -> 100, v -> {}); // 快速异步返回 {@link #callbackReturn(CallbackReturn, CallbackArg)}
|
||||
* RunAsync.later(() -> {}, 1000); // 延时一秒执行 {@link #later(Callback, long)}
|
||||
*
|
||||
* // 标准构造
|
||||
* new RunAsync<T>() {
|
||||
*
|
||||
* @Override
|
||||
* protected T call() throws Exception {
|
||||
*
|
||||
* // 这里不是 FX 线程,可以执行一些长时间的事情
|
||||
*
|
||||
* update(new T()); // 主动更新数据
|
||||
* progress(.6); // 更新进度
|
||||
* return new T(); // 返回更新数据
|
||||
* }
|
||||
*
|
||||
* @Override
|
||||
* protected void onUpdate(T t) {
|
||||
* // 数据更新事件,属于 FX 线程,视 UI 线程状态回调
|
||||
* }
|
||||
*
|
||||
* @Override
|
||||
* protected void onUpdateProgress(double progress) {
|
||||
* // 更新进度事件,属于 FX 线程,视 UI 线程状态回调
|
||||
* }
|
||||
*
|
||||
* @Override
|
||||
* protected void onFinish() {
|
||||
* // 线程执行完成,属于 FX 线程
|
||||
* }
|
||||
*
|
||||
* @Override
|
||||
* protected void onException(Throwable e) {
|
||||
* // 线程异常,属于 FX 线程
|
||||
* }
|
||||
* }.start(); <-- 千万别忘了启动任务
|
||||
* </pre>
|
||||
*
|
||||
* @author 夜雨
|
||||
* @since
|
||||
*
|
||||
* @param <T> 数据处理返回类型
|
||||
*
|
||||
* @author 夜雨
|
||||
* @version 2021-02-13 12:56
|
||||
*/
|
||||
public abstract class RunAsync<T> extends Service<T> {
|
||||
|
||||
/** 任务对象 */
|
||||
protected PublicTask<T> task;
|
||||
|
||||
/** 最近一次更新数据 */
|
||||
protected T lastT;
|
||||
|
||||
protected boolean isInterrupted = false;
|
||||
|
||||
@Override
|
||||
protected Task<T> createTask() {
|
||||
task = new PublicTask<>() {
|
||||
|
||||
protected T call() throws Exception {
|
||||
return RunAsync.this.call();
|
||||
}
|
||||
};
|
||||
task.setOnScheduled(e -> isInterrupted = false);
|
||||
task.setOnSucceeded(e -> {
|
||||
onFinish();
|
||||
onFinish(lastT);
|
||||
onFinally();
|
||||
isInterrupted = false;
|
||||
});
|
||||
task.setOnFailed(e -> {
|
||||
onFinally();
|
||||
isInterrupted = false;
|
||||
});
|
||||
task.valueProperty().addListener((obs, o, t) -> {
|
||||
lastT = t;
|
||||
onUpdate(t);
|
||||
});
|
||||
task.messageProperty().addListener((obs, o, msg) -> onMessage(msg));
|
||||
task.progressProperty().addListener((obs, o, p) -> onProgress(p.doubleValue()));
|
||||
task.exceptionProperty().addListener((obs, o, e) -> onException(e));
|
||||
return task;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行事件(非 FX 线程)
|
||||
*
|
||||
* @return 处理结果
|
||||
* @throws Exception 处理异常
|
||||
*/
|
||||
protected abstract T call() throws Exception;
|
||||
|
||||
/**
|
||||
* 主动更新数据,通常是非 FX 线程的 call 里触发,{@link #onUpdate(T)} 里视 UI 线程状态回调
|
||||
*
|
||||
* @param t 更新值
|
||||
*/
|
||||
protected void update(T t) {
|
||||
lastT = t;
|
||||
task.updateValue(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* 主动更新进度,非 FX 线程的 call 里触发,{@link #onProgress(double)} 里视 UI 线程状态回调
|
||||
*
|
||||
* @param progress 进度值
|
||||
*/
|
||||
protected void progress(double progress) {
|
||||
task.updateProgress(progress, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新消息,非 FX 线程的 call 里触发,{@link #onMessage(String)} 里视 UI 线程状态回调
|
||||
*
|
||||
* @param msg 消息
|
||||
*/
|
||||
protected void message(String msg) {
|
||||
task.updateMessage(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据更新事件,{@link #update(T)} 或 {@link #call()} 返回参数触发,属于 FX 线程
|
||||
*
|
||||
* @param t 更新数据
|
||||
*/
|
||||
protected void onUpdate(T t) {
|
||||
// 子类实现
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新进度事件,{@link #progress(double)} 触发,属于 FX 线程
|
||||
*
|
||||
* @param progress 进度值
|
||||
*/
|
||||
protected void onProgress(double progress) {
|
||||
// 子类实现
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新消息
|
||||
*
|
||||
* @param msg 消息
|
||||
*/
|
||||
protected void onMessage(String msg) {
|
||||
// 子类实现
|
||||
}
|
||||
|
||||
/** 完成事件(FX 线程,只要线程结束就会调用) */
|
||||
protected void onFinish() {
|
||||
// 子类实现
|
||||
}
|
||||
|
||||
/**
|
||||
* 完成事件(FX 线程,只要线程结束就会调用,参数为 {@link #update(T)} 或 {@link #call()} 最后一次更新值)
|
||||
*
|
||||
* @param t 执行事件返回值
|
||||
*/
|
||||
protected void onFinish(T t) {
|
||||
// 子类实现
|
||||
}
|
||||
|
||||
/**
|
||||
* 发生异常(FX 线程)
|
||||
*
|
||||
* @param e 异常
|
||||
*/
|
||||
protected void onException(Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
/** 线程完成监听,无论正常完成还是出现异常,都会触发此方法 */
|
||||
protected void onFinally() {
|
||||
// 子类实现
|
||||
}
|
||||
|
||||
/** 中断任务 */
|
||||
public void interrupt() {
|
||||
isInterrupted = true;
|
||||
}
|
||||
|
||||
// ---------- 静态构造 ----------
|
||||
|
||||
/**
|
||||
* 快速构造稍后执行,触发事件属于 FX 线程
|
||||
*
|
||||
* @param callback 异步事件
|
||||
* @param delay 延时时间(毫秒)
|
||||
*/
|
||||
public static void later(Callback callback, long delay) {
|
||||
run(() -> {
|
||||
try {
|
||||
Thread.sleep(delay);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* 快速构造异步任务
|
||||
*
|
||||
* @param callback 异步回调
|
||||
*/
|
||||
public static void run(Callback callback) {
|
||||
run(callback, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 快速构造异步任务
|
||||
*
|
||||
* @param asyncCallback 异步回调
|
||||
* @param finishCallback 异步完成回调
|
||||
*/
|
||||
public static void run(Callback asyncCallback, Callback finishCallback) {
|
||||
run(asyncCallback, finishCallback, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 快速构造异步任务
|
||||
*
|
||||
* @param asyncCallback 异步回调
|
||||
* @param exceptionCallback 异常回调
|
||||
*/
|
||||
public static void run(Callback asyncCallback, CallbackArg<Throwable> exceptionCallback) {
|
||||
run(asyncCallback, null, exceptionCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* 快速构造异步任务(私有为了可读性,既然主要事件都用上了那应该使用 new {@link RunAsync}() 来保持可读性)
|
||||
*
|
||||
* @param asyncCallback 异步回调
|
||||
* @param finishCallback 异步完成回调
|
||||
* @param exceptionCallback 异常回调
|
||||
*/
|
||||
private static void run(Callback asyncCallback, Callback finishCallback, CallbackArg<Throwable> exceptionCallback) {
|
||||
new RunAsync<Void>() {
|
||||
|
||||
@Override
|
||||
protected Void call() {
|
||||
asyncCallback.handler();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinish() {
|
||||
try {
|
||||
if (finishCallback != null) {
|
||||
finishCallback.handler();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onException(Throwable e) {
|
||||
if (exceptionCallback != null) {
|
||||
exceptionCallback.handler(e);
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* 快速构造异步任务
|
||||
*
|
||||
* @param asyncCallback 异步回调
|
||||
* @param finishCallback 异步完成回调
|
||||
* @param <T> 回调数据类型
|
||||
*/
|
||||
public static <T> void callbackReturn(CallbackReturn<T> asyncCallback, CallbackArg<T> finishCallback) {
|
||||
new RunAsync<T>() {
|
||||
|
||||
@Override
|
||||
protected T call() {
|
||||
return asyncCallback.handler();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinish(T t) {
|
||||
finishCallback.handler(t);
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user