Hunter0x7c7
2023-09-08 c64f00a1f9a91cb82bd1b8308e0c9b29ef5de76f
版本v1.0.1(2)发布。
5个文件已修改
224 ■■■■■ 已修改文件
readme.md 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/github/hunter0x7c7/sync/ctrls/Controller.java 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/github/hunter0x7c7/sync/model/global/Parameters.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/github/hunter0x7c7/sync/utils/DateUtils.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/github/hunter0x7c7/sync/utils/PathUtil.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
readme.md
@@ -2,17 +2,19 @@
根据目标数据库中的传感器数据列表,到总表中查找最新的数据值
将idea中的JavaFX项目打包成可执行的exe应用
 - 将idea中的JavaFX项目打包成可执行的exe应用
https://blog.csdn.net/qq_29428909/article/details/122103131
JavaFx 自定义系统托盘
 - JavaFx 自定义系统托盘
https://www.jianshu.com/p/6058e7a48f0b
~~~~
```
.ico文件在线转换
http://www.ico51.cn
.icns文件在线转换 
https://www.alltoall.net/png_icns
https://cloudconvert.com/png-to-icns
```
## 解决系统托盘乱码问题
1. 运行乱码,Run->Edit Configurations->Modify options->Add VM options->输入“-Dfile.encoding=GBK”
src/main/java/com/github/hunter0x7c7/sync/ctrls/Controller.java
@@ -7,11 +7,13 @@
import com.github.hunter0x7c7.sync.model.storage.Session;
import com.github.hunter0x7c7.sync.utils.*;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.Observer;
import io.reactivex.*;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.functions.Predicate;
import io.reactivex.schedulers.Schedulers;
import javafx.application.Platform;
import javafx.event.ActionEvent;
@@ -177,7 +179,7 @@
                    public void accept(Object o) throws Exception {
                        //添加到系统托盘
                        Stage primaryStage = Session.getInstance().getPrimaryStage();
                        String tooltip = String.format("%s v%s", AppName, VersionName);//SyncTools v1.0
                        //String tooltip = String.format("%s v%s", AppName, VersionName);//SyncTools v1.0
                        String mipmap = "mipmap/ic_chinese_cabbage_16.png";
                        MenuItem show = new MenuItem("显示");//显示Show
                        //绑定系统托盘事件
@@ -197,78 +199,109 @@
                            }
                        };
                        //添加到系统托盘
                        TrayUtil.getInstance().addSystemTray(primaryStage, AppNameString, mipmap, callback, show);
                        TrayUtil.getInstance().addSystemTray(primaryStage, AppName_zh_rCN, mipmap, callback, show);
                    }
                }).doOnNext(new Consumer<Object>() {
                }).concatMap(new Function<Object, Observable<ConfigBean>>() {//准备初始化的配置数据
                    @Override
                    public void accept(Object o) throws Exception {
                    public Observable<ConfigBean> apply(Object o) throws Exception {
                        //初始化已保存的配置信息
                        ConfigBean cb = getSaveConfig();
                        if (cb != null) {
                            //UI线程
                            Platform.runLater(new Runnable() {
                                @Override
                                public void run() {
                                    setInputText(tvInputSrcHost, cb.getSrcHost());
                                    setInputText(tvInputSrcName, cb.getSrcName());
                                    setInputText(tvInputSrcPwd, getDecryptData(cb.getSrcPwd()));
                                    setInputText(tvInputSrcDbName, cb.getSrcDbName());
                                    setInputText(tvInputTargetHost, cb.getTargetHost());
                                    setInputText(tvInputTargetName, cb.getTargetName());
                                    setInputText(tvInputTargetPwd, getDecryptData(cb.getTargetPwd()));
                                    setInputText(tvInputTargetDbName, cb.getTargetDbName());
                                    setInputText(tvInputFreq, cb.getFreqValue());
                                    cbSelectFreqUnit.getSelectionModel().select(cb.getFreqUnit());
                                    //默认启动同步功能
                                    if (cb.isStartSync()) {
                                        startSync();    //启动同步功能
                        final ConfigBean configBean = getSaveConfig();
                        return Observable.just(configBean != null)
                                .subscribeOn(Schedulers.io())
                                .filter(new Predicate<Boolean>() {
                                    @Override
                                    public boolean test(Boolean aBoolean) throws Exception {
                                        //return false过滤, true不过滤。false立刻执行switchIfEmpty
                                        return aBoolean != null && aBoolean;
                                    }
                                }
                            });
                                }).map(new Function<Boolean, ConfigBean>() {
                                    @Override
                                    public ConfigBean apply(Boolean aBoolean) throws Exception {
                                        return configBean;
                                    }
                                }).switchIfEmpty(new Observable<ConfigBean>() {
                                    @Override
                                    protected void subscribeActual(Observer<? super ConfigBean> observer) {
                                        //如果是Debug环境才初始化测试数据
                                        if (BuildType.equals(BuildTypeEnum.DEBUG)) {
                                            String srcHost = ConfigProperties.SRC_HOST;
                                            String srcName = ConfigProperties.SRC_NAME;
                                            String srcPwd = ConfigProperties.SRC_PWD;
                                            String srcDbName = ConfigProperties.SRC_DB_NAME;
                        } else if (BuildType.equals(BuildTypeEnum.DEBUG)) {
                            try {
                                String srcHost = ConfigProperties.SRC_HOST;
                                String srcName = ConfigProperties.SRC_NAME;
                                String srcPwd = ConfigProperties.SRC_PWD;
                                String srcDbName = ConfigProperties.SRC_DB_NAME;
                                            String targetHost = ConfigProperties.TARGET_HOST;
                                            String targetName = ConfigProperties.TARGET_NAME;
                                            String targetPwd = ConfigProperties.TARGET_PWD;
                                            String targetDbName = ConfigProperties.TARGET_DB_NAME;
                                String targetHost = ConfigProperties.TARGET_HOST;
                                String targetName = ConfigProperties.TARGET_NAME;
                                String targetPwd = ConfigProperties.TARGET_PWD;
                                String targetDbName = ConfigProperties.TARGET_DB_NAME;
                                            String freqValue = "5";
                                            int freqUnitIndex = 1;//秒
                                            ConfigBean cb = new ConfigBean(srcHost, srcName, srcPwd, srcDbName, targetHost, targetName, targetPwd, targetDbName, freqValue, freqUnitIndex, false);
                                            if (observer != null) {
                                                observer.onNext(cb);
                                                observer.onComplete();
                                            }
                                        } else {
                                            if (observer != null) {
                                                observer.onNext(new ConfigBean());
                                                observer.onComplete();
                                            }
                                        }
                                    }
                                });
                    }
                }).concatMap(new Function<ConfigBean, ObservableSource<ConfigBean>>() {//更新配置数据到界面
                    @Override
                    public ObservableSource<ConfigBean> apply(final ConfigBean cb) throws Exception {
                        //数据为空,不更新界面
                        if (cb == null) {
                            return Observable.just(new ConfigBean());
                        }
                        //更新界面
                        return Observable.create(new ObservableOnSubscribe<ConfigBean>() {
                            @Override
                            public void subscribe(ObservableEmitter<ConfigBean> emitter) throws Exception {
                                //UI线程
                                Platform.runLater(new Runnable() {
                                    @Override
                                    public void run() {
                                        setInputText(tvInputSrcHost, srcHost);
                                        setInputText(tvInputSrcName, srcName);
                                        setInputText(tvInputSrcPwd, srcPwd);
                                        setInputText(tvInputSrcDbName, srcDbName);
                                        setInputText(tvInputTargetHost, targetHost);
                                        setInputText(tvInputTargetName, targetName);
                                        setInputText(tvInputTargetPwd, targetPwd);
                                        setInputText(tvInputTargetDbName, targetDbName);
                                        setInputText(tvInputFreq, "10");
                                        cbSelectFreqUnit.getSelectionModel().select(1);
                                        //更新界面数据
                                        setInputText(tvInputSrcHost, cb.getSrcHost());
                                        setInputText(tvInputSrcName, cb.getSrcName());
                                        setInputText(tvInputSrcPwd, getDecryptData(cb.getSrcPwd()));
                                        setInputText(tvInputSrcDbName, cb.getSrcDbName());
                                        setInputText(tvInputTargetHost, cb.getTargetHost());
                                        setInputText(tvInputTargetName, cb.getTargetName());
                                        setInputText(tvInputTargetPwd, getDecryptData(cb.getTargetPwd()));
                                        setInputText(tvInputTargetDbName, cb.getTargetDbName());
                                        setInputText(tvInputFreq, cb.getFreqValue());
                                        cbSelectFreqUnit.getSelectionModel().select(cb.getFreqUnit());
                                        if (emitter != null) {
                                            emitter.onNext(cb);
                                            emitter.onComplete();
                                        }
                                    }
                                });
                            } catch (Exception e) {
                                throw new RuntimeException(e);
                            }
                        }
                        });
                    }
                }).subscribe(new Consumer<Object>() {
                }).subscribe(new Consumer<ConfigBean>() {
                    @Override
                    public void accept(Object o) throws Exception {
                    public void accept(ConfigBean cb) throws Exception {
                        //UI线程
                        Platform.runLater(new Runnable() {
                            @Override
                            public void run() {
                                updateResult("数据同步工具");
                                //默认启动同步功能
                                if (cb != null && cb.isStartSync()) {
                                    startSync();    //启动同步功能
                                }
                            }
                        });
                    }
@@ -599,12 +632,12 @@
        operate.setAlignment(Pos.CENTER_RIGHT);
        operate.setSpacing(8);
//        operate.setStyle("-fx-background-color: #F0F0F0");
        operate.setPadding(new Insets(12, 20, 8, 20));
        operate.setPadding(new Insets(12, 20, 12, 20));
        operate.getChildren().addAll(defButton, cancelButton);
        VBox vBox = new VBox();
        vBox.setSpacing(0);
        vBox.setPadding(getInsets());
        //vBox.setPadding(getInsets());
        vBox.getChildren().addAll(content, operate);
        stage.setScene(new Scene(vBox));
@@ -654,7 +687,7 @@
        VBox vBox = new VBox();
        vBox.setPadding(new Insets(20, 20, 4, 20));
        vBox.setPadding(new Insets(20, 20, 10, 20));
        vBox.getChildren().addAll(label1, label2, label3, label4);
        stage.setScene(new Scene(vBox));
@@ -814,9 +847,9 @@
                        }
                    }
                })
                .concatMap(new Function<Integer, ObservableSource<String>>() {
                .concatMap(new Function<Integer, ObservableSource<Object>>() {
                    @Override
                    public ObservableSource<String> apply(Integer freq) throws Exception {
                    public ObservableSource<Object> apply(Integer freq) throws Exception {
                        int delay = freq > 0 ? freq : 10;
                        TimeUnit timeUnit = ListUtil.getDataByList(mFreqUnitList, freqSelect);
@@ -824,16 +857,37 @@
                        //System.out.println("delay:" + delay + " unit:" + unit);
                        return Observable.timer(delay, unit)
                                /*.doOnNext(new Consumer<Long>() {
                                .doOnNext(new Consumer<Long>() {
                                    @Override
                                    public void accept(Long aLong) throws Exception {
                                        startSync(srcHost, srcName, srcPwd, srcDbName, targetHost, targetName, targetPwd, targetDbName);
                                        //如果中途某次执行失败,不能导致整个计划的失败
                                        addSubscribe(getStartSyncObservable(srcHost, srcName, srcPwd, srcDbName, targetHost, targetName, targetPwd, targetDbName)
                                                .subscribe(new Consumer<Object>() {
                                                    @Override
                                                    public void accept(Object o) throws Exception {
                                                        //同步成功!
                                                        setSyncing(true);
                                                        mSyncCount++;
                                                        if (mSyncCount >= Integer.MAX_VALUE) {
                                                            mSyncCount = 0;
                                                        }
                                                        setInputText(txLastSyncTime, DateUtils.formatDate(new Date()));
                                                        setInputText(txSyncCount, String.valueOf(mSyncCount));
                                                        updateResult("同步成功!");
                                                    }
                                                }, new Consumer<Throwable>() {
                                                    @Override
                                                    public void accept(Throwable e) throws Exception {
                                                        e.printStackTrace();
                                                        //执行失败
                                                        updateResult(e.getMessage());
                                                    }
                                                }));
                                    }
                                })*/
                                .concatMap(new Function<Long, ObservableSource<String>>() {
                                }).map(new Function<Long, Object>() {
                                    @Override
                                    public ObservableSource<String> apply(Long o) throws Exception {
                                        return getStartSyncObservable(srcHost, srcName, srcPwd, srcDbName, targetHost, targetName, targetPwd, targetDbName);
                                    public Object apply(Long aLong) throws Exception {
                                        return String.valueOf(aLong);
                                    }
                                }).repeat();
                    }
@@ -842,21 +896,14 @@
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        setSyncing(true);
                        mSyncCount++;
                        if (mSyncCount >= Integer.MAX_VALUE) {
                            mSyncCount = 0;
                        }
                        setInputText(txLastSyncTime, DateUtils.formatDate(new Date()));
                        setInputText(txSyncCount, String.valueOf(mSyncCount));
                        updateResult("同步成功!");
                        //流程执行完毕
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        throwable.printStackTrace();
                        updateResult(throwable.getMessage());
                    public void accept(Throwable e) throws Exception {
                        e.printStackTrace();
                        //执行失败
                        updateResult(e.getMessage());
                    }
                }));
    }
@@ -1054,7 +1101,8 @@
    }
    private void updateResult(String str) {
        System.out.println(str);
        //输出结果带时间
        System.out.printf("%s\t%s%n", DateUtils.formatDate(new Date()), str);
        setInputText(txOutResult, str);
    }
src/main/java/com/github/hunter0x7c7/sync/model/global/Parameters.java
@@ -2,18 +2,19 @@
import com.github.hunter0x7c7.sync.utils.StringUtil;
//参数设置
public class Parameters {
    public static final int VersionCode = 2;
    public static final String VersionName = "1.0.1";
    public static final String BuildDate = "230812";
    public static final String BuildDate = "230818";
    public static final BuildTypeEnum BuildType = BuildTypeEnum.RELEASE;
    public static final String AppName = "SyncTools";
    //数据同步工具(传感器) v1.0.1
    public static final String AppNameString = String.format("数据同步工具(传感器) v%s", VersionName);
    public static final String AppName_zh_rCN = "数据同步工具(传感器)";
    //数据同步工具(传感器) v1.0.1 - SyncTools
    public static final String AppNameString = String.format("%s v%s - %s", AppName_zh_rCN, VersionName, AppName);
    public static final String Author = "Hunter";
    public static final String APPID = "com.github.hunter0x7c7.SyncTools";
src/main/java/com/github/hunter0x7c7/sync/utils/DateUtils.java
@@ -7,7 +7,7 @@
import java.util.*;
public final class DateUtils {
    public static final String PATTERN_Def = "yyyy-MM-dd HH:mm:ss";
    public static final String PATTERN_Def = "yyyy.MM.dd HH:mm:ss";
    public static final String PATTERN_RFC1123 = "EEE, dd MMM yyyy HH:mm:ss zzz";
    public static final String PATTERN_RFC1036 = "EEE, dd-MMM-yy HH:mm:ss zzz";
    public static final String PATTERN_ASCTIME = "EEE MMM d HH:mm:ss yyyy";
src/main/java/com/github/hunter0x7c7/sync/utils/PathUtil.java
@@ -2,6 +2,7 @@
import java.io.File;
import java.net.URL;
import java.net.URLDecoder;
public class PathUtil {
    /**
@@ -27,7 +28,7 @@
        URL url = PathUtil.class.getProtectionDomain().getCodeSource().getLocation();
        String filePath = null;
        try {
            filePath = java.net.URLDecoder.decode(url.getPath(), "utf-8");
            filePath = URLDecoder.decode(url.getPath(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
@@ -64,7 +65,7 @@
        File file = new File(realPath);
        realPath = file.getAbsolutePath();//去掉了最前面的斜杠/
        try {
            realPath = java.net.URLDecoder.decode(realPath, "utf-8");
            realPath = URLDecoder.decode(realPath, "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        }