feat(gui): 重构主界面并添加新功能

- 重新设计了主窗口布局,增加了侧边栏和内容面板
- 添加了分类按钮和设置按钮
- 实现了内存分析面板的自动补全功能
- 优化了日志文件生成和异常处理机制- 更新了依赖库版本
This commit is contained in:
tzdwindows 7
2025-08-12 20:30:41 +08:00
parent 4b7c153756
commit 9d684b310f
20 changed files with 2645 additions and 1121 deletions

View File

@@ -65,6 +65,8 @@ dependencies {
//implementation 'com.formdev:flatlaf:0.26'
implementation 'commons-io:commons-io:2.14.0'
implementation 'com.formdev:flatlaf:3.2.1' // FlatLaf核心
implementation 'com.formdev:flatlaf-extras:3.2.1' // 扩展组件
implementation 'com.formdev:flatlaf-intellij-themes:3.2.1' // 官方主题包
@@ -74,6 +76,7 @@ dependencies {
implementation files('libs/JNC-1.0-jnc.jar')
implementation files('libs/dog api 1.3.jar')
implementation files('libs/DesktopWallpaperSdk-1.0-SNAPSHOT.jar')
implementation 'org.fxmisc.richtext:richtextfx:0.11.0' // 更新后的richtextfx
implementation 'org.bitbucket.mstrobel:procyon-core:0.5.36' // 使用JitPack版本
@@ -112,6 +115,21 @@ dependencies {
//runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.3', // JWT实现
// 'io.jsonwebtoken:jjwt-jackson:0.12.3' // JWT序列化
implementation 'org.json:json:20230618'
implementation 'org.lwjgl:lwjgl:3.3.1'
implementation 'org.lwjgl:lwjgl-glfw:3.3.1'
implementation 'org.lwjgl:lwjgl-opengl:3.3.1'
implementation 'org.lwjgl:lwjgl:3.3.1:natives-windows' // Windows natives
implementation 'org.lwjgl:lwjgl-glfw:3.3.1:natives-windows'
implementation 'org.lwjgl:lwjgl-opengl:3.3.1:natives-windows'
implementation 'org.bytedeco:javacv-platform:1.5.7' // JavaCV
implementation 'org.bytedeco:javacpp-platform:1.5.7' // JavaCPP
implementation 'com.madgag:animated-gif-lib:1.4'
implementation 'org.openjfx:javafx-web:17'
runtimeOnly 'com.mysql:mysql-connector-j'
@@ -136,12 +154,15 @@ dependencies {
implementation 'me.friwi:jcefmaven:122.1.10'
implementation 'com.alphacephei:vosk:0.3.45' // Java API
implementation 'net.java.dev.jna:jna:5.12.1' // 本地库加载
implementation 'net.java.dev.jna:jna:5.13.0'
implementation 'net.java.dev.jna:jna-platform:5.13.0'
// 高性能音频处理
implementation 'org.apache.commons:commons-math3:3.6.1'
implementation 'com.google.guava:guava:31.1-jre'
implementation 'com.github.javaparser:javaparser-symbol-solver-core:3.25.9'
// 中文拼音处理
implementation 'com.belerweb:pinyin4j:2.5.1'

View File

@@ -1,3 +1,3 @@
#Current Loaded Language
#Sat May 31 10:30:35 CST 2025
#Wed Jul 02 20:11:55 CST 2025
loadedLanguage=system\:zh_CN

Binary file not shown.

View File

@@ -17,6 +17,7 @@ import com.axis.innovators.box.util.Tray;
import com.axis.innovators.box.util.UserLocalInformation;
import com.axis.innovators.box.verification.UserTags;
import com.formdev.flatlaf.FlatLightLaf;
import com.sun.management.HotSpotDiagnosticMXBean;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.Appender;
@@ -78,6 +79,10 @@ public class AxisInnovatorsBox {
public AxisInnovatorsBox(String[] args, boolean isDebug) {
this.args = args;
this.isDebug = isDebug;
Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> {
organizingCrashReports(throwable instanceof Exception ?
(Exception) throwable : new Exception(throwable));
});
}
/**
@@ -358,7 +363,7 @@ public class AxisInnovatorsBox {
if (appender instanceof FileAppender fileAppender) {
String fileName = fileAppender.getFileName();
if (fileName != null && !addedFiles.contains(fileName)) {
addFileToZip(zos, new File(fileName), "logs/");
addFileToZip(zos, new File(fileName), "logs/" + new File(fileName).getName());
addedFiles.add(fileName);
}
}
@@ -387,7 +392,7 @@ public class AxisInnovatorsBox {
for (File file : logFiles) {
String absolutePath = file.getAbsolutePath();
if (!addedFiles.contains(absolutePath)) {
addFileToZip(zos, file, "logs/");
addFileToZip(zos, file, "logs/" + file.getName());
addedFiles.add(absolutePath);
}
}
@@ -436,6 +441,24 @@ public class AxisInnovatorsBox {
addFileToZip(zos, generateSystemProperties(), "debug_files/system_properties.txt");
// 7. 添加环境变量
addFileToZip(zos, generateEnvironmentVariables(), "debug_files/environment_variables.txt");
// 8.生成dump文件
addFileToZip(zos, generateFileDump(), "debug_files/dump.hprof");
}
private File generateFileDump() throws IOException {
final String javaLibraryPath = System.getProperty("java.library.path");
String jvmFolder = javaLibraryPath.contains(";")
? javaLibraryPath.substring(0, javaLibraryPath.indexOf(';'))
: javaLibraryPath;
logger.info("JVM folder: {}", jvmFolder);
File dumpFile = File.createTempFile("dump", ".hprof");
String dumpFilePath = dumpFile.getAbsolutePath();
if (!dumpFile.delete()) {
throw new IOException("Failed to delete temporary placeholder file");
}
HotSpotDiagnosticMXBean bean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
bean.dumpHeap(dumpFilePath, true);
return new File(dumpFilePath);
}
private File generateClassLoaderInfo() throws IOException {
@@ -606,8 +629,7 @@ public class AxisInnovatorsBox {
return;
}
String entryName = entryPath + file.getName();
ZipEntry zipEntry = new ZipEntry(entryName);
ZipEntry zipEntry = new ZipEntry(entryPath);
zos.putNextEntry(zipEntry);
try (FileInputStream fis = new FileInputStream(file)) {
@@ -805,6 +827,22 @@ public class AxisInnovatorsBox {
}
public static void run(String[] args, boolean isDebug) {
Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> {
if (main != null) {
main.organizingCrashReports(throwable instanceof Exception ?
(Exception) throwable : new Exception(throwable));
} else {
// 如果主类尚未初始化,创建临时实例处理崩溃
new AxisInnovatorsBox(args, isDebug)
.organizingCrashReports(throwable instanceof Exception ?
(Exception) throwable : new Exception(throwable));
}
});
// 设置EDT(事件调度线程)的异常处理器
System.setProperty("sun.awt.exception.handler", EDTCrashHandler.class.getName());
main = new AxisInnovatorsBox(args,isDebug);
try {
main.initLog4j2();
@@ -880,7 +918,6 @@ public class AxisInnovatorsBox {
throw new RuntimeException(e);
}
}, "TrayThread").start();
} catch (Exception e) {
logger.error("Failed to load plugins", e);
if (main.ex != null) {
@@ -972,4 +1009,16 @@ public class AxisInnovatorsBox {
public StateManager getStateManager() {
return stateManager;
}
/**
* 专门处理EDT线程异常的处理器
*/
public static class EDTCrashHandler {
public void handle(Throwable throwable) {
if (main != null) {
main.organizingCrashReports(throwable instanceof Exception ?
(Exception) throwable : new Exception(throwable));
}
}
}
}

View File

@@ -126,10 +126,7 @@ public class Main {
}
}
// 添加JVM关闭钩子确保锁释放
static {
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
releaseLock();
}));
Runtime.getRuntime().addShutdownHook(new Thread(Main::releaseLock));
}
}

