{
-
- public static final Logger LOGGER = LoggerFactory.getLogger(AsyncTask.class);
-
- private final String description;
-
- private final long startTime;
-
- private final AsyncEvent asyncEvent;
-
- public AsyncTask(String description, AsyncEvent asyncEvent) {
- this.description = description;
- this.asyncEvent = asyncEvent;
- this.startTime = System.currentTimeMillis();
- }
-
- @Override
- protected Void call() throws Exception {
- try {
- LOGGER.info("Task {} 开始执行", description);
- asyncEvent.handler();
- } catch (Exception e) {
- LOGGER.info("Task {} 执行异常:{}", description, e.getMessage());
- }
- return null;
- }
-
- @Override
- protected void succeeded() {
- super.succeeded();
- LOGGER.info("Task {} 执行结束,耗时 {} ms", description, System.currentTimeMillis() - startTime);
- }
-
- @Override
- protected void failed() {
- super.failed();
- LOGGER.info("Task {} 执行失败", description);
- }
-
- public static void runOnce(AsyncEvent event) {
- runOnce("任务", event);
- }
-
- public static void runOnce(String description, AsyncEvent event) {
- GitThreadPool.EXECUTOR_SERVICE.execute(new AsyncTask(description, event));
- }
-}
diff --git a/src/main/java/com/light/thread/FxAsyncTask.java b/src/main/java/com/light/thread/FxAsyncTask.java
new file mode 100644
index 0000000000000000000000000000000000000000..2ce9c6aa154ebc9c216e6dc8692ff8c9e1fd292c
--- /dev/null
+++ b/src/main/java/com/light/thread/FxAsyncTask.java
@@ -0,0 +1,159 @@
+package com.light.thread;
+
+import javafx.concurrent.Task;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.function.Consumer;
+
+/**
+ * 启用虚拟线程异步执行任务 - 工具类
+ *
+ * 注意:为了能正确执行 成功和失败 方法,自定义方法中有异常要抛出,不要处理
+ *
+ * 虚拟线程的应用场景主要包括 IO 密集型任务和高并发 Web 服务器等领域
+ *
+ * 不支持 CPU 密集型任务、无法直接访问线程本地变量
+ */
+public final class FxAsyncTask {
+
+ public static final Logger LOGGER = LoggerFactory.getLogger(FxAsyncTask.class);
+
+ /**
+ * 异步执行一次
+ *
+ * @param run
+ * @param
+ * @return
+ */
+ public static Task runOnce(Run run) {
+ return runOnce("异步执行一次", run);
+ }
+
+ /**
+ * 异步执行一次
+ *
+ * @param message
+ * @param run
+ * @param
+ * @return
+ */
+ public static Task runOnce(String message, Run run) {
+ return runOnce(System.currentTimeMillis(), message, run);
+ }
+
+ /**
+ * 异步执行一次
+ *
+ * @param startTime
+ * @param message
+ * @param run
+ * @param
+ * @return
+ */
+ public static Task runOnce(long startTime, String message, Run run) {
+ return runOnce(startTime, message, run, null);
+ }
+
+ /**
+ * 异步执行一次
+ *
+ * @param startTime
+ * @param message
+ * @param run
+ * @param success
+ * @param
+ * @return
+ */
+ public static Task runOnce(long startTime, String message, Run run, RunSuccess success) {
+ return runOnce(startTime, message, run, success, null);
+ }
+
+ /**
+ * 异步执行一次
+ *
+ * @param startTime
+ * @param message
+ * @param run
+ * @param success
+ * @param fail
+ * @param
+ * @return
+ */
+ public static Task runOnce(long startTime, String message, Run run, RunSuccess success, RunFail fail) {
+ Task task = FxTask.createTask(startTime, message, run, success, fail);
+ Thread.startVirtualThread(task);
+ return task;
+ }
+
+ /**
+ * 异步执行一次有返回值
+ *
+ * @param runBack
+ * @param
+ * @return
+ */
+ public static Task runOnceBack(RunBack runBack) {
+ return runOnceBack("异步执行一次有返回值", runBack);
+ }
+
+ /**
+ * 异步执行一次有返回值
+ *
+ * @param message
+ * @param runBack
+ * @param
+ * @return
+ */
+ public static Task runOnceBack(String message, RunBack runBack) {
+ return runOnceBack(System.currentTimeMillis(), message, runBack);
+ }
+
+ /**
+ * 异步执行一次有返回值
+ *
+ * @param startTime
+ * @param message
+ * @param runBack
+ * @param
+ * @return
+ */
+ public static Task runOnceBack(long startTime, String message, RunBack runBack) {
+ return runOnceBack(startTime, message, runBack, null);
+ }
+
+ /**
+ * 异步执行一次有返回值
+ *
+ * @param startTime
+ * @param message
+ * @param runBack
+ * @param
+ * @return
+ */
+ public static Task runOnceBack(long startTime, String message, RunBack runBack, Consumer success) {
+ return runOnceBack(startTime, message, runBack, success, null);
+ }
+
+ /**
+ * 异步执行一次有返回值
+ *
+ * @param startTime
+ * @param message
+ * @param runBack 要处理的方法
+ * @param success 成功后执行的方法
+ * @param fail 失败后执行的方法
+ * @param
+ * @return
+ */
+ public static Task runOnceBack(long startTime, String message, RunBack runBack, Consumer success, Consumer fail) {
+ Task task = FxTask.createTaskBack(startTime, message, runBack, success, fail);
+ Thread.startVirtualThread(task);
+ return task;
+ }
+
+ public static void runOnceTask(String message, Task task) {
+ LOGGER.info("Task {} 开始执行", message);
+ Thread.startVirtualThread(task);
+ }
+}
diff --git a/src/main/java/com/light/thread/FxTask.java b/src/main/java/com/light/thread/FxTask.java
new file mode 100644
index 0000000000000000000000000000000000000000..a79c7b2d4e421356d39936391948ca6e45aefd5e
--- /dev/null
+++ b/src/main/java/com/light/thread/FxTask.java
@@ -0,0 +1,68 @@
+package com.light.thread;
+
+import javafx.concurrent.Task;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Optional;
+import java.util.function.Consumer;
+
+/**
+ * 创建task工具类
+ */
+public class FxTask {
+ public static final Logger LOGGER = LoggerFactory.getLogger(FxTask.class);
+
+ public static Task createTask(long startTime, String message, Run run, RunSuccess success, RunFail fail) {
+ return new Task<>() {
+ @Override
+ protected T call() throws Exception {
+ LOGGER.info("Task {} 开始执行", message);
+ run.run();
+ return null;
+ }
+
+ @Override
+ protected void succeeded() {
+ super.succeeded();
+ if (null != success) {
+ success.run();
+ }
+ LOGGER.info("Task {} 执行成功,耗时 {} ms", message, System.currentTimeMillis() - startTime);
+ }
+
+ @Override
+ protected void failed() {
+ super.failed();
+ if (null != fail) {
+ fail.run();
+ }
+ LOGGER.info("Task {} 执行失败,耗时 {} ms", message, System.currentTimeMillis() - startTime);
+ }
+ };
+ }
+
+ public static Task createTaskBack(long startTime, String message, RunBack runBack, Consumer success, Consumer fail) {
+ return new Task<>() {
+ @Override
+ protected T call() throws Exception {
+ LOGGER.info("Task {} 开始执行", message);
+ return runBack.get();
+ }
+
+ @Override
+ protected void succeeded() {
+ super.succeeded();
+ Optional.of(success).ifPresent(success -> success.accept(getValue()));
+ LOGGER.info("Task {} 执行成功,耗时 {} ms", message, System.currentTimeMillis() - startTime);
+ }
+
+ @Override
+ protected void failed() {
+ super.failed();
+ Optional.of(fail).ifPresent(fail -> fail.accept(getValue()));
+ LOGGER.info("Task {} 执行失败,耗时 {} ms", message, System.currentTimeMillis() - startTime);
+ }
+ };
+ }
+}
diff --git a/src/main/java/com/light/thread/FxThreadPoolTask.java b/src/main/java/com/light/thread/FxThreadPoolTask.java
new file mode 100644
index 0000000000000000000000000000000000000000..41f227dd370d3b81a683655344a28b7567c18a1d
--- /dev/null
+++ b/src/main/java/com/light/thread/FxThreadPoolTask.java
@@ -0,0 +1,87 @@
+package com.light.thread;
+
+import javafx.concurrent.Task;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * 利用线程池处理异步任务
+ */
+public class FxThreadPoolTask {
+ public static final Logger LOGGER = LoggerFactory.getLogger(FxThreadPoolTask.class);
+
+ // 普通线程池
+ public static final ExecutorService EXECUTOR_SERVICE = Executors.newFixedThreadPool(10);
+ // 虚拟线程池
+ public static final ExecutorService EXECUTOR_VIRTUAL_SERVICE = Executors.newVirtualThreadPerTaskExecutor();
+
+ // 当前正在处理的任务数(目前设定同时最多处理5个任务)
+ public static final AtomicInteger THREAD_DEALING_NUM = new AtomicInteger(0);
+
+ public static void close() {
+ if (!EXECUTOR_SERVICE.isShutdown()) {
+ EXECUTOR_SERVICE.shutdown();
+ LOGGER.info("普通线程池关闭");
+ }
+ if (!EXECUTOR_VIRTUAL_SERVICE.isShutdown()) {
+ EXECUTOR_VIRTUAL_SERVICE.shutdown();
+ LOGGER.info("虚拟线程池关闭");
+ }
+ }
+
+ /**
+ * 普通线程池执行task任务
+ *
+ * @param message
+ * @param run
+ */
+ public static void runPool(String message, Run run) {
+ runPool(System.currentTimeMillis(), message, run, null, null);
+ }
+
+ /**
+ * 普通线程池执行task任务
+ *
+ * @param startTime
+ * @param message
+ * @param run
+ * @param success
+ * @param fail
+ */
+ public static void runPool(long startTime, String message, Run run, RunSuccess success, RunFail fail) {
+ runPool(FxTask.createTask(startTime, message, run, success, fail));
+ }
+
+ public static void runPool(Task task) {
+ // 正在运行task +1
+ THREAD_DEALING_NUM.incrementAndGet();
+ EXECUTOR_SERVICE.execute(task);
+ }
+
+ public static void runVirtualPool(String message, Run run) {
+ runVirtualPool(System.currentTimeMillis(), message, run, null, null);
+ }
+
+ /**
+ * 虚拟线程池执行task任务
+ *
+ * @param startTime
+ * @param message
+ * @param run
+ * @param success
+ * @param fail
+ */
+ public static void runVirtualPool(long startTime, String message, Run run, RunSuccess success, RunFail fail) {
+ runVirtualPool(FxTask.createTask(startTime, message, run, success, fail));
+ }
+
+ public static void runVirtualPool(Task task) {
+ // 正在运行task +1
+ THREAD_DEALING_NUM.incrementAndGet();
+ EXECUTOR_VIRTUAL_SERVICE.execute(task);
+ }
+}
diff --git a/src/main/java/com/light/thread/GitThreadPool.java b/src/main/java/com/light/thread/GitThreadPool.java
deleted file mode 100644
index 0572585c426895897f7fdb04914147cbc0169af5..0000000000000000000000000000000000000000
--- a/src/main/java/com/light/thread/GitThreadPool.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.light.thread;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-
-public class GitThreadPool {
- public static final Logger LOGGER = LoggerFactory.getLogger(GitThreadPool.class);
-
- // 普通线程池
- public static final ExecutorService EXECUTOR_SERVICE = Executors.newFixedThreadPool(10);
-
- // 定时线程池
- public static final ScheduledExecutorService SCHEDULED_EXECUTOR_SERVICE = Executors.newScheduledThreadPool(5);
-
- public static void close() {
- if (!EXECUTOR_SERVICE.isShutdown()) {
- EXECUTOR_SERVICE.shutdown();
- }
- if (!SCHEDULED_EXECUTOR_SERVICE.isShutdown()) {
- SCHEDULED_EXECUTOR_SERVICE.shutdown();
- }
- LOGGER.info("线程池关闭");
- }
-}
diff --git a/src/main/java/com/light/thread/Run.java b/src/main/java/com/light/thread/Run.java
new file mode 100644
index 0000000000000000000000000000000000000000..5eea1c09752d160e912e221492099745f756adca
--- /dev/null
+++ b/src/main/java/com/light/thread/Run.java
@@ -0,0 +1,5 @@
+package com.light.thread;
+
+public interface Run {
+ void run() throws Exception;
+}
diff --git a/src/main/java/com/light/thread/AsyncEvent.java b/src/main/java/com/light/thread/RunBack.java
similarity index 30%
rename from src/main/java/com/light/thread/AsyncEvent.java
rename to src/main/java/com/light/thread/RunBack.java
index 0ec782afbc59c93e31c44bd7c5f001ee6ed3df41..999a7e5164508c7df0f5ba8d8e464a06cf7cbba5 100644
--- a/src/main/java/com/light/thread/AsyncEvent.java
+++ b/src/main/java/com/light/thread/RunBack.java
@@ -1,6 +1,6 @@
package com.light.thread;
-public interface AsyncEvent {
+public interface RunBack {
- void handler() throws Exception;
+ T get() throws Exception;
}
diff --git a/src/main/java/com/light/thread/RunFail.java b/src/main/java/com/light/thread/RunFail.java
new file mode 100644
index 0000000000000000000000000000000000000000..bbf518ca53af2b493ddedba61d2a9f4b177fbfb3
--- /dev/null
+++ b/src/main/java/com/light/thread/RunFail.java
@@ -0,0 +1,5 @@
+package com.light.thread;
+
+public interface RunFail {
+ void run();
+}
diff --git a/src/main/java/com/light/thread/RunSuccess.java b/src/main/java/com/light/thread/RunSuccess.java
new file mode 100644
index 0000000000000000000000000000000000000000..943ee74058a9275840dfed044c7b3a5b8be798e8
--- /dev/null
+++ b/src/main/java/com/light/thread/RunSuccess.java
@@ -0,0 +1,6 @@
+package com.light.thread;
+
+public interface RunSuccess {
+
+ void run();
+}
diff --git a/src/main/java/com/light/util/FxApplicationContextUtils.java b/src/main/java/com/light/util/FxApplicationContextUtils.java
index 0ff48b63a507fd9c7e17220cbd15e345e361564f..02e16f6636e2baa95c5cd5cf608d8a632353ec0c 100644
--- a/src/main/java/com/light/util/FxApplicationContextUtils.java
+++ b/src/main/java/com/light/util/FxApplicationContextUtils.java
@@ -54,5 +54,5 @@ public final class FxApplicationContextUtils {
/**
* 历史通知集合
*/
- public static final ObservableList HISTORY_NOTICE_LIST = FXCollections.observableArrayList();
+ public static final ObservableList HISTORY_NOTICE_LIST = FXCollections.observableArrayList();
}
diff --git a/src/main/java/com/light/util/FxUtil.java b/src/main/java/com/light/util/FxUtil.java
index db43480d74e4684b0bf657ee5a7d6bcf5c002d39..c631cf6d1786f13f8d0739fb6690a9e8ae0f97a9 100644
--- a/src/main/java/com/light/util/FxUtil.java
+++ b/src/main/java/com/light/util/FxUtil.java
@@ -1,18 +1,27 @@
package com.light.util;
+import atlantafx.base.theme.Styles;
+import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.geometry.Bounds;
import javafx.geometry.Insets;
+import javafx.geometry.Pos;
import javafx.scene.Node;
+import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.shape.Rectangle;
+import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.stage.Window;
+import org.kordamp.ikonli.bootstrapicons.BootstrapIcons;
+import org.kordamp.ikonli.javafx.FontIcon;
import java.util.Objects;
import java.util.concurrent.Callable;
@@ -166,6 +175,17 @@ public class FxUtil {
* @param message
*/
public static void addNoticeList(String message) {
- FxApplicationContextUtils.HISTORY_NOTICE_LIST.add(0, message);
+ if (message.length() > 200) {
+ message = message.substring(0, 200);
+ }
+ Text text = new Text(message);
+ text.setWrappingWidth(500d);
+ Button removeButton = new Button(null, new FontIcon(BootstrapIcons.X));
+ removeButton.getStyleClass().addAll(Styles.BUTTON_ICON, Styles.FLAT, Styles.ACCENT);
+ HBox hBox = new HBox(10, text, removeButton);
+ hBox.setAlignment(Pos.CENTER);
+ HBox.setHgrow(text, Priority.ALWAYS);
+ removeButton.setOnMouseClicked(event -> FxApplicationContextUtils.HISTORY_NOTICE_LIST.remove(hBox));
+ Platform.runLater(() -> FxApplicationContextUtils.HISTORY_NOTICE_LIST.add(0, hBox));
}
}
diff --git a/src/main/java/com/light/util/JGitUtils.java b/src/main/java/com/light/util/JGitUtils.java
index 7602c0572446c6b2df0e13106353d36b13e36d90..a30b5e4f9a1367d3afbfb3bfe35aa6f1d3d060cb 100644
--- a/src/main/java/com/light/util/JGitUtils.java
+++ b/src/main/java/com/light/util/JGitUtils.java
@@ -6,7 +6,6 @@ import com.light.exception.JGitException;
import com.light.exception.TimeOutException;
import com.light.model.GitAuthInfo;
import com.light.model.GitProject;
-import javafx.application.Platform;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleIntegerProperty;
@@ -183,7 +182,7 @@ public class JGitUtils {
// 插入之前验证是否已经存在
if (H2PoolUtils.existsGitProjects(newProject)) {
LOGGER.warn("项目 {},作者 {} 已经存在,不再新增", name, author);
- Platform.runLater(() -> FxApplicationContextUtils.HISTORY_NOTICE_LIST.add("项目 " + name + ",作者 " + author + " 已经存在,不再新增"));
+ FxUtil.addNoticeList("项目 " + name + ",作者 " + author + " 已经存在,不再新增");
newProject = null;
} else {
// 不存在则继续新增,并设置id
@@ -192,7 +191,7 @@ public class JGitUtils {
}
} catch (Exception e) {
LOGGER.error("本地项目 {} 解析失败:{}", path.getAbsolutePath(), e.getMessage());
- Platform.runLater(() -> FxApplicationContextUtils.HISTORY_NOTICE_LIST.add("本地项目 " + path.getAbsolutePath() + " 解析失败:" + e.getMessage()));
+ FxUtil.addNoticeList("本地项目 " + path.getAbsolutePath() + " 解析失败:" + e.getMessage());
}
});
@@ -208,7 +207,7 @@ public class JGitUtils {
} catch (Exception e) {
String message = e.getMessage();
LOGGER.error("项目 {} 克隆异常:{}", remoteUrl, message);
- Platform.runLater(() -> FxApplicationContextUtils.HISTORY_NOTICE_LIST.add("项目 " + remoteUrl + " 克隆异常:" + message));
+ FxUtil.addNoticeList("项目 " + remoteUrl + " 克隆异常:" + message);
if (message.contains("authorized") || message.contains("Authentication")) {
// 权限异常
throw new AuthException();
@@ -233,7 +232,7 @@ public class JGitUtils {
} catch (Exception e) {
String message = e.getMessage();
LOGGER.error("项目 {} 更新异常:{}", remoteUrl, message);
- Platform.runLater(() -> FxApplicationContextUtils.HISTORY_NOTICE_LIST.add("项目 " + remoteUrl + " 更新异常:" + message));
+ FxUtil.addNoticeList("项目 " + remoteUrl + " 更新异常:" + message);
if ("Github".equals(getType(remoteUrl))) {
GITHUB_FAIL_NUMBER.incrementAndGet();
}
diff --git a/src/main/java/com/light/view/ManagerView.java b/src/main/java/com/light/view/ManagerView.java
index 2f5596d3212b7a984113cde9c478465adcf6e1fc..56efdb5c6ecd4a832ab0a8ebe65e46d317794fc0 100644
--- a/src/main/java/com/light/view/ManagerView.java
+++ b/src/main/java/com/light/view/ManagerView.java
@@ -3,26 +3,21 @@ package com.light.view;
import atlantafx.base.controls.CustomTextField;
import atlantafx.base.theme.Styles;
import atlantafx.base.theme.Tweaks;
-import com.google.common.collect.Lists;
-import com.light.component.AuthenticationPane;
import com.light.component.LevelTableCell;
import com.light.component.OperationTableCell;
import com.light.component.TooltipTableRow;
-import com.light.exception.AuthException;
-import com.light.exception.JGitException;
-import com.light.exception.TimeOutException;
import com.light.model.GitAuthInfo;
import com.light.model.GitProject;
-import com.light.thread.AsyncTask;
+import com.light.thread.FxAsyncTask;
+import com.light.thread.FxTask;
+import com.light.thread.FxThreadPoolTask;
import com.light.util.DateUtils;
import com.light.util.FxApplicationContextUtils;
import com.light.util.H2PoolUtils;
import com.light.util.JGitUtils;
-import javafx.application.Platform;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.collections.FXCollections;
import javafx.geometry.Insets;
-import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.TableColumn;
@@ -43,6 +38,7 @@ import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.Date;
+import java.util.Iterator;
import java.util.List;
public class ManagerView extends StackPane {
@@ -158,7 +154,7 @@ public class ManagerView extends StackPane {
dirChooser.setInitialDirectory(new File(H2PoolUtils.queryDictByLabel("GIT_CURRENT_LOCAL_DIR", "D:") + File.separator));
File file = dirChooser.showDialog(getScene().getWindow());
if (null != file) {
- AsyncTask.runOnce("加载本地项目", () -> {
+ FxAsyncTask.runOnce("加载本地项目", () -> {
JGitUtils.parseLocalProjectPath(file);
JGitUtils.parseLocalProject();
});
@@ -185,6 +181,7 @@ public class ManagerView extends StackPane {
// 全部更新按钮
updateButton.setOnMouseClicked(event -> {
+ event.consume();
JGitUtils.GITHUB_FAIL_NUMBER.set(0);
JGitUtils.GITEE_FAIL_NUMBER.set(0);
List list = tableView.getItems().stream().filter(param -> param.selected().get()).toList();
@@ -193,31 +190,39 @@ public class ManagerView extends StackPane {
}
// 更新更新数量
FxApplicationContextUtils.UPDATE_PROPERTY.set(String.valueOf(FxApplicationContextUtils.UPDATE_NUMBER.addAndGet(list.size())));
- List> partitioned = Lists.partition(list, list.size() / 5);
- partitioned.forEach(partitionList -> AsyncTask.runOnce("更新项目", () -> {
- partitionList.forEach(param -> {
- SimpleDoubleProperty rate = param.downloadRate();
- File localRepoFile = new File(param.local().get());
- String remoteUrl = param.remote();
- try {
- if ("Gitee".equals(JGitUtils.getType(remoteUrl)) && JGitUtils.GITEE_FAIL_NUMBER.get() < 10) {
- pull(param, localRepoFile, remoteUrl, rate);
- } else if ("Github".equals(JGitUtils.getType(remoteUrl)) && JGitUtils.GITHUB_FAIL_NUMBER.get() < 5) {
- pull(param, localRepoFile, remoteUrl, rate);
+ Iterator iterator = list.iterator();
+ FxAsyncTask.runOnce(System.currentTimeMillis(), "批量更新", () -> {
+ while (iterator.hasNext()) {
+ if (FxThreadPoolTask.THREAD_DEALING_NUM.get() >= 5) {
+ Thread.sleep(1500);
+ continue;
+ }
+ GitProject project = iterator.next();
+ FxThreadPoolTask.runVirtualPool(FxTask.createTask(System.currentTimeMillis(), "更新项目",
+ () -> {
+ SimpleDoubleProperty rate = project.downloadRate();
+ File localRepoFile = new File(project.local().get());
+ String remoteUrl = project.remote();
+ if ("Gitee".equals(JGitUtils.getType(remoteUrl)) && JGitUtils.GITEE_FAIL_NUMBER.get() < 10) {
+ pull(project, localRepoFile, remoteUrl, rate);
+ } else if ("Github".equals(JGitUtils.getType(remoteUrl)) && JGitUtils.GITHUB_FAIL_NUMBER.get() < 5) {
+ pull(project, localRepoFile, remoteUrl, rate);
+ }
+ },
+ () -> {
+ // 正在运行task -1
+ FxThreadPoolTask.THREAD_DEALING_NUM.decrementAndGet();
+ FxApplicationContextUtils.UPDATE_PROPERTY.set(String.valueOf(FxApplicationContextUtils.UPDATE_NUMBER.decrementAndGet()));
+ selectAll.setSelected(false);
+ }, () -> {
+ // 正在运行task -1
+ FxThreadPoolTask.THREAD_DEALING_NUM.decrementAndGet();
+ FxApplicationContextUtils.UPDATE_PROPERTY.set(String.valueOf(FxApplicationContextUtils.UPDATE_NUMBER.decrementAndGet()));
+ }));
}
- } catch (AuthException e) {
- LOGGER.error("项目 {} 需要权限", remoteUrl);
- } catch (TimeOutException | JGitException ignored) {
-
- } catch (Exception e) {
- LOGGER.error("项目更新异常:{}", e.getMessage());
- }
- // 更新更新数量-1
- FxApplicationContextUtils.UPDATE_PROPERTY.set(String.valueOf(FxApplicationContextUtils.UPDATE_NUMBER.decrementAndGet()));
- });
- updateButton.setDisable(false);
- }));
- event.consume();
+ },
+ () -> updateButton.setDisable(false),
+ () -> updateButton.setDisable(false));
});
// 删除
@@ -235,36 +240,6 @@ public class ManagerView extends StackPane {
});
}
- public static void showAuthPane(String remoteUrl, File file, GitProject project, SimpleDoubleProperty rate, Button updateButton) throws Exception {
- // 弹出输入权限界面
- AuthenticationPane authPane = AuthenticationPane.getInstance();
- authPane.refreshData(remoteUrl, (username, password) -> {
- GitAuthInfo authInfo = authPane.dealAuthInfo(username, password, JGitUtils.getType(remoteUrl));
- if (authInfo != null) {
- // 更新
- // 更新更新数量+1
- FxApplicationContextUtils.UPDATE_PROPERTY.set(String.valueOf(FxApplicationContextUtils.UPDATE_NUMBER.incrementAndGet()));
- try {
- CredentialsProvider provider = JGitUtils.createCredential(username, password);
- boolean pull = JGitUtils.pull(remoteUrl, file, provider, rate);
- if (pull) {
- project.updateTime().set(DateUtils.formatDateTime(new Date()));
- H2PoolUtils.updateGitProject(project);
- project.selected().set(false);
- }
- } catch (AuthException e1) {
- // 弹出输入权限界面
- Platform.runLater(() -> authPane.show((Scene) FxApplicationContextUtils.GLOBAL_CONTEXT_MAP.get("scene")));
- } catch (TimeOutException | JGitException ignored) {
-
- }
- // 更新更新数量-1
- FxApplicationContextUtils.UPDATE_PROPERTY.set(String.valueOf(FxApplicationContextUtils.UPDATE_NUMBER.decrementAndGet()));
- }
- });
- Platform.runLater(() -> authPane.show((Scene) FxApplicationContextUtils.GLOBAL_CONTEXT_MAP.get("scene")));
- }
-
public static void pull(GitProject project, File localRepoFile, String remoteUrl, SimpleDoubleProperty rate) {
GitAuthInfo existsAuthInfo = JGitUtils.isExistsAuthInfo(project.remote());
CredentialsProvider provider = null;
diff --git a/src/main/java/com/light/view/NotificationView.java b/src/main/java/com/light/view/NotificationView.java
index af09622f24eaa18eed5fe732ec447cd7e1039390..7b203a037c8e7801783f1a7cf283d13b16669dd9 100644
--- a/src/main/java/com/light/view/NotificationView.java
+++ b/src/main/java/com/light/view/NotificationView.java
@@ -3,12 +3,13 @@ package com.light.view;
import atlantafx.base.theme.Styles;
import com.light.util.FxApplicationContextUtils;
import javafx.collections.ListChangeListener;
+import javafx.scene.layout.HBox;
import javafx.scene.text.Text;
public class NotificationView extends Text {
public NotificationView() {
super(FxApplicationContextUtils.HISTORY_NOTICE_LIST.size() + "");
getStyleClass().addAll(Styles.TEXT, Styles.WARNING);
- FxApplicationContextUtils.HISTORY_NOTICE_LIST.addListener((ListChangeListener) c -> setText(FxApplicationContextUtils.HISTORY_NOTICE_LIST.size() + ""));
+ FxApplicationContextUtils.HISTORY_NOTICE_LIST.addListener((ListChangeListener) c -> setText(FxApplicationContextUtils.HISTORY_NOTICE_LIST.size() + ""));
}
}
diff --git a/src/main/resources/css/menu.css b/src/main/resources/css/menu.css
index f2a1ba5901ac9a45378b583def9ecf86633dc144..6eb5422b58c69fc5c434680eb77191be2aaec4f2 100644
--- a/src/main/resources/css/menu.css
+++ b/src/main/resources/css/menu.css
@@ -151,4 +151,9 @@
.cf-message.danger > .ikonli-font-icon {
-fx-icon-color: -cf-danger-color;
+}
+
+.payment-qrcode {
+ -fx-pref-width: 50px;
+ -fx-pref-height: 50px;
}
\ No newline at end of file
diff --git a/src/main/resources/icons/author.png b/src/main/resources/icons/author.png
new file mode 100644
index 0000000000000000000000000000000000000000..5ee94d2d0529fbd76aa26b7237da76ff33528904
Binary files /dev/null and b/src/main/resources/icons/author.png differ
diff --git a/src/main/resources/icons/qrcode.jpg b/src/main/resources/icons/qrcode.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..6816c812f9591854379517f620bd929ae4d91168
Binary files /dev/null and b/src/main/resources/icons/qrcode.jpg differ