增加gui到git

This commit is contained in:
2026-03-14 11:32:29 +08:00
parent 7fd0760c79
commit fa07450606
12 changed files with 3068 additions and 0 deletions

2
.gitignore vendored
View File

@@ -18,3 +18,5 @@
/app/src/androidTest/java/com/uiui/videoplayer/
/library/build/
/JZVideo/build/
/ui/video-encryptor/.idea/
/ui/video-encryptor/target/

View File

@@ -0,0 +1,2 @@
SET class_path=target/video-encryptor-1.0-SNAPSHOT.jar;
native-image --no-fallback -H:ConfigurationFileDirectories=META-INF/native-image --allow-incomplete-classpath -classpath %class_path% com.penngo.gralvm.MainSwing

View File

@@ -0,0 +1,7 @@
@REM 使用idea 的mvn clean package
java -agentlib:native-image-agent=config-output-dir=./META-INF/native-image -jar video-encryptor-1.0.jar
native-image -jar target\video-encryptor-1.0.jar --no-fallback -H:ConfigurationFileDirectories=.\src\main\resources\META-INF\native-image
"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\editbin.exe" /SUBSYSTEM:WINDOWS video-encryptor-1.0.exe

View File

@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.hainaos</groupId>
<artifactId>video-encryptor</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.hnos.video.VideoEncryptorGUI</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<version>0.10.2</version> <!-- 建议使用最新版本 -->
<extensions>true</extensions>
<executions>
<execution>
<id>build-native</id>
<goals>
<goal>compile-no-fork</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
<configuration>
<imageName>VideoEncryptor</imageName> <!-- 生成的EXE名称 -->
<mainClass>com.hnos.video.VideoEncryptorGUI</mainClass> <!-- 你的主类 -->
<buildArgs>
<arg>--no-fallback</arg>
</buildArgs>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,29 @@
package com.hnos.video;
import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
public class VideoEncryptor {
private static final String ALGORITHM = "AES/CTR/NoPadding";
public static void encryptFile(File inputFile, File outputFile, byte[] key, byte[] iv) throws Exception {
Cipher cipher = Cipher.getInstance(ALGORITHM);
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
try (FileInputStream fis = new FileInputStream(inputFile);
FileOutputStream fos = new FileOutputStream(outputFile);
CipherOutputStream cos = new CipherOutputStream(fos, cipher)) {
byte[] buffer = new byte[8192];
int read;
while ((read = fis.read(buffer)) != -1) {
cos.write(buffer, 0, read);
}
}
}
}

View File

