上传备份

wjdr
王兵 3 months ago
parent 0354ebb5d9
commit 187c9bae5a

@ -7,6 +7,7 @@
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="starter-jmacro" />
<module name="jmacro" />
<module name="starter-jmacro-wjdr" />
</profile>
</annotationProcessing>

@ -43,6 +43,12 @@
<version>5.8.26</version>
</dependency>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.14.2.1</version>
</dependency>
<!-- java注册全局热键 -->
<dependency>
<groupId>com.melloware</groupId>

@ -11,6 +11,7 @@ import xyz.wbsite.jmacro.util.*;
import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
@ -300,6 +301,26 @@ public abstract class JMacro {
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
}
/**
*
*/
public void sendCopyCommand() {
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_C);
robot.keyRelease(KeyEvent.VK_C);
robot.keyRelease(KeyEvent.VK_CONTROL);
}
/**
*
*/
public void sendPasteCommand() {
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_CONTROL);
}
/**
*
*/

@ -1,5 +1,12 @@
package xyz.wbsite.jmacro;
import cn.hutool.core.collection.BoundedPriorityQueue;
import cn.hutool.core.util.StrUtil;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import xyz.wbsite.jmacro.base.Legend;
import xyz.wbsite.jmacro.base.ViewRect;
import xyz.wbsite.jmacro.tool.Measure;
@ -7,10 +14,6 @@ import xyz.wbsite.jmacro.tool.PickLegend;
import xyz.wbsite.jmacro.tool.PickPoint;
import xyz.wbsite.jmacro.tool.PickRect;
import xyz.wbsite.jmacro.util.DialogUtil;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import java.awt.*;
import java.util.concurrent.Semaphore;
@ -32,6 +35,11 @@ public class JMainController {
private Button capture;
@FXML
private ImageView preview;
@FXML
private TextArea console;
private final int MAX_LENGTH = 100;
private final BoundedPriorityQueue<String> logs = new BoundedPriorityQueue<>(MAX_LENGTH);
private Semaphore semaphore = new Semaphore(1);
@ -127,7 +135,7 @@ public class JMainController {
/**
*
*
* @param image
* @param image
*/
public void preview(Image image) {
try {
@ -143,4 +151,20 @@ public class JMainController {
throw new RuntimeException(e);
}
}
/**
*
*
* @param log
* @param args
*/
public synchronized void println(String log, Object... args) {
String format = StrUtil.format(log, args) + "\n";
if (logs.size() >= MAX_LENGTH) {
String poll = logs.poll();
console.deleteText(0, poll.length());
}
logs.add(format);
console.appendText(format);
}
}

@ -0,0 +1,151 @@
package xyz.wbsite.jmacro.db;
import java.io.File;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Types;
/**
* xyz.wbsite.wsqlite.Client
*
* @author wangbing
*/
public class Client {
Connection connection;
ResultSet resultSet;
String dbFilePath;
/**
*
*
* @param dbFile
* @throws ClassNotFoundException
* @throws SQLException
*/
public Client(File dbFile) throws ClassNotFoundException, SQLException {
this.dbFilePath = dbFile.getAbsolutePath();
if (!dbFile.exists()) {
connection = getConnection();
}
}
/**
* sql
*
* @param sql
* @throws SQLException
* @throws ClassNotFoundException
*/
public void execute(String sql) throws SQLException, ClassNotFoundException {
try {
executeUpdate(sql);
} finally {
destroyed();
}
}
/**
* sql
*
* @param sql
* @throws SQLException
* @throws ClassNotFoundException
*/
public ResultSet executeQuery(String sql, Object... args) throws SQLException, ClassNotFoundException {
PreparedStatement preparedStatement = getConnection().prepareStatement(sql);
setArg(preparedStatement, args);
return preparedStatement.executeQuery();
}
/**
* sql
*
* @param sql
* @throws SQLException
* @throws ClassNotFoundException
*/
public int executeUpdate(String sql, Object... args) throws SQLException, ClassNotFoundException {
try {
PreparedStatement preparedStatement = getConnection().prepareStatement(sql);
setArg(preparedStatement, args);
return preparedStatement.executeUpdate();
} finally {
destroyed();
}
}
private void setArg(PreparedStatement ps, Object... args) throws SQLException {
for (int i = 0; i < args.length; i++) {
Object arg = args[i];
if (arg == null) {
ps.setNull(i + 1, Types.NULL);
} else if (arg instanceof String) {
ps.setString(i + 1, (String) arg);
} else if (arg instanceof Date) {
ps.setDate(i + 1, (Date) arg);
} else if (arg instanceof Time) {
ps.setTime(i + 1, (Time) arg);
} else if (arg instanceof java.util.Date) {
ps.setLong(i + 1, ((java.util.Date) arg).getTime());
} else if (arg instanceof Boolean) {
ps.setBoolean(i + 1, (Boolean) arg);
} else if (arg instanceof Byte) {
ps.setByte(i + 1, (Byte) arg);
} else if (arg instanceof Short) {
ps.setShort(i + 1, (Short) arg);
} else if (arg instanceof Integer) {
ps.setInt(i + 1, (int) arg);
} else if (arg instanceof Long) {
ps.setLong(i + 1, (long) arg);
} else if (arg instanceof Float) {
ps.setFloat(i + 1, (float) arg);
} else if (arg instanceof Double) {
ps.setDouble(i + 1, (double) arg);
} else if (arg instanceof byte[]) {
ps.setBytes(i + 1, (byte[]) arg);
}
}
}
/**
*
*
* @return
* @throws ClassNotFoundException
* @throws SQLException
*/
Connection getConnection() throws ClassNotFoundException, SQLException {
if (null == connection) {
Class.forName("org.sqlite.JDBC");
connection = DriverManager.getConnection("jdbc:sqlite:" + dbFilePath);
}
return connection;
}
/**
*
*/
public void destroyed() {
try {
if (null != resultSet) {
resultSet.close();
resultSet = null;
}
if (null != connection) {
connection.close();
connection = null;
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}

@ -0,0 +1,323 @@
package xyz.wbsite.jmacro.db;
import xyz.wbsite.jmacro.db.anonation.TableField;
import java.io.File;
import java.lang.reflect.Field;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* xyz.wbsite.wsqlite.Client
*
* @author wangbing
*/
public class ObjectClient extends Client {
private Map<String, Class> classMap = new HashMap<>();
/**
*
*
* @param dbFile
* @param classList
* @throws ClassNotFoundException
* @throws SQLException
*/
public ObjectClient(File dbFile, List<Class> classList) throws ClassNotFoundException, SQLException {
super(dbFile);
for (Class aClass : classList) {
classMap.put(aClass.getName(), aClass);
}
for (String key : classMap.keySet()) {
Class object = classMap.get(key);
StringBuffer sql = new StringBuffer();
String name = object.getSimpleName();
sql.append("CREATE TABLE IF NOT EXISTS ");
sql.append(name);
sql.append(" (");
Field[] fields = object.getDeclaredFields();
for (Field f : fields) {
if (f.isAnnotationPresent(TableField.class)) {
TableField bind = f.getAnnotation(TableField.class);
int length = bind.value();
if (f.getType() == String.class) {
sql.append(f.getName().toUpperCase());
sql.append(" VARCHAR(" + length + "),");
} else if (f.getType() == Boolean.class || f.getType() == boolean.class) {
sql.append(f.getName().toUpperCase());
sql.append(" BOOLEAN,");
} else if (f.getType() == Byte.class || f.getType() == byte.class ||
f.getType() == Short.class || f.getType() == short.class ||
f.getType() == Character.class || f.getType() == char.class ||
f.getType() == Integer.class || f.getType() == int.class ||
f.getType() == Long.class || f.getType() == long.class) {
sql.append(f.getName().toUpperCase());
sql.append(" INTEGER,");
} else if (f.getType() == Float.class || f.getType() == float.class ||
f.getType() == Double.class || f.getType() == double.class) {
sql.append(f.getName().toUpperCase());
sql.append(" REAL,");
} else if (f.getType() == Byte[].class || f.getType() == byte[].class) {
sql.append(f.getName().toUpperCase());
sql.append(" BLOB,");
} else if (f.getType() == Date.class) {
sql.append(f.getName().toUpperCase());
sql.append(" TIMESTAMP,");
}
}
}
sql.replace(sql.length() - 1, sql.length(), "");
sql.append(")");
System.out.println("SQL ==> " + sql.toString());
execute(sql.toString());
}
}
public <T> int insert(Class<T> poClass, T po) throws SQLException, ClassNotFoundException {
try {
Class aClass = classMap.get(poClass.getName());
if (aClass == null) {
System.err.println(poClass.getName() + " not found.");
} else {
StringBuffer sql = new StringBuffer();
sql.append("INSERT INTO ");
sql.append(aClass.getSimpleName());
sql.append("(");
//获取字段列表
List<Field> fs = getFields(poClass);
StringBuffer fieldsSql = new StringBuffer();
StringBuffer valueSql = new StringBuffer();
Object[] values = new Object[fs.size()];
for (int i = 0; i < fs.size(); i++) {
Field f = fs.get(i);
f.setAccessible(true);
fieldsSql.append(f.getName().toUpperCase());
valueSql.append("?");
values[i] = f.get(po);
if (i != fs.size() - 1) {
fieldsSql.append(",");
valueSql.append(",");
}
}
sql.append(fieldsSql);
sql.append(") VALUES (");
sql.append(valueSql);
sql.append(")");
System.out.println("SQL ==> " + sql.toString());
return executeUpdate(sql.toString(), values);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} finally {
destroyed();
}
return 0;
}
public <T> int delete(Class<T> poClass, Where where) throws SQLException, ClassNotFoundException {
try {
Class aClass = classMap.get(poClass.getName());
if (aClass == null) {
System.err.println(poClass.getName() + " not found.");
} else {
StringBuffer sql = new StringBuffer();
sql.append("DELETE FROM ");
sql.append(aClass.getSimpleName());
sql.append(where.getSql());
System.out.println("SQL ==> " + sql.toString());
return executeUpdate(sql.toString(), where.getArgs());
}
} finally {
destroyed();
}
return 0;
}
public <T> int update(Class<T> poClass, T po, Where where) throws SQLException, ClassNotFoundException {
try {
Class aClass = classMap.get(poClass.getName());
if (aClass == null) {
System.err.println(poClass.getName() + " not found.");
} else {
//获取字段列表
List<Field> fs = getFields(poClass);
StringBuffer sql = new StringBuffer();
Object[] values = new Object[fs.size()];
sql.append("UPDATE ");
sql.append(aClass.getSimpleName());
sql.append(" SET ");
for (int i = 0; i < fs.size(); i++) {
Field f = fs.get(i);
f.setAccessible(true);
sql.append(f.getName());
sql.append(" = ?");
values[i] = f.get(po);
if (i != fs.size() - 1) {
sql.append(",");
}
}
// 条件
sql.append(where.getSql());
System.out.println("SQL ==> " + sql.toString());
return executeUpdate(sql.toString(), concat(values, where.getArgs()));
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} finally {
destroyed();
}
return 0;
}
public <T> List<T> select(Class<T> poClass, Where where, int pageNumber, int pageSize) throws SQLException, ClassNotFoundException {
ArrayList<T> list = new ArrayList<>();
try {
Class aClass = classMap.get(poClass.getName());
if (aClass == null) {
System.err.println(poClass.getName() + " not found.");
} else {
StringBuffer sql = new StringBuffer();
sql.append("SELECT ");
//获取字段列表
List<Field> fs = getFields(poClass);
for (int i = 0; i < fs.size(); i++) {
Field f = fs.get(i);
sql.append(f.getName().toUpperCase());
if (i != fs.size() - 1) {
sql.append(",");
}
}
sql.append(" FROM ");
sql.append(aClass.getSimpleName());
// 条件
sql.append(where.getSql());
//分页参数
if (pageSize > 0) {
sql.append(" LIMIT " + (pageNumber - 1) + "," + pageSize);
}
System.out.println("SQL ==> " + sql.toString());
list.addAll(executeQuery(poClass, sql.toString(), where.getArgs()));
}
} finally {
destroyed();
}
return list;
}
/**
* select
*
* @param sql sql select
* @param poClass
* @return
* @throws SQLException
* @throws ClassNotFoundException
*/
public <T> List<T> executeQuery(Class<T> poClass, String sql, Object... args) throws SQLException, ClassNotFoundException {
List<T> rsList = new ArrayList<T>();
try {
resultSet = executeQuery(sql, args);
//获取字段列表
List<Field> fs = getFields(poClass);
while (resultSet.next()) {
try {
T o = poClass.newInstance();
for (int i = 0; i < fs.size(); i++) {
Field f = fs.get(i);
f.setAccessible(true);
if (f.getType() == String.class) {
String v = resultSet.getString(f.getName());
f.set(o, v);
} else if (f.getType() == Boolean.class || f.getType() == boolean.class) {
boolean v = resultSet.getBoolean(f.getName());
f.set(o, v);
} else if (f.getType() == Byte.class || f.getType() == byte.class) {
byte v = resultSet.getByte(f.getName());
f.set(o, v);
} else if (f.getType() == Short.class || f.getType() == short.class) {
short v = resultSet.getShort(f.getName());
f.set(o, v);
} else if (f.getType() == Character.class || f.getType() == char.class) {
short v = resultSet.getShort(f.getName());
f.set(o, (char) v);
} else if (f.getType() == Integer.class || f.getType() == int.class) {
int v = resultSet.getInt(f.getName());
f.set(o, v);
} else if (f.getType() == Long.class || f.getType() == long.class) {
long v = resultSet.getLong(f.getName());
f.set(o, v);
} else if (f.getType() == Float.class || f.getType() == float.class) {
float v = resultSet.getFloat(f.getName());
f.set(o, v);
} else if (f.getType() == Double.class || f.getType() == double.class) {
double v = resultSet.getDouble(f.getName());
f.set(o, v);
} else if (f.getType() == Byte[].class || f.getType() == byte[].class) {
byte[] v = resultSet.getBytes(f.getName());
f.set(o, v);
} else if (f.getType() == Date.class) {
Date v = resultSet.getDate(f.getName());
f.set(o, v);
} else {
String v = resultSet.getString(f.getName());
f.set(o, v);
}
}
rsList.add(o);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
} finally {
destroyed();
}
return rsList;
}
private List<Field> getFields(Class aClass) {
List<Field> fs = new ArrayList<>();
for (Field f : aClass.getDeclaredFields()) {
if (f.isAnnotationPresent(TableField.class)) {
fs.add(f);
}
}
return fs;
}
private <T> T[] concat(T[] arr1, T[] arr2) {
List<T> temp = new ArrayList<>();
temp.addAll(Arrays.asList(arr1));
temp.addAll(Arrays.asList(arr2));
return (T[]) temp.toArray();
}
}

@ -0,0 +1,94 @@
package xyz.wbsite.jmacro.db;
import java.util.ArrayList;
import java.util.List;
public class Where {
private String sql;
private Object[] args;
private Where() {
}
public String getSql() {
return sql;
}
public void setSql(String sql) {
this.sql = sql;
}
public Object[] getArgs() {
return args;
}
public void setArgs(Object[] args) {
this.args = args;
}
public Where(String sql, Object[] args) {
this.sql = sql;
this.args = args;
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
private StringBuilder sb = new StringBuilder();
private List<Object> argsList = new ArrayList<>();
public Builder eq(String name, Object value) {
return eq(true, name, value);
}
public Builder like(String name, Object value) {
return like(true, name, value);
}
public Builder isNull(String name, Object value) {
return isNull(true, name, value);
}
public Builder isNotNull(String name, Object value) {
return isNotNull(true, name, value);
}
public Builder eq(boolean condition, String name, Object value) {
if (condition) {
sb.append(sb.length() > 0 ? " and " : " where ").append(name).append(" = ? ");
argsList.add(value);
}
return this;
}
public Builder like(boolean condition, String name, Object value) {
if (condition) {
sb.append(sb.length() > 0 ? " and " : " where ").append(name).append("like ?");
argsList.add(value);
}
return this;
}
public Builder isNull(boolean condition, String name, Object value) {
if (condition) {
sb.append(sb.length() > 0 ? " and " : " where ").append(name).append("is null");
argsList.add(value);
}
return this;
}
public Builder isNotNull(boolean condition, String name, Object value) {
if (condition) {
sb.append(sb.length() > 0 ? " and " : " where ").append(name).append("is not null");
argsList.add(value);
}
return this;
}
public Where build() {
return new Where(sb.toString(), argsList.toArray());
}
}
}

@ -0,0 +1,13 @@
package xyz.wbsite.jmacro.db.anonation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TableField {
int value() default 20;
}

@ -0,0 +1,110 @@
package xyz.wbsite.jmacro.db.entity;
import xyz.wbsite.jmacro.db.anonation.TableField;
import java.util.Date;
public class Example {
@TableField(40)
private String s;
@TableField
private boolean b;
@TableField
private byte[] bs;
@TableField
private byte b1;
@TableField
private short s1;
@TableField
private int age;
@TableField
private long id;
@TableField
private float f1;
@TableField
private double d1;
@TableField
private Date date;
public String getS() {
return s;
}
public void setS(String s) {
this.s = s;
}
public boolean isB() {
return b;
}
public void setB(boolean b) {
this.b = b;
}
public byte[] getBs() {
return bs;
}
public void setBs(byte[] bs) {
this.bs = bs;
}
public byte getB1() {
return b1;
}
public void setB1(byte b1) {
this.b1 = b1;
}
public short getS1() {
return s1;
}
public void setS1(short s1) {
this.s1 = s1;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public float getF1() {
return f1;
}
public void setF1(float f1) {
this.f1 = f1;
}
public double getD1() {
return d1;
}
public void setD1(double d1) {
this.d1 = d1;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
}

@ -5,6 +5,7 @@ import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.caller.CallerUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.level.Level;
import xyz.wbsite.jmacro.JMainApplication;
import xyz.wbsite.jmacro.ex.MacroErrorException;
/**
@ -16,7 +17,6 @@ import xyz.wbsite.jmacro.ex.MacroErrorException;
*/
public class Logger {
public static void info(String format, Object... arg) {
DateTime date = DateUtil.date();
String level = Level.INFO.toString();
@ -26,19 +26,23 @@ public class Logger {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
// 通常堆栈追踪数组的第三个元素是logMessage方法的调用者
int lineNumber = stackTrace[2].getLineNumber();
System.out.println(StrUtil.format("[{}] [{}] {} [{}:{}]", date, level, log, name, lineNumber));
JMainApplication.mainController.println("[{}] [{}] {} [{}:{}]", date, level, log, name, lineNumber);
}
public static void error(String format, Object... arg) {
// 获取当前时间
DateTime date = DateUtil.date();
// 获取日志级别
String level = Level.ERROR.toString();
// 格式化日志信息
String log = StrUtil.format(format, arg);
// 获取调用者类名
String name = CallerUtil.getCallerCaller().getSimpleName();
// 获取当前线程的堆栈追踪
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
// 通常堆栈追踪数组的第三个元素是logMessage方法的调用者
int lineNumber = stackTrace[2].getLineNumber();
System.out.println(StrUtil.format("[{}] [{}] {} [{}:{}]", date, level, log, name, lineNumber));
throw new MacroErrorException(StrUtil.format(format, arg));
// 打印日志信息
JMainApplication.mainController.println("[{}] [{}] {} [{}:{}]", date, level, log, name, lineNumber);
}
}

@ -0,0 +1,12 @@
/* styles.css */
.text-area,
.text-area:focused,
.text-area:unfocused,
.text-area:disabled {
-fx-control-inner-background: transparent;
-fx-background-color: transparent;
}
.text-area .content {
-fx-background-color: transparent;
}

@ -5,7 +5,7 @@
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<AnchorPane prefHeight="300.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="xyz.wbsite.jmacro.JMainController">
<AnchorPane prefHeight="300.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="xyz.wbsite.jmacro.JMainController" stylesheets="@main.css">
<children>
<Separator layoutY="-1.0" opacity="0.5" prefWidth="200.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
<VBox maxWidth="204.0" minWidth="204.0" prefWidth="204.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="0.0">
@ -81,6 +81,13 @@
</padding>
</Label>
<Separator layoutX="-3.0" layoutY="39.0" opacity="0.5" prefWidth="200.0" AnchorPane.leftAnchor="1.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="41.0" />
<TextArea fx:id="console" editable="false" layoutX="1.0" layoutY="41.0" prefHeight="270.0"
style="-fx-background-color: transparent; -fx-focus-color: no; -fx-control-inner-background: transparent;-fx-text-fill: #444444;"
wrapText="true"
AnchorPane.leftAnchor="1.0"
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="45.0">
</TextArea>
</children>
</AnchorPane>
</children>

Loading…
Cancel
Save

Powered by TurnKey Linux.