Initial project

This commit is contained in:
Timi
2025-07-14 14:12:45 +08:00
parent c1788c7d30
commit 16e11e30ce
32 changed files with 4945 additions and 94 deletions

View 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&lt;T&gt;() {
*
* &#064;Override
* protected T call() throws Exception {
*
* // 这里不是 FX 线程,可以执行一些长时间的事情
*
* update(new T()); // 主动更新数据
* progress(.6); // 更新进度
* return new T(); // 返回更新数据
* }
*
* &#064;Override
* protected void onUpdate(T t) {
* // 数据更新事件,属于 FX 线程,视 UI 线程状态回调
* }
*
* &#064;Override
* protected void onUpdateProgress(double progress) {
* // 更新进度事件,属于 FX 线程,视 UI 线程状态回调
* }
*
* &#064;Override
* protected void onFinish() {
* // 线程执行完成,属于 FX 线程
* }
*
* &#064;Override
* protected void onException(Throwable e) {
* // 线程异常,属于 FX 线程
* }
* }.start(); &lt;-- 千万别忘了启动任务
* </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();
}
}