diff --git a/.gitignore b/.gitignore
index 0e13eeb..e5dba25 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,8 +4,5 @@ pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
-dependency-reduced-pom.xml
-buildNumber.properties
-.mvn/timing.properties
-# https://github.com/takari/maven-wrapper#usage-without-binary-jar
-.mvn/wrapper/maven-wrapper.jar
+*.iml
+.idea/
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..99d9792
--- /dev/null
+++ b/README.md
@@ -0,0 +1,20 @@
+## 大屏客户端
+
+### 介绍
+一体机、大屏、展示屏等终端设备需要全屏展示H5应用或统计大屏客户端;
+本程序采用java编写,内核采用jcef java版本,目前支持直接打包为exe,其他系统支持需要二次开发
+
+### 开发环境
+jdk 11+
+
+### 构建工具
+Maven 3+
+
+##### 版本说明
+###### v0.0.1-SNAPSHOT
+1. 开机自启
+2. 自动全屏
+3. 支持本地静态文件和在线地址
+
+### 联系方式
+E-Mail:wangbing@wbsite.xyz
diff --git a/ScreenClient.ico b/ScreenClient.ico
new file mode 100644
index 0000000..b46159a
Binary files /dev/null and b/ScreenClient.ico differ
diff --git a/default.config b/default.config
new file mode 100644
index 0000000..8ed8058
--- /dev/null
+++ b/default.config
@@ -0,0 +1,8 @@
+#标题,默认ScreenClient
+title=ScreenClient
+
+#启动打开地址,不写默认html/index.html
+url=html/index.html
+
+#默认大小,full全屏,normal正常
+size=full
diff --git a/html/index.html b/html/index.html
new file mode 100644
index 0000000..884cadd
--- /dev/null
+++ b/html/index.html
@@ -0,0 +1,38 @@
+
+
+
+Welcome to ScreenClient!
+
+
+
+Welcome to ScreenClient!
+If you see this page, the ScreenClient server is successfully installed and
+working. Further configuration is required.
+
+Config
+
+To modify the configuration please refer to 【default.config】
+
+
+ - title : Title of the application
+ - url : File path (absolute or relative) or online address, default to html/index.htm
+ - size : Default size at startup, full or normal
+
+
+Shortcut
+
+
+ - Esc : exit
+ - F1 : set auto start
+ - F2 : del auto start
+ - F5 : refresh
+ - F11 : full screen or normal
+
+
+Thank you for using ScreenClient.
+
+
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..6d399b1
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,163 @@
+
+
+ 4.0.0
+
+ xyz.wbsite
+ ScreenClient
+ 0.0.1-SNAPSHOT
+ jar
+ ScreenClient
+ ScreenClient
+
+
+ UTF-8
+ UTF-8
+ 11
+ true
+ 2.3.7.RELEASE
+ Hoxton.SR8
+
+
+
+
+
+ central
+ Central Repository
+ default
+ https://maven.aliyun.com/repository/public
+
+
+
+
+
+ central
+ Central Repository
+ https://maven.aliyun.com/repository/public
+ default
+
+
+
+
+
+ me.friwi
+ jcefmaven
+ 110.0.25.1
+
+
+
+ cn.hutool
+ hutool-all
+ 5.8.0.M2
+
+
+
+
+ me.friwi
+ jcef-natives-windows-amd64
+ jcef-87476e9+cef-110.0.25+g75b1c96+chromium-110.0.5481.78
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ com.melloware
+ jintellitype
+ 1.4.0
+
+
+
+
+
+ ${artifactId}-${version}
+
+ src/main/java
+
+ src/test/java
+
+
+ src/main/resources
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ ${java.version}
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+
+
+
+ ${project.basedir}/src/main/resources/lib
+ WEB-INF/lib
+
+ *.jar
+
+
+
+
+
+
+
+ io.github.fvarrui
+ javapackager
+ 1.7.1
+
+
+ package
+
+ package
+
+
+
+ xyz.wbsite.screen.Starter
+
+ true
+ true
+ false
+ windows
+ ${artifactId}
+ ${version}
+
+ ${project.basedir}/html
+ ${project.basedir}/log
+ ${project.basedir}/default.config
+ ${project.basedir}/service.bat
+
+
+
+
+ ${project.basedir}/ScreenClient.ico
+ false
+ false
+ false
+
+
+
+
+
+
+
+
diff --git a/src/main/java/xyz/wbsite/screen/Starter.java b/src/main/java/xyz/wbsite/screen/Starter.java
new file mode 100644
index 0000000..52eb005
--- /dev/null
+++ b/src/main/java/xyz/wbsite/screen/Starter.java
@@ -0,0 +1,63 @@
+package xyz.wbsite.screen;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.log.StaticLog;
+import cn.hutool.setting.dialect.Props;
+import me.friwi.jcefmaven.CefInitializationException;
+import me.friwi.jcefmaven.UnsupportedPlatformException;
+import xyz.wbsite.screen.client.ShortCutUtil;
+import xyz.wbsite.screen.client.WebClient;
+
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.io.File;
+import java.io.IOException;
+
+public class Starter {
+
+ public void run() throws InterruptedException, UnsupportedPlatformException, CefInitializationException, IOException {
+ // 检查配置文件
+ File configFile = new File("default.config");
+ System.out.println(configFile.getAbsolutePath());
+ if (!FileUtil.exist(configFile)) {
+ throw new IllegalArgumentException("default.config not exist!");
+ }
+ // 初始化配置
+ Props props = new Props(configFile);
+ // 初始化客户端
+ WebClient webClient = new WebClient(props);
+ // 焦点事件监听
+ webClient.addFocusListener(new FocusListener() {
+ @Override
+ public void focusGained(FocusEvent e) {
+ StaticLog.debug("获得焦点事件");
+ }
+
+ @Override
+ public void focusLost(FocusEvent e) {
+ StaticLog.debug("丢失焦点事件");
+ }
+ });
+
+ // 添加一个鼠标点击监听
+ webClient.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ StaticLog.debug("鼠标点击事件");
+ }
+ });
+
+ // 调用脚本
+ webClient.executeJavaScript("console.log('java 调用 JavaScript')");
+
+ // 创建快捷方式使用
+ File targetFile = new File("ScreenClient.exe");
+ ShortCutUtil.createShortCutForDesktop(targetFile);
+ }
+
+ public static void main(String[] args) throws InterruptedException, UnsupportedPlatformException, CefInitializationException, IOException {
+ new Starter().run();
+ }
+}
diff --git a/src/main/java/xyz/wbsite/screen/client/KeyEnum.java b/src/main/java/xyz/wbsite/screen/client/KeyEnum.java
new file mode 100644
index 0000000..6ab038c
--- /dev/null
+++ b/src/main/java/xyz/wbsite/screen/client/KeyEnum.java
@@ -0,0 +1,58 @@
+package xyz.wbsite.screen.client;
+
+public enum KeyEnum {
+
+ F1(112),
+ F2(113),
+ F3(114),
+ F4(115),
+ F5(116),
+ F6(117),
+ F7(118),
+ F8(119),
+ F9(120),
+ F10(121),
+ F11(122),
+ F12(123),
+ ESC(27),
+ TAB(9),
+ CAPSLOCK(20),
+ SHIFT(16),
+ CTRL(17),
+ START_LEFT(91),
+ START_RIGHT(92),
+ CONTEXT_MENU(93),
+ ALT(18),
+ SPACE(32),
+ CARRIAGE_RETURN(13),
+ LINE_FEED(10),
+ BACK_SLASH(220),
+ BACK_SPACE(8),
+ INSERT(45),
+ DEL(46),
+ HOME(36),
+ END(35),
+ PAGE_UP(33),
+ PAGE_DOWN(34),
+ PRINT_SCREEN(44),
+ SCR_LK(145),
+ PAUSE(19),
+ LEFT_ARROW_KEY(37),
+ UP_ARROW_KEY(38),
+ RIGHT_ARROW_KEY(39),
+ DOWN_ARROW_KEY(40),
+ MOD_ALT(1),
+ MOD_CONTROL(2),
+ MOD_SHIFT(4),
+ MOD_WIN(8);
+
+ private int value;
+
+ KeyEnum(int value) {
+ this.value = value;
+ }
+
+ public int value() {
+ return value;
+ }
+}
diff --git a/src/main/java/xyz/wbsite/screen/client/ShortCutUtil.java b/src/main/java/xyz/wbsite/screen/client/ShortCutUtil.java
new file mode 100644
index 0000000..88fea45
--- /dev/null
+++ b/src/main/java/xyz/wbsite/screen/client/ShortCutUtil.java
@@ -0,0 +1,177 @@
+package xyz.wbsite.screen.client;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.system.SystemUtil;
+
+import javax.swing.filechooser.FileSystemView;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.channels.FileChannel;
+
+public class ShortCutUtil {
+
+ /**
+ * 文件头,固定字段
+ */
+ private static byte[] headFile = {0x4c, 0x00, 0x00, 0x00,
+ 0x01, 0x14, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ (byte) 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46
+ };
+ /**
+ * 文件头属性
+ */
+ private static byte[] fileAttributes = {(byte) 0x93, 0x00, 0x08, 0x00,//可选文件属性
+ 0x20, 0x00, 0x00, 0x00,//目标文件属性
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,//文件创建时间
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,//文件修改时间
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,//文件最后一次访问时间
+ 0x00, 0x00, 0x00, 0x00,//文件长度
+ 0x00, 0x00, 0x00, 0x00,//自定义图标个数
+ 0x01, 0x00, 0x00, 0x00,//打开时窗口状态
+ 0x00, 0x00, 0x00, 0x00,//热键
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00//未知
+ };
+ /**
+ * 固定字段1
+ */
+ static byte[] fixedValueOne = {
+ (byte) 0x83, 0x00, 0x14, 0x00
+ , 0x1F, 0x50, (byte) 0xE0, 0x4F
+ , (byte) 0xD0, 0x20, (byte) 0xEA
+ , 0x3A, 0x69, 0x10, (byte) 0xA2
+ , (byte) 0xD8, 0x08, 0x00, 0x2B
+ , 0x30, 0x30, (byte) 0x9D, 0x19, 0x00, 0x2f
+ };
+ /**
+ * 固定字段2
+ */
+ static byte[] fixedValueTwo = {
+ 0x3A, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ , 0x00, 0x54, 0x00, 0x32, 0x00, 0x04
+ , 0x00, 0x00, 0x00, 0x67, 0x50, (byte) 0x91, 0x3C, 0x20, 0x00
+ };
+
+ /**
+ * 复制文件
+ *
+ * @param source
+ * @param dest
+ * @throws IOException
+ */
+ private static void copyFileUsingFileChannels(File source, File dest) throws IOException {
+ FileChannel inputChannel = null;
+ FileChannel outputChannel = null;
+ try {
+ inputChannel = new FileInputStream(source).getChannel();
+ outputChannel = new FileOutputStream(dest).getChannel();
+ outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
+ } finally {
+ inputChannel.close();
+ outputChannel.close();
+ }
+ }
+
+ /**
+ * 创建快捷方式
+ *
+ * @param lnk 快捷方式文件路径
+ * @param target 目标文件(exe,path,bat...)
+ */
+ public static void createShortCut(File lnk, File target) {
+ if (!SystemUtil.getOsInfo().isWindows()) {
+ System.out.println("当前系统不是window系统,无法创建快捷方式!!");
+ return;
+ }
+
+ try {
+ File touch = FileUtil.touch(lnk);
+ BufferedOutputStream stream = FileUtil.getOutputStream(touch);
+ stream.write(headFile);
+ stream.write(fileAttributes);
+ stream.write(fixedValueOne);
+ stream.write((target.getAbsolutePath().toCharArray()[0] + "").getBytes());
+ stream.write(fixedValueTwo);
+ stream.write(target.getAbsolutePath().substring(3).getBytes("gbk"));
+ stream.flush();
+ IoUtil.close(stream);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 在目标位置创建快捷方式
+ *
+ * @param target 目标
+ */
+ public static File createShortCut(File target) {
+ File lnk = new File(target.getParentFile(), FileUtil.mainName(target) + ".lnk");
+ createShortCut(lnk, target);
+ return lnk;
+ }
+
+ /**
+ * 在桌面创建快捷方式
+ *
+ * @param target 目标
+ */
+ public static File createShortCutForDesktop(File target) {
+ File lnk = new File(FileSystemView.getFileSystemView().getHomeDirectory(), FileUtil.mainName(target) + ".lnk");
+ createShortCut(lnk, target);
+ return lnk;
+ }
+
+ /**
+ * 设置某软件开启启动
+ *
+ * @param targetFile 源文件
+ * @return 是否设置成功
+ */
+ public static boolean setStartup(File targetFile, boolean forAllUser) {
+ File shortCut = createShortCut(targetFile);
+ // 用户启动目录
+ String userStartup = System.getProperty("user.home") + "\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\";
+ // 系统启动目录
+ String sysStartup = "C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Startup";
+ String startup = forAllUser ? sysStartup : userStartup;
+ // 快捷方式复制到启动目录
+ FileUtil.copy(shortCut, new File(startup, shortCut.getName()), true);
+ return true;
+ }
+
+ public static boolean delStartup(File targetFile, boolean forAllUser) {
+ File shortCut = createShortCut(targetFile);
+ // 用户启动目录
+ String userStartup = System.getProperty("user.home") + "\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\";
+ // 系统启动目录
+ String sysStartup = "C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Startup";
+ String startup = forAllUser ? sysStartup : userStartup;
+ FileUtil.del(new File(startup, shortCut.getName()));
+ return true;
+ }
+
+ /**
+ * 设置软件开机启动
+ *
+ * @param targetFile 源文件
+ * @return 是否设置成功
+ */
+ public static boolean setStartup(File targetFile) {
+ return setStartup(targetFile, false);
+ }
+
+ /**
+ * 删除软件开机启动
+ *
+ * @param targetFile 源文件
+ * @return 是否设置成功
+ */
+ public static boolean delStartup(File targetFile) {
+ return delStartup(targetFile, false);
+ }
+}
diff --git a/src/main/java/xyz/wbsite/screen/client/WebClient.java b/src/main/java/xyz/wbsite/screen/client/WebClient.java
new file mode 100644
index 0000000..5b0ebe3
--- /dev/null
+++ b/src/main/java/xyz/wbsite/screen/client/WebClient.java
@@ -0,0 +1,268 @@
+package xyz.wbsite.screen.client;
+
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.img.ImgUtil;
+import cn.hutool.core.io.resource.ResourceUtil;
+import cn.hutool.log.StaticLog;
+import com.melloware.jintellitype.HotkeyListener;
+import com.melloware.jintellitype.JIntellitype;
+import me.friwi.jcefmaven.CefAppBuilder;
+import me.friwi.jcefmaven.CefBuildInfo;
+import me.friwi.jcefmaven.CefInitializationException;
+import me.friwi.jcefmaven.MavenCefAppHandlerAdapter;
+import me.friwi.jcefmaven.UnsupportedPlatformException;
+import org.cef.CefApp;
+import org.cef.CefClient;
+import org.cef.browser.CefBrowser;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.FocusListener;
+import java.awt.event.KeyListener;
+import java.awt.event.MouseListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Properties;
+
+public class WebClient extends JFrame {
+
+ // 退出
+ private final int KEY_MARK_ESC = 1;
+ // 最小化
+ private final int KEY_MARK_SWITCH = 2;
+ // 刷新
+ private final int KEY_MARK_RELOAD = 3;
+ // 添加自启
+ private final int KEY_MARK_SET_START = 4;
+ // 移除自启
+ private final int KEY_MARK_DEL_START = 5;
+
+ private CefClient cefClient;
+ private CefApp cefApp;
+ private CefBrowser cefBrowser;
+ private String lastUrl = "about:blank";
+ private Properties config;
+
+ private final HotkeyListener hotkeyListener = new HotkeyListener() {
+ @Override
+ public void onHotKey(int i) {
+ switch (i) {
+ case KEY_MARK_ESC: {
+ StaticLog.info("exit.");
+ JIntellitype.getInstance().unregisterHotKey(KEY_MARK_ESC);
+ JIntellitype.getInstance().removeHotKeyListener(hotkeyListener);
+ close();
+ }
+ break;
+ case KEY_MARK_SWITCH: {
+ StaticLog.info("screen switch.");
+ if (getExtendedState() == Frame.NORMAL) {
+ removeNotify();
+ setUndecorated(true);
+ setExtendedState(JFrame.MAXIMIZED_BOTH);
+ } else {
+ setExtendedState(Frame.NORMAL);
+ removeNotify();
+ setUndecorated(false);
+ }
+ setVisible(true);
+ }
+ break;
+ case KEY_MARK_RELOAD: {
+ StaticLog.info("screen reload.");
+ reload();
+ }
+ break;
+ case KEY_MARK_SET_START: {
+ StaticLog.info("screen setStartup.");
+ setStartup();
+ }
+ break;
+ case KEY_MARK_DEL_START: {
+ StaticLog.info("screen delStartup.");
+ delStartup();
+ }
+ break;
+ }
+ }
+ };
+
+ public WebClient(Properties config) {
+ this.config = config;
+ try {
+ initCef(new String[]{});
+ initClient();
+ } catch (Exception e) {
+ StaticLog.error(e);
+ }
+ }
+
+ private void initClient() {
+ setTitle(getProp("title", "ScreenClient"));
+ getContentPane().add(cefBrowser.getUIComponent(), BorderLayout.CENTER);
+ setSize(800, 600);//初始大小
+ setLocation(0, 0);//位置
+ // 设置全屏模式
+ if ("full".equals(getProp("size", "full"))) {
+ setExtendedState(JFrame.MAXIMIZED_BOTH);
+ setUndecorated(true);
+ setAlwaysOnTop(true);
+ }
+
+ addWindowListener(new WindowAdapter() {
+ @Override
+ public void windowClosing(WindowEvent e) {
+ // 关闭应用时要释放资源
+ CefApp.getInstance().dispose();
+ dispose();
+ System.exit(0);//0正常退出,1非正常退出
+ }
+ });
+
+ // 添加热键
+ JIntellitype.getInstance().registerHotKey(KEY_MARK_ESC, 0, KeyEnum.ESC.value());
+ JIntellitype.getInstance().registerHotKey(KEY_MARK_SET_START, 0, KeyEnum.F1.value());
+ JIntellitype.getInstance().registerHotKey(KEY_MARK_DEL_START, 0, KeyEnum.F2.value());
+ JIntellitype.getInstance().registerHotKey(KEY_MARK_RELOAD, 0, KeyEnum.F5.value());
+ JIntellitype.getInstance().registerHotKey(KEY_MARK_SWITCH, 0, KeyEnum.F11.value());
+ JIntellitype.getInstance().addHotKeyListener(hotkeyListener);
+
+ //设置图标
+ URL resource = ResourceUtil.getResource("ScreenClient.png");
+ BufferedImage read = ImgUtil.read(resource);
+ setIconImage(read);
+
+ // 显示
+ setVisible(true);
+ }
+
+ /**
+ * 初始化 CefBrowser
+ *
+ * @param args
+ */
+ private void initCef(String[] args) throws InterruptedException, UnsupportedPlatformException, CefInitializationException, IOException {
+ CefAppBuilder builder = new CefAppBuilder();
+ // window下不需要OSR
+ boolean useOSR = false;
+ builder.getCefSettings().windowless_rendering_enabled = useOSR;
+ builder.setAppHandler(new MavenCefAppHandlerAdapter() {
+ @Override
+ public void stateHasChanged(org.cef.CefApp.CefAppState state) {
+ // 关闭应用时退出jvm运行
+ if (state == CefApp.CefAppState.TERMINATED) System.exit(0);
+ }
+ });
+
+ // 设置cef运行参数,这里为空
+ builder.addJcefArgs(args);
+
+ // 这边不设置,程序会自动解压
+ // 设置 cef chrome实例的目录,关键,若不设置他会默认从网络中下载,国外网络可能下载不稳定导致失败
+ // 我的 cef chrome 位于项目的chrome目录下 C:\Users\Administrator\Desktop\project\java\demo-desktop\chrome
+ // builder.setInstallDir(new File(System.getProperty("user.dir") + File.separator + "chrome"));
+ // 由于是手动设置cef的chrome,我们要跳过ins检查,防止版本不一致导致从镜像站下载
+ // builder.setSkipInstallation(true);
+
+ // 全局的 CefApp 每个程序只能有一个,线程安全
+ cefApp = builder.build();
+ // 显示一些版本信息
+ CefBuildInfo buildInfo = CefBuildInfo.fromClasspath();
+ StaticLog.info(buildInfo.toString());
+ CefApp.CefVersion cefVersion = cefApp.getVersion();
+ StaticLog.info(cefVersion.toString());
+
+ // 创建一个浏览器客户端实例
+ cefClient = cefApp.createClient();
+
+ // 创建一个浏览器实例
+ lastUrl = getProp("url", "html/index.html");
+ // 处理非http时的相对路径
+ if (!lastUrl.startsWith("http")) {
+ lastUrl = new File(lastUrl).getAbsolutePath();
+ }
+
+ cefBrowser = cefClient.createBrowser(lastUrl, useOSR, true);
+ }
+
+ /**
+ * 加载地址
+ *
+ * @param url 地址
+ * @throws InterruptedException
+ */
+ public void loadUrl(String url) throws InterruptedException {
+ // 必须延迟,否则可能因为切换太快无法加载成功
+ Thread.sleep(300);
+ lastUrl = url;
+ // 处理非http时的相对路径
+ if (!lastUrl.startsWith("http")) {
+ lastUrl = new File(lastUrl).getAbsolutePath();
+ }
+ cefBrowser.loadURL(url);
+ }
+
+ /**
+ * 刷新
+ */
+ public void reload() {
+ // 创建一个浏览器实例
+ cefBrowser = cefClient.createBrowser(lastUrl, false, true);
+ getContentPane().remove(0);
+ getContentPane().add(cefBrowser.getUIComponent(), BorderLayout.CENTER);
+ setVisible(true);
+ }
+
+ /**
+ * 开机自启
+ */
+ public void setStartup() {
+ if (ShortCutUtil.setStartup(new File("ScreenClient.exe"))) {
+ executeJavaScript("alert('set startup success')");
+ } else {
+ executeJavaScript("alert('set startup failed')");
+ }
+ }
+
+ /**
+ * 删除自启
+ */
+ public void delStartup() {
+ if (ShortCutUtil.delStartup(new File("ScreenClient.exe"))) {
+ executeJavaScript("alert('del startup success')");
+ } else {
+ executeJavaScript("alert('del startup failed')");
+ }
+ }
+
+ private String getProp(String key, String defaultValue) {
+ return Convert.toStr(config.getProperty(key), defaultValue);
+ }
+
+ public void addFocusListener(FocusListener listener) {
+ cefBrowser.getUIComponent().addFocusListener(listener);
+ }
+
+ public void addMouseListener(MouseListener listener) {
+ cefBrowser.getUIComponent().addMouseListener(listener);
+ }
+
+ public void addKeyListener(KeyListener listener) {
+ cefBrowser.getUIComponent().addKeyListener(listener);
+ }
+
+ public void executeJavaScript(String javascript) {
+ cefBrowser.executeJavaScript(javascript, null, 1);
+ }
+
+ public void close() {
+ // 关闭应用时要释放资源
+ CefApp.getInstance().dispose();
+ dispose();
+ System.exit(0);
+ }
+}
diff --git a/src/main/resources/ScreenClient.png b/src/main/resources/ScreenClient.png
new file mode 100644
index 0000000..4b0f312
Binary files /dev/null and b/src/main/resources/ScreenClient.png differ
diff --git a/src/main/resources/logging.properties b/src/main/resources/logging.properties
new file mode 100644
index 0000000..f5e15b6
--- /dev/null
+++ b/src/main/resources/logging.properties
@@ -0,0 +1,34 @@
+#-----------------------------------------------------------------------------------------------------------
+# == JDK Logging ļ ==
+#Levelȼ
+# SEVERE
+# WARNING
+# INFO
+# CONFIG
+# FINE
+# FINER
+# FINEST
+#
+#-----------------------------------------------------------------------------------------------------------
+# ־ʽ
+#java.util.logging.SimpleFormatter.format=%4$s: %5$s [%1$tc]%n
+#ָRoot Logger
+.level=ALL
+#Ϊ Handler ָĬϵļĬΪ Level.INFO
+java.util.logging.ConsoleHandler.level=ALL
+# ָҪʹõ Formatter ƣĬΪ java.util.logging.SimpleFormatter
+java.util.logging.ConsoleHandler.formatter=logging.formatter.MySimpleFormatter
+# Ϊ Handler ָĬϵļĬΪ Level.ALL
+java.util.logging.FileHandler.level=INFO
+# ָҪʹõ Formatter ƣĬΪ java.util.logging.XMLFormatter
+java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
+# ָҪд뵽ļĽֽΪλΪ 0ûƣĬΪƣ
+java.util.logging.FileHandler.limit=1024000
+# ָжļѭĬΪ 1
+java.util.logging.FileHandler.count=1
+# ΪɵļָһģʽйϸμݣĬΪ "%h/java%u.log"
+java.util.logging.FileHandler.pattern=log/info.log
+# ָǷӦý FileHandler ӵκļϣĬΪ false
+java.util.logging.FileHandler.append=true
+# ִеLogHandlerʹöŸ
+handlers=java.util.logging.ConsoleHandler,java.util.logging.FileHandler