Files
timi-fx-ui/src/main/java/com/imyeyu/fx/ui/components/VersionLabel.java
2026-01-14 14:54:15 +08:00

209 lines
4.4 KiB
Java

package com.imyeyu.fx.ui.components;
import com.imyeyu.fx.task.RunAsync;
import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.utils.Encoder;
import javafx.beans.binding.Bindings;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.geometry.Pos;
import javafx.scene.Cursor;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import java.awt.Desktop;
import java.io.IOException;
import java.net.URI;
/**
* 版本标签,此组件用于显示版本、检查更新和可更新时点击去向,目前可能只适合我使用
*
* @author 夜雨
* @since 2022-02-19 18:42
*/
public abstract class VersionLabel<T> extends VBox implements TimiFXUI, TimiFXUI.Colorful {
/**
* 状态
*
* @author 夜雨
* @since 2022-11-27 16:13
*/
protected enum Status {
/** 一般 */
NORMAL(BLACK),
/** 正在检查 */
CHECKING(ORANGE),
/** 存在更新 */
HAS_UPDATE(GREEN),
/** 错误 */
ERROR(RED);
Color textColor;
Status(Color textColor) {
this.textColor = textColor;
}
/**
* 设置该状态的文本颜色
*
* @param textColor 颜色
*/
public void setTextColor(Color textColor) {
this.textColor = textColor;
}
}
/** 更新链接 */
protected String updateURL;
/** 版本标签 */
protected Label version;
/** 其他内容标签 */
protected Label content;
/** 状态 */
protected ObjectProperty<Status> status;
/** 默认构造 */
public VersionLabel() {
this("");
}
/**
* 默认构造
*
* @param text 显示版本
*/
public VersionLabel(String text) {
status = new SimpleObjectProperty<>(Status.NORMAL);
version = new Label();
version.setText(text);
version.setWrapText(true);
version.textFillProperty().bind(Bindings.createObjectBinding(() -> status.get().textColor, status));
content = new Label();
content.managedProperty().bind(content.textProperty().isNotEmpty());
setSpacing(3);
setAlignment(Pos.CENTER);
getChildren().addAll(version, content);
}
/**
* 检查版本更新
*
* @param nowVersion 当前版本
*/
public void checkVersion(String nowVersion) {
status.set(Status.CHECKING);
version.setCursor(Cursor.DEFAULT);
version.setOnMouseClicked(null);
// ---------- 事件 ----------
new RunAsync<T>() {
@Override
protected T call() {
return VersionLabel.this.run();
}
@Override
protected void onFinish(T t) {
try {
String version = onReturn(t);
if (version.equals(nowVersion)) {
// 无新版本
VersionLabel.this.version.setText(nowVersion);
status.set(Status.NORMAL);
} else {
// 存在新版本
VersionLabel.this.version.setText(VersionLabel.this.updateText(version));
VersionLabel.this.version.setCursor(Cursor.HAND);
VersionLabel.this.version.underlineProperty().bind(VersionLabel.this.version.hoverProperty());
VersionLabel.this.version.setOnMouseClicked(event -> {
try {
Desktop dp = Desktop.getDesktop();
if (dp.isSupported(Desktop.Action.BROWSE)) {
dp.browse(URI.create(Encoder.url(updateURL)));
}
} catch (IOException e) {
e.printStackTrace();
}
});
status.set(Status.HAS_UPDATE);
}
} catch (RuntimeException e) {
version.setText(e.getMessage());
status.set(Status.ERROR);
}
}
@Override
protected void onException(Throwable e) {
version.setText(TimiFXUI.MULTILINGUAL.text("version.fail"));
version.setOnMouseClicked(event -> checkVersion(nowVersion));
e.printStackTrace();
}
}.start();
}
/**
* 执行查询版本
*
* @return 执行返回
*/
protected abstract T run() throws RuntimeException;
/**
* 执行返回
*
* @param t 返回数据
* @return 具体版本号
*/
protected abstract String onReturn(T t) throws RuntimeException;
/**
* 存在更新时执行
*
* @param newVersion 版本
* @return 显示文本
*/
protected abstract String updateText(String newVersion);
/**
* 执行异常的显示文本
*
* @param e 异常
* @return 显示文本
*/
protected abstract String failText(Throwable e);
/**
* 获取更新链接
*
* @return 更新链接
*/
public String getUpdateURL() {
return updateURL;
}
/**
* 设置更新链接
*
* @param updateURL 更新链接
*/
public void setUpdateURL(String updateURL) {
this.updateURL = updateURL;
}
}