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 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; /** 默认构造 */ 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() { @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; } }