完善配置和监听全局快捷键功能

This commit is contained in:
yang 2022-10-05 10:22:23 +08:00
parent a3d288fab2
commit 222dacfb68
16 changed files with 395 additions and 104 deletions

View File

@ -13,11 +13,11 @@ repositories {
}
ext {
junitVersion = '5.8.1'
junitVersion = '5.9.0'
}
sourceCompatibility = "14"
targetCompatibility = "14"
sourceCompatibility = "11"
targetCompatibility = "11"
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
@ -34,8 +34,10 @@ javafx {
}
dependencies {
implementation("com.jfoenix:jfoenix:9.0.0")
implementation('com.jfoenix:jfoenix:9.0.10')
implementation("com.google.code.gson:gson:2.9.1")
implementation('net.java.dev.jna:jna:5.12.1')
implementation('net.java.dev.jna:jna-platform:5.12.1')
testImplementation("org.junit.jupiter:junit-jupiter-api:${junitVersion}")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${junitVersion}")
}
@ -45,7 +47,7 @@ test {
}
jlink {
imageZip = project.file("${buildDir}/distributions/app-${javafx.platform.classifier}.zip")
imageZip = project.file("${buildDir}/distributions/app-${javafx.platform.classifier}.zip") as RegularFile
options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
launcher {
name = 'app'

View File

@ -4,12 +4,14 @@ module org.rococy.roomit {
requires java.desktop;
requires com.jfoenix;
requires com.google.gson;
requires com.sun.jna;
requires com.sun.jna.platform;
opens org.rococy.roomit.domain to com.google.gson;
opens org.rococy.roomit to javafx.fxml;
opens org.rococy.roomit.controller to javafx.fxml;
exports org.rococy.roomit.control to javafx.fxml;
exports org.rococy.roomit;
exports org.rococy.roomit.controller;
exports org.rococy.roomit.function;
opens org.rococy.roomit.controller to javafx.fxml;
exports org.rococy.roomit.control to javafx.fxml;
}

View File

@ -7,7 +7,12 @@ import javafx.scene.Scene;
import javafx.scene.paint.Paint;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import org.rococy.roomit.config.ConfigurationManager;
import org.rococy.roomit.constant.KeyBoardConsts;
import org.rococy.roomit.domain.KeyBoardConfiguration;
import org.rococy.roomit.listener.TrayIconMouseListener;
import org.rococy.roomit.listener.WindowGlobalKeyBoardListener;
import org.rococy.roomit.util.KeyBoardUtils;
import org.rococy.roomit.util.ScreenUtils;
import javax.imageio.ImageIO;
@ -23,8 +28,19 @@ public class MainWindow extends Application {
private static Stage stage;
static {
{
try {
// 设置全局快捷键
KeyBoardConfiguration keyBoardConfiguration = ConfigurationManager.getKeyboardConfiguration();
WindowGlobalKeyBoardListener.addEventListener(event -> {
String keyBoardText = KeyBoardUtils.parse(event);
String type = keyBoardConfiguration.getType(keyBoardText);
// 关闭或启动窗口
if (type.equals(KeyBoardConsts.OPEN_OR_CLOSE)) {
Platform.runLater(MainWindow::toggleDisplay);
}
});
// 初始化托盘图标
initTrayIcon();
// 设置当程序所有窗口都关闭时JavaFx的UI线程继续运行
@ -35,7 +51,13 @@ public class MainWindow extends Application {
}
@Override
public void start(Stage stage) throws IOException {
public void start(Stage stage) {
launch(stage);
}
public static void launch(Stage stage) {
try {
MainWindow.stage = stage;
// 加载FXML文件
FXMLLoader fxmlLoader = new FXMLLoader(MainWindow.class.getResource("fxml/mainWindow.fxml"));
@ -55,22 +77,23 @@ public class MainWindow extends Application {
stage.initStyle(StageStyle.TRANSPARENT);
// 将窗口显示出来
stage.show();
} catch (
IOException e) {
e.printStackTrace();
}
public void show() {
}
public static void toggleDisplay() {
if (stage.isShowing()) {
stage.close();
System.gc();
return;
}
try {
start(new Stage());
} catch (IOException e) {
e.printStackTrace();
} else {
launch(new Stage());
}
}
private static void initTrayIcon() throws IOException, AWTException {
private void initTrayIcon() throws IOException, AWTException {
// 获取系统托盘
SystemTray systemTray = SystemTray.getSystemTray();
// 加载托盘图片 16*16的png图片

View File

@ -4,10 +4,7 @@ import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.rococy.roomit.domain.BrushConfiguration;
import org.rococy.roomit.domain.EllipseConfiguration;
import org.rococy.roomit.domain.RectangleConfiguration;
import org.rococy.roomit.domain.ShapeConfiguration;
import org.rococy.roomit.domain.*;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@ -20,10 +17,11 @@ import java.util.Map;
* @author Rococy
* @date 2022/9/29
*/
@SuppressWarnings("unchecked")
public class ConfigurationManager {
private static ShapeConfiguration shapeConfiguration;
private static Map<String, String> keyboardMap;
private static KeyBoardConfiguration keyBoardConfiguration;
private static final String CONFIGURATION_FILE_URL = System.getProperty("user.dir") + "\\src\\main\\resources\\org\\rococy\\roomit\\config.json";
@ -34,7 +32,7 @@ public class ConfigurationManager {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
Map<String, Object> configMap = new HashMap<>(2);
configMap.put("shape", shapeConfiguration);
configMap.put("keyboard", keyboardMap);
configMap.put("keyboard", keyBoardConfiguration.getKeyBoardMap());
try {
Files.writeString(Path.of(CONFIGURATION_FILE_URL), gson.toJson(configMap));
@ -56,8 +54,8 @@ public class ConfigurationManager {
return shapeConfiguration.getEllipse();
}
public static Map<String, String> getKeyboardConfiguration() {
return keyboardMap;
public static KeyBoardConfiguration getKeyboardConfiguration() {
return keyBoardConfiguration;
}
private static void initConfiguration(String jsonStr) {
@ -76,7 +74,7 @@ public class ConfigurationManager {
shapeConfiguration.setEllipse(ellipseConfiguration);
// 快捷键配置
keyboardMap = gson.fromJson(rootObject.get("keyboard"), Map.class);
keyBoardConfiguration = new KeyBoardConfiguration(gson.fromJson(rootObject.get("keyboard"), Map.class));
}
private static String readConfigFileContent() {

View File

@ -0,0 +1,20 @@
package org.rococy.roomit.constant;
/**
* @author Rococy
* @date 2022/10/4
*/
public class KeyBoardConsts {
public static final String BRUSH = "brush";
public static final String RECTANGLE = "rectangle";
public static final String ELLIPSE = "ellipse";
public static final String TOOLS = "tools";
public static final String COLOR_PICKER = "colorPicker";
public static final String EXPEND_MOUSE = "expendMouse";
public static final String CLEAR = "clear";
public static final String SCREENSHOT_AND_COPY = "screenshotAndCopy";
public static final String OPEN_OR_CLOSE = "openOrClose";
public static final String BACK = "back";
}

View File

@ -4,7 +4,9 @@ import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.input.MouseEvent;
import javafx.scene.shape.Ellipse;
import org.rococy.roomit.config.ConfigurationManager;
import org.rococy.roomit.control.base.Resizer;
import org.rococy.roomit.domain.EllipseConfiguration;
import org.rococy.roomit.util.ReactStyleMap;
/**
@ -167,14 +169,13 @@ public class ResizableEllipseWrapper extends Resizer {
/**
* 配置项
*/
private final EllipseConfiguration ellipseConfiguration = ConfigurationManager.getEllipseConfiguration();
private static final String FILL_COLOR = "#00000000";
private static final String BORDER_COLOR = "linear-gradient(to bottom, #f64f59, #c471ed, #12c2e9);";
private static final int BORDER_WIDTH = 3;
public InnerEllipse() {
styleMap.addStyle("-fx-fill", FILL_COLOR);
styleMap.addStyle("-fx-stroke", BORDER_COLOR);
styleMap.addReactStyle("-fx-stroke-width", BORDER_WIDTH);
styleMap.addStyle("-fx-stroke", ellipseConfiguration.getBorderColor());
styleMap.addReactStyle("-fx-stroke-width", ellipseConfiguration.getBorderWidth());
}
/**
@ -183,6 +184,7 @@ public class ResizableEllipseWrapper extends Resizer {
* @param hexColor 16进制颜色值
*/
public void setBorderColor(String hexColor) {
ellipseConfiguration.setBorderColor(hexColor);
styleMap.addReactStyle("-fx-stroke", hexColor);
}
}

View File

@ -1,7 +1,9 @@
package org.rococy.roomit.control;
import javafx.scene.Parent;
import org.rococy.roomit.config.ConfigurationManager;
import org.rococy.roomit.control.base.Resizer;
import org.rococy.roomit.domain.RectangleConfiguration;
import org.rococy.roomit.util.ReactStyleMap;
/**
@ -15,8 +17,7 @@ public class ResizableRectangle extends Resizer {
/**
* 配置项
*/
private static final String BORDER_COLOR = "linear-gradient(to bottom, #f64f59, #c471ed, #12c2e9)";
private static final double BORDER_WIDTH = 3;
private final RectangleConfiguration rectangleConfiguration = ConfigurationManager.getRectangleConfiguration();
/**
* 样式集合
@ -37,8 +38,8 @@ public class ResizableRectangle extends Resizer {
// 填充颜色边框颜色边框宽度圆角
styleMap.addStyle("-fx-fill", "#00000000");
styleMap.addStyle("-fx-border-color", BORDER_COLOR);
styleMap.addStyle("-fx-border-width", BORDER_WIDTH);
styleMap.addStyle("-fx-border-color", rectangleConfiguration.getBorderColor());
styleMap.addStyle("-fx-border-width", rectangleConfiguration.getBorderWidth());
styleMap.addStyle("-fx-border-style", "solid");
styleMap.addReactStyle("-fx-border-radius", 5);
this.setMinSize(MIN_WIDTH, MIN_HEIGHT);
@ -46,7 +47,7 @@ public class ResizableRectangle extends Resizer {
@Override
protected double getBorderWidth() {
return BORDER_WIDTH;
return rectangleConfiguration.getBorderWidth();
}
@Override
@ -60,6 +61,7 @@ public class ResizableRectangle extends Resizer {
* @param hexColor 16进制颜色值
*/
public void setBorderColor(String hexColor) {
rectangleConfiguration.setBorderColor(hexColor);
styleMap.addReactStyle("-fx-border-color", hexColor);
}

View File

@ -225,43 +225,56 @@ public abstract class Resizer extends Pane {
switch (rectangleCtrl) {
case TOP_LEFT -> {
case TOP_LEFT: {
this.setLayoutX(screenX);
this.setLayoutY(screenY);
this.setPrefSize(width - x, height - y);
break;
}
case TOP_MIDDLE -> {
case TOP_MIDDLE: {
this.setLayoutY(screenY);
this.setPrefHeight(height - y);
break;
}
case TOP_RIGHT -> {
case TOP_RIGHT: {
this.setLayoutY(screenY);
this.setPrefSize(x, height - y);
break;
}
case CENTER_LEFT -> {
case CENTER_LEFT: {
this.setLayoutX(screenX);
this.setPrefWidth(width - x);
break;
}
case CENTER_RIGHT -> this.setPrefWidth(x);
case CENTER_RIGHT: {
this.setPrefWidth(x);
break;
}
case BOTTOM_LEFT -> {
case BOTTOM_LEFT: {
this.setLayoutX(screenX);
this.setPrefSize(width - x, y);
break;
}
case BOTTOM_MIDDLE -> this.setPrefHeight(y);
case BOTTOM_MIDDLE: {
this.setPrefHeight(y);
break;
}
case BOTTOM_RIGHT -> {
case BOTTOM_RIGHT: {
this.setPrefSize(x, y);
break;
}
case MOVE -> {
case MOVE: {
this.setLayoutX(screenX - moveX);
this.setLayoutY(screenY - moveY);
break;
}
}
});
@ -284,10 +297,11 @@ public abstract class Resizer extends Pane {
private void bindKeyPressedEvent() {
this.addEventHandler(KeyEvent.KEY_PRESSED, e -> {
switch (e.getCode()) {
case DELETE -> {
case DELETE: {
// 删除自身
Pane parent = (Pane) this.getParent();
parent.getChildren().remove(this);
break;
}
}
});

View File

@ -10,10 +10,12 @@ import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Background;
import javafx.scene.shape.Shape;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import org.rococy.roomit.config.ConfigurationManager;
import org.rococy.roomit.constant.KeyBoardConsts;
import org.rococy.roomit.control.Container;
import org.rococy.roomit.control.*;
import org.rococy.roomit.cursor.RoomItCursor;
import org.rococy.roomit.domain.KeyBoardConfiguration;
import org.rococy.roomit.event.RoomItCursorEvent;
import org.rococy.roomit.function.Handler;
import org.rococy.roomit.symbol.BrushSymbol;
@ -22,6 +24,7 @@ import org.rococy.roomit.symbol.RectangleSymbol;
import org.rococy.roomit.symbol.base.MouseSymbol;
import org.rococy.roomit.util.ColorUtils;
import org.rococy.roomit.util.ImageTransfer;
import org.rococy.roomit.util.KeyBoardUtils;
import org.rococy.roomit.util.ScreenUtils;
import java.awt.*;
@ -84,42 +87,63 @@ public class MainWindowController implements Initializable {
*/
private final ColorPicker colorPicker = new ColorPicker();
private final KeyBoardConfiguration keyBoardConfiguration = ConfigurationManager.getKeyboardConfiguration();
@FXML
public void windowKeyPressed(KeyEvent event) {
if (event.isControlDown()) {
switch (event.getCode()) {
String keyBoardText = KeyBoardUtils.parse(event);
switch (keyBoardConfiguration.getType(keyBoardText)) {
// 切换为画笔
case G -> changeState(BRUSH_SYMBOL);
case KeyBoardConsts.BRUSH: {
changeState(BRUSH_SYMBOL);
break;
}
// 切换为绘制矩形状态
case R -> {
case KeyBoardConsts.RECTANGLE: {
changeState(RECTANGLE_SYMBOL);
shapePane.switchToDrawRectangle();
break;
}
// 切换为绘制椭圆状态
case Q -> {
case KeyBoardConsts.ELLIPSE: {
changeState(ELLIPSE_SYMBOL);
shapePane.switchToDrawEllipse();
break;
}
// 弹出颜色框 picker
case P -> ejectColorPicker();
case KeyBoardConsts.COLOR_PICKER: {
ejectColorPicker();
break;
}
// 鼠标放大操作 expand
case E -> cursor.expand(globalMouseX, globalMouseY);
case KeyBoardConsts.EXPEND_MOUSE: {
cursor.expand(globalMouseX, globalMouseY);
break;
}
// 清空操作 clear
case C -> this.clear();
case KeyBoardConsts.CLEAR: {
this.clear();
break;
}
// 回退操作
case Z -> canvasGroup.undo();
case KeyBoardConsts.BACK: {
canvasGroup.undo();
break;
}
// 将截图放入剪切板操作
case B -> this.captureToClipBoard();
case KeyBoardConsts.SCREENSHOT_AND_COPY: {
this.captureToClipBoard();
break;
}
}
}
@FXML

View File

@ -13,6 +13,7 @@ import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import org.rococy.roomit.config.ConfigurationManager;
import org.rococy.roomit.constant.GlobalConsts;
import org.rococy.roomit.constant.KeyBoardConsts;
import org.rococy.roomit.domain.BrushConfiguration;
import org.rococy.roomit.domain.EllipseConfiguration;
import org.rococy.roomit.domain.RectangleConfiguration;
@ -33,7 +34,7 @@ public class SettingWindowController {
private final BrushConfiguration brushConfiguration = ConfigurationManager.getBrushConfiguration();
private final RectangleConfiguration rectangleConfiguration = ConfigurationManager.getRectangleConfiguration();
private final EllipseConfiguration ellipseConfiguration = ConfigurationManager.getEllipseConfiguration();
private final Map<String, String> keyboardConfiguration = ConfigurationManager.getKeyboardConfiguration();
private final Map<String, String> keyboardConfiguration = ConfigurationManager.getKeyboardConfiguration().getKeyBoardMap();
private static final String SLIDE_BUTTON_SELECTED_CLASS = "selected";
@ -190,7 +191,6 @@ public class SettingWindowController {
.addListener((observable, oldValue, newValue) -> brushConfiguration.setTransparent(Boolean.parseBoolean((String) newValue.getUserData())));
// 线条颜色
brushStrokeColorPicker.setOnAction(e -> {
System.out.println(brushStrokeColorPicker.getValue());
brushConfiguration.setStrokeColor(ColorUtils.toHexStr(brushStrokeColorPicker.getValue()));
});
// 线条粗细
@ -235,14 +235,14 @@ public class SettingWindowController {
}
private void initKeyboardConfiguration() {
brushKeyboard.setText(keyboardConfiguration.get("brush"));
rectangleKeyboard.setText(keyboardConfiguration.get("rectangle"));
ellipseKeyboard.setText(keyboardConfiguration.get("ellipse"));
toolsKeyboard.setText(keyboardConfiguration.get("tools"));
colorPickerKeyboard.setText(keyboardConfiguration.get("colorPicker"));
expendMouseKeyboard.setText(keyboardConfiguration.get("expendMouse"));
clearKeyboard.setText(keyboardConfiguration.get("clear"));
screenshotAndCopyKeyboard.setText(keyboardConfiguration.get("screenshotAndCopy"));
openOrCloseKeyboard.setText(keyboardConfiguration.get("openOrClose"));
brushKeyboard.setText(keyboardConfiguration.get(KeyBoardConsts.BRUSH));
rectangleKeyboard.setText(keyboardConfiguration.get(KeyBoardConsts.RECTANGLE));
ellipseKeyboard.setText(keyboardConfiguration.get(KeyBoardConsts.ELLIPSE));
toolsKeyboard.setText(keyboardConfiguration.get(KeyBoardConsts.TOOLS));
colorPickerKeyboard.setText(keyboardConfiguration.get(KeyBoardConsts.COLOR_PICKER));
expendMouseKeyboard.setText(keyboardConfiguration.get(KeyBoardConsts.EXPEND_MOUSE));
clearKeyboard.setText(keyboardConfiguration.get(KeyBoardConsts.CLEAR));
screenshotAndCopyKeyboard.setText(keyboardConfiguration.get(KeyBoardConsts.SCREENSHOT_AND_COPY));
openOrCloseKeyboard.setText(keyboardConfiguration.get(KeyBoardConsts.OPEN_OR_CLOSE));
}
}

View File

@ -37,6 +37,8 @@ public class RoomItCursor extends SVGPath {
private double x, y;
public RoomItCursor() {
// 一开始先隐藏
super.relocate(-1000, -1000);
// 绘制路径
this.setContent("M285 611 c-23 -10 -53 -32 -67 -49 -44 -53 -51 -90 -46 -262 3 -130 7 -162 22 -185 15 -23 22 -26 49 -21 78 16 265 170 306 252 82 164 -95 342 -264 265z");
// 置顶

View File

@ -0,0 +1,29 @@
package org.rococy.roomit.domain;
import java.util.Map;
/**
* @author Rococy
* @date 2022/10/4
*/
public class KeyBoardConfiguration {
private final Map<String, String> keyBoardMap;
public KeyBoardConfiguration(Map<String, String> keyBoardMap) {
this.keyBoardMap = keyBoardMap;
}
public String getType(String keyBoard) {
for (Map.Entry<String, String> entry : keyBoardMap.entrySet()) {
if (entry.getValue().equals(keyBoard)) {
return entry.getKey();
}
}
return "";
}
public Map<String, String> getKeyBoardMap() {
return keyBoardMap;
}
}

View File

@ -25,16 +25,20 @@ public class TrayIconMouseListener implements MouseListener {
public void mousePressed(MouseEvent e) {
switch (e.getButton()) {
// 左键
case MOUSE_LEFT_BUTTON -> Platform.runLater(() -> new MainWindow().show());
case MOUSE_LEFT_BUTTON: {
Platform.runLater(MainWindow::toggleDisplay);
break;
}
// 右键
case MOUSE_RIGHT_BUTTON -> {
case MOUSE_RIGHT_BUTTON: {
Platform.runLater(() -> {
if (trayWindow == null) {
trayWindow = new TrayWindow();
}
trayWindow.show(e.getXOnScreen(), e.getYOnScreen());
});
break;
}
}

View File

@ -0,0 +1,131 @@
package org.rococy.roomit.listener;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinUser;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Consumer;
/**
* @author Rococy
* @date 2022/10/3
*/
public class WindowGlobalKeyBoardListener {
private static final List<Consumer<KeyEvent>> EVENT_LIST = new ArrayList<>(10);
private static WinUser.HHOOK hhk = null;
static {
startNativeKeyBoardListener();
}
public static void addEventListener(Consumer<KeyEvent> event) {
EVENT_LIST.add(event);
}
private static void startNativeKeyBoardListener() {
ExecutorService executor = Executors.newFixedThreadPool(1);
executor.execute(() -> {
final User32 lib = User32.INSTANCE;
WinDef.HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);
GlobalKeyEvent keyEvent = new GlobalKeyEvent();
WinUser.LowLevelKeyboardProc keyboardHook = (nCode, wParam, info) -> {
if (nCode >= 0) {
int code = info.vkCode;
switch (wParam.intValue()) {
// 键盘按下
case WinUser.WM_KEYDOWN: {
if (code == 160) {
keyEvent.isShiftDown = true;
} else if (code == 162) {
keyEvent.isCtrlDown = true;
} else if (code == 164) {
keyEvent.isAltDown = true;
} else if (code >= 48 && code <= 57 || code >= 65 && code <= 90) {
// 字母或数字
keyEvent.keyCode = KeyCode.getKeyCode(String.valueOf((char) code));
// 触发事件
EVENT_LIST.forEach(c -> c.accept(new KeyEvent(null, null, null, null, null, keyEvent.keyCode, keyEvent.isShiftDown, keyEvent.isCtrlDown, keyEvent.isAltDown, false)));
}
break;
}
// 键盘抬起
case WinUser.WM_KEYUP: {
if (code == 160) {
keyEvent.isShiftDown = false;
}
if (code == 162) {
keyEvent.isCtrlDown = false;
}
if (code == 164) {
keyEvent.isAltDown = false;
}
break;
}
}
}
return lib.CallNextHookEx(hhk, nCode, wParam, new WinDef.LPARAM(Pointer.nativeValue(info.getPointer())));
};
hhk = lib.SetWindowsHookEx(WinUser.WH_KEYBOARD_LL, keyboardHook, hMod, 0);
int result;
WinUser.MSG msg = new WinUser.MSG();
while ((result = lib.GetMessage(msg, null, 0, 0)) != 0) {
if (result == -1) {
// error in get message
break;
} else {
// got message
lib.TranslateMessage(msg);
lib.DispatchMessage(msg);
}
}
lib.UnhookWindowsHookEx(hhk);
});
}
public static class GlobalKeyEvent {
private boolean isShiftDown;
private boolean isCtrlDown;
private boolean isAltDown;
private KeyCode keyCode;
public boolean isShiftDown() {
return isShiftDown;
}
public boolean isCtrlDown() {
return isCtrlDown;
}
public boolean isAltDown() {
return isAltDown;
}
public KeyCode getKeyCode() {
return keyCode;
}
@Override
public String toString() {
return "GlobalKeyEvent{" +
"isShiftDown=" + isShiftDown +
", isCtrlDown=" + isCtrlDown +
", isAltDown=" + isAltDown +
", keyCode=" + keyCode +
'}';
}
}
}

View File

@ -0,0 +1,37 @@
package org.rococy.roomit.util;
import javafx.scene.input.KeyEvent;
import java.util.StringJoiner;
/**
* @author Rococy
* @date 2022/10/4
*/
public class KeyBoardUtils {
public static String parse(KeyEvent e) {
StringJoiner keyBoardJoiner = new StringJoiner("+");
String keyBoard = "";
if (e.isControlDown()) {
keyBoardJoiner.add("CTRL");
}
if (e.isShiftDown()) {
keyBoardJoiner.add("SHIFT");
}
if (e.isAltDown()) {
keyBoardJoiner.add("ALT");
}
// 如果上面的键一个没点
if (keyBoardJoiner.length() == 0) {
return keyBoard;
}
keyBoard = keyBoardJoiner.add(e.getCode().getChar()).toString();
return keyBoard;
}
}

View File

@ -23,6 +23,7 @@
"expendMouse": "CTRL+E",
"clear": "CTRL+C",
"screenshotAndCopy": "CTRL+B",
"openOrClose": "CTRL+O"
"openOrClose": "CTRL+O",
"back": "CTRL+Z"
}
}