@@ -0,0 +1,365 @@
package com.hnos.video;
import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
/**
* 视频加密工具GUI
* 支持单文件加密和目录下所有视频文件批量加密
* 加密后文件扩展名改为.hnv
*/
public class VideoEncryptorGUI extends JFrame {
// 加密算法常量保持和VideoEncryptor一致
private static final String ALGORITHM = "AES/CTR/NoPadding";
// 视频文件扩展名列表(可根据需要扩展)
private static final List<String> VIDEO_EXTENSIONS = Arrays.asList("mp4", "avi", "mov", "mkv", "flv", "wmv",
"rmvb");
// 测试用AES密钥16字节AES-128实际使用请替换为安全生成的密钥
private static final byte[] TEST_KEY = "1234567890123456".getBytes();
// 测试用IV向量16字节CTR模式要求IV长度等于块大小实际使用请随机生成
private static final byte[] TEST_IV = "1234567890123456".getBytes();
public VideoEncryptorGUI() {
// 初始化窗口
initFrame();
// 初始化界面组件
initComponents();
}
/**
* 初始化窗口基本属性
*/
private void initFrame() {
setTitle("视频加密工具");
setSize(350, 400);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null); // 居中显示
setResizable(false); // 固定窗口大小
}
// 输入框组件
private JTextField keyField;
private JTextField ivField;
// 状态文本框
private JTextField statusField;
// 转换按钮
private JButton convertBtn;
// 选中的文件或目录
private File selectedFile;
private File selectedDir;
/**
* 初始化界面组件(按钮、布局等)
*/
private void initComponents() {
// 创建面板和设置布局
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.setBorder(BorderFactory.createEmptyBorder(20, 40, 20, 40));
// 创建选择按钮
JButton selectFileBtn = new JButton("选择单个视频文件");
JButton selectDirBtn = new JButton("选择目录(批量加密)");
// 设置按钮大小
Dimension btnSize = new Dimension(200, 30);
selectFileBtn.setPreferredSize(btnSize);
selectDirBtn.setPreferredSize(btnSize);
// 添加按钮事件监听
selectFileBtn.addActionListener(e -> selectSingleFile());
selectDirBtn.addActionListener(e -> selectDirectory());
// 创建输入框标签
JLabel keyLabel = new JLabel("密钥 (16字节):");
JLabel ivLabel = new JLabel("IV向量 (16字节):");
// 创建输入框
keyField = new JTextField("hainaos_key_123_", 20);
ivField = new JTextField("hainaos1hainaos1", 20);
// 创建转换按钮
convertBtn = new JButton("开始转换");
convertBtn.setPreferredSize(btnSize);
convertBtn.addActionListener(e -> startConversion());
// 创建状态文本框
statusField = new JTextField("准备就绪");
statusField.setPreferredSize(btnSize);
statusField.setEditable(false);
statusField.setHorizontalAlignment(JTextField.CENTER);
// 添加组件到面板(垂直排列)
panel.add(selectFileBtn);
panel.add(Box.createVerticalStrut(10)); // 垂直间距
panel.add(selectDirBtn);
panel.add(Box.createVerticalStrut(20)); // 垂直间距
panel.add(keyLabel);
panel.add(keyField);
panel.add(Box.createVerticalStrut(10)); // 垂直间距
panel.add(ivLabel);
panel.add(ivField);
panel.add(Box.createVerticalStrut(20)); // 垂直间距
panel.add(convertBtn);
panel.add(Box.createVerticalStrut(10)); // 垂直间距
panel.add(statusField);
// 添加面板到窗口
add(panel);
}
/**
* 选择单个视频文件
*/
private void selectSingleFile() {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
fileChooser.setDialogTitle("选择要加密的视频文件");
// 过滤视频文件
fileChooser.setFileFilter(new javax.swing.filechooser.FileFilter() {
@Override
public boolean accept(File f) {
if (f.isDirectory())
return true;
String ext = getFileExtension(f);
return VIDEO_EXTENSIONS.contains(ext.toLowerCase());
}
@Override
public String getDescription() {
return "视频文件 (" + String.join(", ", VIDEO_EXTENSIONS) + ")";
}
});
int result = fileChooser.showOpenDialog(this);
if (result == JFileChooser.APPROVE_OPTION) {
selectedFile = fileChooser.getSelectedFile();
selectedDir = null; // 清除目录选择
JOptionPane.showMessageDialog(this, "已选择文件:" + selectedFile.getName(), "选择成功", JOptionPane.INFORMATION_MESSAGE);
}
}
/**
* 选择目录
*/
private void selectDirectory() {
JFileChooser dirChooser = new JFileChooser();
dirChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
dirChooser.setDialogTitle("选择要批量加密的目录");
int result = dirChooser.showOpenDialog(this);
if (result == JFileChooser.APPROVE_OPTION) {
selectedDir = dirChooser.getSelectedFile();
selectedFile = null; // 清除文件选择
JOptionPane.showMessageDialog(this, "已选择目录:" + selectedDir.getName(), "选择成功", JOptionPane.INFORMATION_MESSAGE);
}
}
/**
* 开始转换过程
*/
private void startConversion() {
// 检查是否选择了文件或目录
if (selectedFile == null && selectedDir == null) {
JOptionPane.showMessageDialog(this, "请先选择要加密的文件或目录!", "错误", JOptionPane.ERROR_MESSAGE);
return;
}
// 获取用户输入的key和iv
String keyStr = keyField.getText();
String ivStr = ivField.getText();
// 验证key和iv的长度
if (keyStr.length() != 16) {
JOptionPane.showMessageDialog(this, "密钥长度必须为16字节", "错误", JOptionPane.ERROR_MESSAGE);
return;
}
if (ivStr.length() != 16) {
JOptionPane.showMessageDialog(this, "IV向量长度必须为16字节", "错误", JOptionPane.ERROR_MESSAGE);
return;
}
// 禁用转换按钮并更新状态
convertBtn.setEnabled(false);
statusField.setText("转换中...");
// 转换为字节数组
byte[] key = keyStr.getBytes();
byte[] iv = ivStr.getBytes();
// 根据选择的是文件还是目录,开始加密
if (selectedFile != null) {
File targetFile = getEncryptedFile(selectedFile);
encryptFileAsync(selectedFile, targetFile, key, iv);
} else if (selectedDir != null) {
traverseAndEncryptDir(selectedDir, key, iv);
}
}
/**
* 遍历目录下所有视频文件并加密
*/
private void traverseAndEncryptDir(File dir, byte[] key, byte[] iv) {
if (!dir.isDirectory()) {
JOptionPane.showMessageDialog(this, "选择的不是有效目录!", "错误", JOptionPane.ERROR_MESSAGE);
convertBtn.setEnabled(true);
statusField.setText("准备就绪");
return;
}
File[] files = dir.listFiles();
if (files == null || files.length == 0) {
JOptionPane.showMessageDialog(this, "目录下无文件!", "提示", JOptionPane.INFORMATION_MESSAGE);
convertBtn.setEnabled(true);
statusField.setText("准备就绪");
return;
}
// 批量加密使用SwingWorker避免UI卡顿
new SwingWorker<Void, File>() {
@Override
protected Void doInBackground() throws Exception {
for (File file : files) {
if (file.isFile()) {
String ext = getFileExtension(file);
// 只处理视频文件
if (VIDEO_EXTENSIONS.contains(ext.toLowerCase())) {
File targetFile = getEncryptedFile(file);
VideoEncryptor.encryptFile(file, targetFile, key, iv);
publish(file); // 发布进度
}
}
}
return null;
}
@Override
protected void process(List<File> chunks) {
// 显示当前加密的文件(可选)
File lastFile = chunks.get(chunks.size() - 1);
System.out.println("已加密: " + lastFile.getName());
}
@Override
protected void done() {
try {
get(); // 捕获后台异常
JOptionPane.showMessageDialog(VideoEncryptorGUI.this,
"目录下所有视频文件加密完成!", "完成", JOptionPane.INFORMATION_MESSAGE);
statusField.setText("转换完成");
} catch (InterruptedException | ExecutionException e) {
JOptionPane.showMessageDialog(VideoEncryptorGUI.this,
"加密失败:" + e.getCause().getMessage(),
"错误", JOptionPane.ERROR_MESSAGE);
statusField.setText("转换失败");
} finally {
convertBtn.setEnabled(true);
}
}
}.execute();
}
/**
* 异步加密单个文件避免UI卡顿
*/
private void encryptFileAsync(File sourceFile, File targetFile, byte[] key, byte[] iv) {
new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
VideoEncryptor.encryptFile(sourceFile, targetFile, key, iv);
return null;
}
@Override
protected void done() {
try {
get(); // 捕获后台异常
JOptionPane.showMessageDialog(VideoEncryptorGUI.this,
"文件加密成功!\n输出路径" + targetFile.getAbsolutePath(),
"成功", JOptionPane.INFORMATION_MESSAGE);
statusField.setText("转换完成");
} catch (InterruptedException | ExecutionException e) {
JOptionPane.showMessageDialog(VideoEncryptorGUI.this,
"加密失败:" + e.getCause().getMessage(),
"错误", JOptionPane.ERROR_MESSAGE);
statusField.setText("转换失败");
} finally {
convertBtn.setEnabled(true);
}
}
}.execute();
}
/**
* 获取加密后的目标文件(替换扩展名为.hnv
*/
private File getEncryptedFile(File sourceFile) {
String parentPath = sourceFile.getParent();
String fileName = sourceFile.getName();
String nameWithoutExt = fileName.substring(0, fileName.lastIndexOf("."));
return new File(parentPath + File.separator + nameWithoutExt + ".hnv");
}
/**
* 获取文件扩展名
*/
private String getFileExtension(File file) {
String name = file.getName();
int lastDotIndex = name.lastIndexOf(".");
if (lastDotIndex == -1)
return "";
return name.substring(lastDotIndex + 1);
}
/**
* 加密核心类原VideoEncryptor
*/
static class VideoEncryptor {
private static final String ALGORITHM = "AES/CTR/NoPadding";
public static void encryptFile(File inputFile, File outputFile, byte[] key, byte[] iv) throws Exception {
Cipher cipher = Cipher.getInstance(ALGORITHM);
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
try (FileInputStream fis = new FileInputStream(inputFile);
FileOutputStream fos = new FileOutputStream(outputFile);
CipherOutputStream cos = new CipherOutputStream(fos, cipher)) {
byte[] buffer = new byte[8192];
int read;
while ((read = fis.read(buffer)) != -1) {
cos.write(buffer, 0, read);
}
}
}
}
/**
* 程序入口
*/
public static void main(String[] args) {
// 判断是否为native运行环境
String classPath = System.getProperty("java.class.path");
if(classPath == null || classPath.isBlank()) {
System.setProperty("java.home", ".");
}
// Swing界面需在EDT线程中运行
SwingUtilities.invokeLater(() -> {
VideoEncryptorGUI gui = new VideoEncryptorGUI();
gui.setVisible(true);
});
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
[
{
"type": "agent-extracted",
"classes": [
]
}
]

View File

@@ -0,0 +1,411 @@
[
{
"name": "[B"
},
{
"name": "[C"
},
{
"name": "[Ljava.awt.event.MouseMotionListener;"
},
{
"name": "com.hnos.video.VideoEncryptorGUI",
"methods": [
{
"name": "coalesceEvents",
"parameterTypes": [
"java.awt.AWTEvent",
"java.awt.AWTEvent"
]
}
]
},
{
"name": "com.sun.crypto.provider.AESCipher$General",
"methods": [
{
"name": "<init>",
"parameterTypes": []
}
]
},
{
"name": "default"
},
{
"name": "java.awt.Image"
},
{
"name": "java.awt.SequencedEvent"
},
{
"name": "java.awt.event.KeyEvent",
"fields": [
{
"name": "VK_A"
},
{
"name": "VK_BACK_SLASH"
},
{
"name": "VK_BACK_SPACE"
},
{
"name": "VK_C"
},
{
"name": "VK_CONTEXT_MENU"
},
{
"name": "VK_COPY"
},
{
"name": "VK_CUT"
},
{
"name": "VK_DELETE"
},
{
"name": "VK_DOWN"
},
{
"name": "VK_END"
},
{
"name": "VK_ENTER"
},
{
"name": "VK_ESCAPE"
},
{
"name": "VK_F10"
},
{
"name": "VK_F2"
},
{
"name": "VK_F5"
},
{
"name": "VK_H"
},
{
"name": "VK_HOME"
},
{
"name": "VK_INSERT"
},
{
"name": "VK_KP_DOWN"
},
{
"name": "VK_KP_LEFT"
},
{
"name": "VK_KP_RIGHT"
},
{
"name": "VK_KP_UP"
},
{
"name": "VK_LEFT"
},
{
"name": "VK_O"
},
{
"name": "VK_PAGE_DOWN"
},
{
"name": "VK_PAGE_UP"
},
{
"name": "VK_PASTE"
},
{
"name": "VK_RIGHT"
},
{
"name": "VK_SLASH"
},
{
"name": "VK_SPACE"
},
{
"name": "VK_UP"
},
{
"name": "VK_V"
},
{
"name": "VK_X"
}
]
},
{
"name": "java.io.InputStream"
},
{
"name": "java.io.Reader"
},
{
"name": "java.lang.String"
},
{
"name": "java.net.URL"
},
{
"name": "java.nio.ByteBuffer"
},
{
"name": "java.nio.CharBuffer"
},
{
"name": "java.rmi.MarshalledObject",
"methods": [
{
"name": "<init>",
"parameterTypes": [
"java.lang.Object"
]
},
{
"name": "get",
"parameterTypes": []
}
]
},
{
"name": "java.rmi.Remote"
},
{
"name": "java.security.SecureRandomParameters"
},
{
"name": "java.util.List"
},
{
"name": "java.util.concurrent.atomic.AtomicBoolean",
"fields": [
{
"name": "value"
}
]
},
{
"name": "javax.swing.plaf.basic.BasicListUI",
"methods": [
{
"name": "createUI",
"parameterTypes": [
"javax.swing.JComponent"
]
}
]
},
{
"name": "javax.swing.plaf.basic.BasicOptionPaneUI",
"methods": [
{
"name": "createUI",
"parameterTypes": [
"javax.swing.JComponent"
]
},
{
"name": "loadActionMap",
"parameterTypes": [
"javax.swing.plaf.basic.LazyActionMap"
]
}
]
},
{
"name": "javax.swing.plaf.basic.BasicPanelUI",
"methods": [
{
"name": "createUI",
"parameterTypes": [
"javax.swing.JComponent"
]
}
]
},
{
"name": "javax.swing.plaf.basic.BasicPopupMenuUI",
"methods": [
{
"name": "createUI",
"parameterTypes": [
"javax.swing.JComponent"
]
}
]
},
{
"name": "javax.swing.plaf.basic.BasicViewportUI",
"methods": [
{
"name": "createUI",
"parameterTypes": [
"javax.swing.JComponent"
]
}
]
},
{
"name": "javax.swing.plaf.metal.MetalButtonUI",
"methods": [
{
"name": "createUI",
"parameterTypes": [
"javax.swing.JComponent"
]
}
]
},
{
"name": "javax.swing.plaf.metal.MetalComboBoxUI",
"methods": [
{
"name": "createUI",
"parameterTypes": [
"javax.swing.JComponent"
]
}
]
},
{
"name": "javax.swing.plaf.metal.MetalFileChooserUI",
"methods": [
{
"name": "createUI",
"parameterTypes": [
"javax.swing.JComponent"
]
}
]
},
{
"name": "javax.swing.plaf.metal.MetalLabelUI",
"methods": [
{
"name": "createUI",
"parameterTypes": [
"javax.swing.JComponent"
]
}
]
},
{
"name": "javax.swing.plaf.metal.MetalRootPaneUI",
"methods": [
{
"name": "createUI",
"parameterTypes": [
"javax.swing.JComponent"
]
}
]
},
{
"name": "javax.swing.plaf.metal.MetalScrollBarUI",
"methods": [
{
"name": "createUI",
"parameterTypes": [
"javax.swing.JComponent"
]
}
]
},
{
"name": "javax.swing.plaf.metal.MetalScrollPaneUI",
"methods": [
{
"name": "createUI",
"parameterTypes": [
"javax.swing.JComponent"
]
}
]
},
{
"name": "javax.swing.plaf.metal.MetalTextFieldUI",
"methods": [
{
"name": "createUI",
"parameterTypes": [
"javax.swing.JComponent"
]
}
]
},
{
"name": "javax.swing.plaf.metal.MetalToggleButtonUI",
"methods": [
{
"name": "createUI",
"parameterTypes": [
"javax.swing.JComponent"
]
}
]
},
{
"name": "sun.awt.Symbol",
"methods": [
{
"name": "<init>",
"parameterTypes": []
}
]
},
{
"name": "sun.awt.Win32FontManager",
"methods": [
{
"name": "<init>",
"parameterTypes": []
}
]
},
{
"name": "sun.awt.shell.Win32ShellFolderManager2",
"methods": [
{
"name": "<init>",
"parameterTypes": []
}
]
},
{
"name": "sun.awt.windows.WingDings",
"methods": [
{
"name": "<init>",
"parameterTypes": []
}
]
},
{
"name": "sun.java2d.marlin.DMarlinRenderingEngine",
"methods": [
{
"name": "<init>",
"parameterTypes": []
}
]
},
{
"name": "sun.security.provider.DRBG",
"methods": [
{
"name": "<init>",
"parameterTypes": [
"java.security.SecureRandomParameters"
]
}
]
}
]

View File

@@ -0,0 +1,59 @@
{
"resources": {
"includes": [
{
"pattern": "java.datatransfer:\\Qsun/datatransfer/resources/flavormap.properties\\E"
},
{
"pattern": "java.desktop:\\Qjavax/swing/plaf/metal/icons/ocean/computer.gif\\E"
},
{
"pattern": "java.desktop:\\Qjavax/swing/plaf/metal/icons/ocean/directory.gif\\E"
},
{
"pattern": "java.desktop:\\Qjavax/swing/plaf/metal/icons/ocean/file.gif\\E"
},
{
"pattern": "java.desktop:\\Qjavax/swing/plaf/metal/icons/ocean/floppy.gif\\E"
},
{
"pattern": "java.desktop:\\Qjavax/swing/plaf/metal/icons/ocean/hardDrive.gif\\E"
},
{
"pattern": "java.desktop:\\Qjavax/swing/plaf/metal/icons/ocean/homeFolder.gif\\E"
},
{
"pattern": "java.desktop:\\Qjavax/swing/plaf/metal/icons/ocean/info.png\\E"
},
{
"pattern": "java.desktop:\\Qjavax/swing/plaf/metal/icons/ocean/newFolder.gif\\E"
},
{
"pattern": "java.desktop:\\Qjavax/swing/plaf/metal/icons/ocean/upFolder.gif\\E"
}
]
},
"bundles": [
{
"name": "com.sun.swing.internal.plaf.basic.resources.basic",
"classNames": [
"com.sun.swing.internal.plaf.basic.resources.basic",
"com.sun.swing.internal.plaf.basic.resources.basic_zh_CN"
]
},
{
"name": "com.sun.swing.internal.plaf.metal.resources.metal",
"classNames": [
"com.sun.swing.internal.plaf.metal.resources.metal",
"com.sun.swing.internal.plaf.metal.resources.metal_zh_CN"
]
},
{
"name": "sun.awt.resources.awt",
"classNames": [
"sun.awt.resources.awt",
"sun.awt.resources.awt_zh_CN"
]
}
]
}

View File

@@ -0,0 +1,8 @@
{
"types": [
],
"lambdaCapturingTypes": [
],
"proxies": [
]
}