View File

@@ -55,7 +55,7 @@ public class CefAppManager {
private static void initializeDefaultSettings() {
initLock.lock();
try {
settings.windowless_rendering_enabled = false;
settings.windowless_rendering_enabled = true;
settings.javascript_flags = "--expose-gc";
settings.cache_path = FolderCreator.getLibraryFolder() + "/jcef/cache";
settings.root_cache_path = FolderCreator.getLibraryFolder() + "/jcef/cache";

View File

@@ -1,138 +0,0 @@
package com.axis.innovators.box.events;
import com.axis.innovators.box.gui.MainWindow;
import java.awt.*;
/**
* 分类栏的渲染事件
* @author tzdwindows 7
*/
public class CategoryRenderingEvent {
private final MainWindow.CustomTabbedPaneUI ui;
private final Graphics graphics;
private final int tabPlacement;
private final int tabIndex;
private final int x;
private final int y;
private final int width;
private final int height;
private final boolean isSelected;
private boolean isEnd = false;
public CategoryRenderingEvent(MainWindow.CustomTabbedPaneUI ui, Graphics graphics, int tabPlacement, int tabIndex, int x, int y, int width, int height, boolean isSelected) {
this.ui = ui;
this.graphics = graphics;
this.tabPlacement = tabPlacement;
this.tabIndex = tabIndex;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.isSelected = isSelected;
}
public MainWindow.CustomTabbedPaneUI getUi() {
return ui;
}
public Graphics getGraphics() {
return graphics;
}
public int getTabPlacement() {
return tabPlacement;
}
public int getTabIndex() {
return tabIndex;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public boolean isSelected() {
return isSelected;
}
public boolean isEnd() {
return isEnd;
}
public void setEnd(boolean end) {
isEnd = end;
}
public static class paintTabBorder {
private final MainWindow.CustomTabbedPaneUI event;
private final Graphics graphics;
private final int tabPlacement;
private final int tabIndex;
private final int x;
private final int y;
private final int width;
private final int height;
private final boolean isSelected;
public paintTabBorder(MainWindow.CustomTabbedPaneUI event, Graphics graphics, int tabPlacement, int tabIndex, int x, int y, int width, int height, boolean isSelected) {
this.event = event;
this.graphics = graphics;
this.tabPlacement = tabPlacement;
this.tabIndex = tabIndex;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.isSelected = isSelected;
}
public MainWindow.CustomTabbedPaneUI getEvent() {
return event;
}
public Graphics getGraphics() {
return graphics;
}
public int getTabPlacement() {
return tabPlacement;
}
public int getTabIndex() {
return tabIndex;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public boolean isSelected() {
return isSelected;
}
}
}

View File

@@ -34,6 +34,7 @@ public class MainWindow extends JFrame {
private final Color CARD_COLOR = Color.WHITE;
private final List<ToolCategory> categories = new ArrayList<>();
private SystemTray systemTray;
private JPanel contentPanel;
//private TrayIcon trayIcon;
public MainWindow() {
@@ -67,7 +68,7 @@ public class MainWindow extends JFrame {
getContentPane().setBackground(new Color(0, 0, 0, 0));
JPanel mainPanel = new JPanel();
JPanel mainPanel = new JPanel(new BorderLayout());
mainPanel.setOpaque(true);
@@ -86,8 +87,87 @@ public class MainWindow extends JFrame {
setVisible(false);
}
});
JPanel sideBar = createSideBar();
mainPanel.add(sideBar, BorderLayout.WEST);
contentPanel = new JPanel(new BorderLayout());
contentPanel.setOpaque(false);
mainPanel.add(contentPanel, BorderLayout.CENTER);
mainPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
add(mainPanel);
}
private JPanel createSideBar() {
JPanel sidebar = new JPanel();
sidebar.setLayout(new BoxLayout(sidebar, BoxLayout.Y_AXIS));
sidebar.setBackground(new Color(35, 35, 35));
sidebar.setPreferredSize(new Dimension(180, getHeight()));
// 添加分类按钮
for (ToolCategory category : categories) {
JButton button = new JButton(category.getName());
button.setAlignmentX(Component.CENTER_ALIGNMENT);
button.setMaximumSize(new Dimension(160, 40));
button.setForeground(Color.WHITE);
button.setBackground(new Color(60, 60, 60));
button.setFocusPainted(false);
button.setBorderPainted(false);
button.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
button.addActionListener(e -> {
JPanel toolsPanel = createToolsPanel(category);
toolsPanel.setOpaque(false);
contentPanel.removeAll();
JScrollPane scrollPane = new JScrollPane(toolsPanel);
scrollPane.setBorder(null);
scrollPane.setOpaque(false);
scrollPane.getViewport().setOpaque(false);
scrollPane.getVerticalScrollBar().setUI(new CustomScrollBarUI());
contentPanel.add(scrollPane, BorderLayout.CENTER);
contentPanel.revalidate();
contentPanel.repaint();
});
sidebar.add(Box.createVerticalStrut(10));
sidebar.add(button);
}
// 添加设置按钮
JButton settingsButton = new JButton("设置");
settingsButton.setAlignmentX(Component.CENTER_ALIGNMENT);
settingsButton.setMaximumSize(new Dimension(160, 40));
settingsButton.setForeground(Color.WHITE);
settingsButton.setBackground(new Color(45, 45, 45));
settingsButton.setFocusPainted(false);
settingsButton.setBorderPainted(false);
settingsButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
settingsButton.addActionListener(e -> showSettings());
sidebar.add(Box.createVerticalGlue());
sidebar.add(settingsButton);
// 添加关于按钮
JButton aboutButton = new JButton("关于");
aboutButton.setAlignmentX(Component.CENTER_ALIGNMENT);
aboutButton.setMaximumSize(new Dimension(160, 40));
aboutButton.setForeground(Color.WHITE);
aboutButton.setBackground(new Color(45, 45, 45));
aboutButton.setFocusPainted(false);
aboutButton.setBorderPainted(false);
aboutButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
aboutButton.addActionListener(e -> JOptionPane.showMessageDialog(this, "作者: tzdwindows7"));
sidebar.add(Box.createVerticalStrut(10));
sidebar.add(aboutButton);
return sidebar;
}
private JPanel createFooter() {
JPanel footer = new JPanel();
footer.setLayout(new BoxLayout(footer, BoxLayout.X_AXIS));
@@ -652,11 +732,6 @@ public class MainWindow extends JFrame {
protected void paintTabBackground(Graphics g, int tabPlacement,
int tabIndex, int x, int y, int w, int h,
boolean isSelected) {
CategoryRenderingEvent event = new CategoryRenderingEvent(this, g, tabPlacement, tabIndex, x, y, w, h, isSelected);
GlobalEventBus.EVENT_BUS.post(event);
if (event.isEnd()){
return;
}
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
@@ -669,15 +744,6 @@ public class MainWindow extends JFrame {
g2d.fillRoundRect(x + 2, y + 2, w - 4, h - 4, 10, 10);
g2d.dispose();
}
@Override
protected void paintTabBorder(Graphics g, int tabPlacement,
int tabIndex, int x, int y, int w, int h,
boolean isSelected) {
GlobalEventBus.EVENT_BUS.post(new CategoryRenderingEvent.paintTabBorder(this, g,
tabPlacement,
tabIndex, x, y, w, h, isSelected));
}
}
private class CardMouseAdapter extends MouseAdapter {

View File

@@ -14,9 +14,7 @@ import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableRowSorter;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.*;
import java.awt.geom.Rectangle2D;
import java.lang.instrument.Instrumentation;
import java.lang.management.ManagementFactory;
@@ -30,7 +28,7 @@ import java.text.DecimalFormat;
import java.util.List;
import java.util.Timer;
import java.util.*;
import java.util.concurrent.CancellationException;
import java.util.concurrent.*;
public class MemoryAnalysisPanel extends JPanel {
private static final DecimalFormat MB_FORMAT = new DecimalFormat("#,##0.00");
@@ -92,6 +90,14 @@ public class MemoryAnalysisPanel extends JPanel {
private final JTable specificClassInstanceTable;
private final DefaultTableModel specificClassInstanceModel;
// 自动补全相关组件
private JPopupMenu autoCompletePopup;
private JList<String> autoCompleteList;
private DefaultListModel<String> autoCompleteModel;
private ScheduledExecutorService autoCompleteExecutor;
private final Map<String, List<String>> classCache = new ConcurrentHashMap<>();
private final Set<String> loadedPackages = ConcurrentHashMap.newKeySet();
// 特定类分析面板组件
private JPanel visualizationPanel;
private JLabel ratioLabel;
@@ -99,6 +105,10 @@ public class MemoryAnalysisPanel extends JPanel {
private JTextField instanceSearchField;
private TableRowSorter<DefaultTableModel> instanceSorter;
// 可调整大小的分割面板
private JSplitPane mainSplitPane;
private JSplitPane infoVisualizationSplitPane;
private JSplitPane visualizationInstanceSplitPane;
public MemoryAnalysisPanel() {
super(new BorderLayout());
@@ -280,6 +290,231 @@ public class MemoryAnalysisPanel extends JPanel {
// 初始刷新 - 只加载内存使用和内存池数据
showLoadingDialog("正在初始化内存数据...");
refreshInitialData();
// 初始化自动补全系统
initAutoCompleteSystem();
}
private void initAutoCompleteSystem() {
// 创建自动补全组件
autoCompleteModel = new DefaultListModel<>();
autoCompleteList = new JList<>(autoCompleteModel);
autoCompleteList.setFont(DebugWindow.MONOSPACE_FONT);
autoCompleteList.setBackground(new Color(50, 50, 50));
autoCompleteList.setForeground(FOREGROUND);
autoCompleteList.setSelectionBackground(ACCENT);
autoCompleteList.setSelectionForeground(FOREGROUND);
autoCompleteList.setFixedCellHeight(25);
autoCompletePopup = new JPopupMenu();
autoCompletePopup.setBorder(BorderFactory.createLineBorder(new Color(80, 80, 80)));
autoCompletePopup.add(new JScrollPane(autoCompleteList));
// 添加选择监听器
autoCompleteList.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 1) {
selectAutoCompleteItem();
}
}
});
// 添加键盘监听器
specificClassField.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
handleAutoCompleteKeyPress(e);
}
});
// 添加文档监听器
specificClassField.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
scheduleAutoCompleteUpdate();
}
@Override
public void removeUpdate(DocumentEvent e) {
scheduleAutoCompleteUpdate();
}
@Override
public void changedUpdate(DocumentEvent e) {
scheduleAutoCompleteUpdate();
}
});
// 初始化线程池
autoCompleteExecutor = Executors.newSingleThreadScheduledExecutor();
}
private void scheduleAutoCompleteUpdate() {
// 取消之前的任务
autoCompleteExecutor.shutdownNow();
autoCompleteExecutor = Executors.newSingleThreadScheduledExecutor();
// 安排新任务
autoCompleteExecutor.schedule(() -> {
SwingUtilities.invokeLater(this::updateAutoCompleteSuggestions);
}, 300, TimeUnit.MILLISECONDS);
}
private void updateAutoCompleteSuggestions() {
String text = specificClassField.getText().trim();
if (text.isEmpty()) {
autoCompletePopup.setVisible(false);
return;
}
// 获取或加载建议
List<String> suggestions = getAutoCompleteSuggestions(text);
autoCompleteModel.clear();
if (suggestions.isEmpty()) {
autoCompletePopup.setVisible(false);
return;
}
// 添加到模型
for (String suggestion : suggestions) {
autoCompleteModel.addElement(suggestion);
}
// 显示弹出菜单
if (!autoCompletePopup.isVisible()) {
showAutoCompletePopup();
}
// 选择第一个项目
autoCompleteList.setSelectedIndex(0);
}
private List<String> getAutoCompleteSuggestions(String input) {
String packagePrefix = input.contains(".") ?
input.substring(0, input.lastIndexOf('.') + 1) :
"";
// 如果包名部分发生变化,重新加载该包下的类
if (!classCache.containsKey(packagePrefix) || !loadedPackages.contains(packagePrefix)) {
loadPackageClasses(packagePrefix);
}
List<String> allClasses = classCache.getOrDefault(packagePrefix, new ArrayList<>());
String searchTerm = input.toLowerCase();
// 过滤匹配的类
List<String> suggestions = new ArrayList<>();
for (String className : allClasses) {
if (className.toLowerCase().contains(searchTerm)) {
suggestions.add(className);
}
// 限制数量
if (suggestions.size() >= 100) {
break;
}
}
// 按匹配度排序
suggestions.sort((s1, s2) -> {
int pos1 = s1.toLowerCase().indexOf(searchTerm);
int pos2 = s2.toLowerCase().indexOf(searchTerm);
return Integer.compare(pos1, pos2);
});
return suggestions;
}
private void loadPackageClasses(String packageName) {
// 对于根包的特殊处理
if (packageName.isEmpty()) {
packageName = "";
}
List<String> classes = new ArrayList<>();
Class<?>[] allClasses = instrumentation.getAllLoadedClasses();
for (Class<?> clazz : allClasses) {
String className = clazz.getName();
// 只处理包匹配的类
if (packageName.isEmpty() || className.startsWith(packageName)) {
classes.add(className);
}
}
// 缓存结果
classCache.put(packageName, classes);
loadedPackages.add(packageName);
}
private void showAutoCompletePopup() {
if (specificClassField.isShowing()) {
// 计算弹出位置
Point location = specificClassField.getLocationOnScreen();
location.y += specificClassField.getHeight();
// 设置弹出大小
int width = Math.max(specificClassField.getWidth(), 400);
int height = Math.min(autoCompleteModel.size() * 25, 300);
autoCompletePopup.setPopupSize(width, height);
// 显示弹出菜单
autoCompletePopup.show(specificClassField, 0, specificClassField.getHeight());
}
}
private void handleAutoCompleteKeyPress(KeyEvent e) {
if (!autoCompletePopup.isVisible()) return;
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
moveSelection(-1);
e.consume();
break;
case KeyEvent.VK_DOWN:
moveSelection(1);
e.consume();
break;
case KeyEvent.VK_ENTER:
selectAutoCompleteItem();
e.consume();
break;
case KeyEvent.VK_ESCAPE:
autoCompletePopup.setVisible(false);
e.consume();
break;
case KeyEvent.VK_TAB:
if (autoCompleteList.getSelectedIndex() >= 0) {
selectAutoCompleteItem();
e.consume();
}
break;
}
}
private void moveSelection(int direction) {
int selected = autoCompleteList.getSelectedIndex();
int newIndex = selected + direction;
if (newIndex >= 0 && newIndex < autoCompleteModel.size()) {
autoCompleteList.setSelectedIndex(newIndex);
autoCompleteList.ensureIndexIsVisible(newIndex);
}
}
private void selectAutoCompleteItem() {
String selected = autoCompleteList.getSelectedValue();
if (selected != null) {
specificClassField.setText(selected);
autoCompletePopup.setVisible(false);
specificClassField.requestFocus();
// 将光标移动到文本末尾
specificClassField.setCaretPosition(selected.length());
}
}
private JPanel createSpecificClassAnalysisPanel() {
@@ -316,41 +551,44 @@ public class MemoryAnalysisPanel extends JPanel {
inputPanel.add(classLabel, BorderLayout.WEST);
inputPanel.add(fieldPanel, BorderLayout.CENTER);
// 主内容面板 (使用网格袋布局)
JPanel mainContentPanel = new JPanel(new GridBagLayout());
mainContentPanel.setBackground(BACKGROUND);
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1.0;
gbc.insets = new Insets(5, 5, 5, 5);
// 使用分割面板替代网格袋布局
mainSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
mainSplitPane.setDividerLocation(0.4); // 初始比例为40%
mainSplitPane.setResizeWeight(0.4);
mainSplitPane.setBorder(BorderFactory.createEmptyBorder());
mainSplitPane.setContinuousLayout(true);
mainSplitPane.setDividerSize(5);
mainSplitPane.setBackground(BACKGROUND);
// 类信息面板
// 上半部分:类信息面板
JPanel infoPanel = createClassInfoPanel();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 2;
gbc.weighty = 0.4;
mainContentPanel.add(infoPanel, gbc);
infoPanel.setMinimumSize(new Dimension(100, 100));
// 下半部分:可视化+实例列表
JSplitPane bottomSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
bottomSplitPane.setDividerLocation(0.3); // 初始比例为30%
bottomSplitPane.setResizeWeight(0.3);
bottomSplitPane.setContinuousLayout(true);
bottomSplitPane.setDividerSize(5);
bottomSplitPane.setBackground(BACKGROUND);
// 可视化面板
visualizationPanel = createVisualizationPanel();
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridwidth = 1;
gbc.weighty = 0.1;
mainContentPanel.add(visualizationPanel, gbc);
visualizationPanel.setMinimumSize(new Dimension(100, 100));
// 实例列表面板
JPanel instancesPanel = createInstancesPanel();
gbc.gridx = 1;
gbc.gridy = 1;
gbc.gridwidth = 1;
gbc.weighty = 0.5;
mainContentPanel.add(instancesPanel, gbc);
instancesPanel.setMinimumSize(new Dimension(100, 100));
bottomSplitPane.setLeftComponent(visualizationPanel);
bottomSplitPane.setRightComponent(instancesPanel);
mainSplitPane.setTopComponent(infoPanel);
mainSplitPane.setBottomComponent(bottomSplitPane);
// 添加主内容面板到中心
panel.add(inputPanel, BorderLayout.NORTH);
panel.add(mainContentPanel, BorderLayout.CENTER);
panel.add(mainSplitPane, BorderLayout.CENTER);
return panel;
}

View File

@@ -5,11 +5,11 @@ import java.nio.file.Paths;
public class Main {
public static void main(String[] args) throws Exception {
HighAccuracySpeechRecognition recognizer = new HighAccuracySpeechRecognition(
"C:\\Users\\Administrator\\Desktop\\声音识别模型\\vosk-model-cn-0.22",
"output"
);
recognizer.processAudio(Paths.get("G:\\鬼畜素材\\工作间\\哪吒-嗵嗵\\哪吒-嗵嗵1.wav"));
//HighAccuracySpeechRecognition recognizer = new HighAccuracySpeechRecognition(
// "C:\\Users\\Administrator\\Desktop\\声音识别模型\\vosk-model-cn-0.22",
// "output"
//);
//
//recognizer.processAudio(Paths.get("G:\\鬼畜素材\\工作间\\哪吒-嗵嗵\\哪吒-嗵嗵1.wav"));
}
}

View File

@@ -0,0 +1,4 @@
package org.tzd.explorer;
public class DesktopIconRenderer {
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB