feat(gui): 添加 MaterialLookAndFeel 主题并优化搜索框样式

- 在系统主题中添加 MaterialLookAndFeel 的暗色、浅色和深色主题
- 实现自定义圆角搜索文本框,增加聚焦动画和发光效果
- 移除 FridaWindow 中的静态代码块- 更新 MainWindow 中的标题样式和搜索框实现
- 在语言文件中添加新主题的翻译
This commit is contained in:
tzdwindows 7
2025-08-14 21:50:40 +08:00
parent 62c521a5ea
commit a41b894ee8
7 changed files with 129 additions and 19 deletions

2
.idea/encodings.xml generated
View File

@@ -4,7 +4,7 @@
<file url="file://$PROJECT_DIR$/language" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/plug-in/python/Testing/main.py" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/Cpp/LM/org_tzd_lm_LM.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/src/main/java/com/axis/innovators/box/gui/FridaWindow.java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/java/com/axis/innovators/box/window/FridaWindow.java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/java/org/tzd/lm/LM.java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/java/org/tzd/lm/LMApi.java" charset="UTF-8" />
</component>

View File

@@ -56,6 +56,7 @@ dependencies {
implementation 'com.formdev:flatlaf:3.2.1'
implementation 'com.formdev:flatlaf-extras:3.2.1'
implementation 'com.formdev:flatlaf-intellij-themes:3.2.1'
implementation 'io.github.vincenzopalazzo:material-ui-swing:1.1.2'
implementation 'org.python:jython-standalone:2.7.3'
implementation 'org.graalvm.python:python-embedding:24.2.1'
implementation files('libs/JNC-1.0-jnc.jar')

View File

@@ -1,3 +1,3 @@
#Current Loaded Language
#Thu Aug 14 15:17:57 CST 2025
#Thu Aug 14 20:44:49 CST 2025
loadedLanguage=system\:zh_CN

View File

@@ -29,6 +29,15 @@ flatMacLight_theme.default.tip=\u7C7B\u4F3C macOS \u7684\u6D45\u8272\u98CE\u683C
flatMacDark_theme.system.topicName=macOS \u6DF1\u8272
flatMacDark_theme.default.tip=\u7C7B\u4F3C macOS \u7684\u6DF1\u8272\u6A21\u5F0F\uFF0C\u4F18\u96C5\u73B0\u4EE3
mars_dark_theme.system.topicName=MaterialLookAndFeel\u7684\u6697\u8272
mars_dark_theme.default.tip=\u57FA\u4E8E MaterialLookAndFeel \u7684\u6697\u8272\u4E3B\u9898
material_lite_theme.system.topicName=MaterialLookAndFeel\u7684\u6D45\u8272
material_lite_theme.default.tip=\u57FA\u4E8E MaterialLookAndFeel \u7684\u6D45\u8272\u4E3B\u9898\uFF0CMaterial Design \u98CE\u683C
material_oceanic_theme.system.topicName=MaterialLookAndFeel\u7684\u6DF1\u8272
material_oceanic_theme.default.tip=\u57FA\u4E8E MaterialLookAndFeel \u7684\u6D45\u8272\u4E3B\u9898\uFF0CMaterial Design \u98CE\u683C
flatLightLaf_theme.system.topicName=flatLightLaf\u98CE\u683C
flatLightLaf_theme.default.tip=flatLightLaf\u98CE\u683C

View File

@@ -19,6 +19,10 @@ import com.axis.innovators.box.verification.UserTags;
import com.formdev.flatlaf.themes.FlatMacDarkLaf;
import com.formdev.flatlaf.themes.FlatMacLightLaf;
import com.sun.management.HotSpotDiagnosticMXBean;
import mdlaf.MaterialLookAndFeel;
import mdlaf.themes.JMarsDarkTheme;
import mdlaf.themes.MaterialLiteTheme;
import mdlaf.themes.MaterialOceanicTheme;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.Appender;
@@ -725,7 +729,7 @@ public class AxisInnovatorsBox {
LanguageManager.getLoadedLanguages().getText("default_theme.default.tip"),
LoadIcon.loadIcon(MainWindow.class, "logo.png", 64),
"system:default_theme",
isDarkMode // 检测系统当前是否为暗黑模式
isDarkMode
);
// 2. Metal (Java默认主题) - 浅色主题
@@ -809,6 +813,33 @@ public class AxisInnovatorsBox {
true
);
main.registrationTopic.addTopic(
new MaterialLookAndFeel(new JMarsDarkTheme()),
LanguageManager.getLoadedLanguages().getText("mars_dark_theme.system.topicName"),
LanguageManager.getLoadedLanguages().getText("mars_dark_theme.default.tip"),
LoadIcon.loadIcon(MainWindow.class, "logo.png", 64),
"system:mars_dark_theme",
true
);
main.registrationTopic.addTopic(
new MaterialLookAndFeel(new MaterialLiteTheme()),
LanguageManager.getLoadedLanguages().getText("material_lite_theme.system.topicName"),
LanguageManager.getLoadedLanguages().getText("material_lite_theme.default.tip"),
LoadIcon.loadIcon(MainWindow.class, "logo.png", 64),
"system:material_lite_theme",
false
);
main.registrationTopic.addTopic(
new MaterialLookAndFeel(new MaterialOceanicTheme()),
LanguageManager.getLoadedLanguages().getText("material_oceanic_theme.system.topicName"),
LanguageManager.getLoadedLanguages().getText("material_oceanic_theme.default.tip"),
LoadIcon.loadIcon(MainWindow.class, "logo.png", 64),
"system:material_oceanic_theme",
true
);
LookAndFeel defaultLaf = isDarkMode ? new FlatMacDarkLaf() : new FlatMacLightLaf();
UIManager.setLookAndFeel(defaultLaf);
main.registrationTopic.setLoading(

View File

@@ -47,14 +47,6 @@ public class FridaWindow extends WindowsJDialog {
initUI();
}
static {
Font chineseFont = new Font("Microsoft YaHei", Font.PLAIN, 13);
UIManager.put("Menu.font", chineseFont);
UIManager.put("MenuItem.font", chineseFont);
UIManager.put("Button.font", chineseFont);
UIManager.put("ComboBox.font", chineseFont);
}
@Override
public void initUI() {
super.initUI();

View File

@@ -18,6 +18,7 @@ import javax.swing.plaf.basic.BasicScrollBarUI;
import javax.swing.plaf.basic.BasicTabbedPaneUI;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Point2D;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.util.*;
@@ -245,7 +246,7 @@ public class MainWindow extends JFrame {
JLabel title = new JLabel(LanguageManager.getLoadedLanguages().getText("mainWindow.title.2"));
title.setFont(new Font(selectFont("Segoe UI", "Microsoft YaHei", "SansSerif", 18).getName(), Font.BOLD, 18));
title.setForeground(UIManager.getColor("Label.foreground"));
//title.setForeground(UIManager.getColor("Label.foreground"));
JPanel left = new JPanel(new FlowLayout(FlowLayout.LEFT, 8, 0));
left.setOpaque(false);
@@ -278,7 +279,6 @@ public class MainWindow extends JFrame {
return header;
}
// 自定义圆角的搜索文本框容器(含聚焦动画)
private static class RoundedSearchField extends JPanel {
private final JTextField textField;
private int targetWidth;
@@ -287,41 +287,59 @@ public class MainWindow extends JFrame {
private final int baseWidth;
private final int heightPx;
// 动画相关变量
private float glowPosition = 0f;
private final Timer glowTimer;
private Color defaultBorderColor;
private boolean focused = false;
RoundedSearchField(int baseWidth, int heightPx) {
this.baseWidth = baseWidth;
this.heightPx = heightPx;
this.targetWidth = baseWidth;
setOpaque(false);
setLayout(new BorderLayout());
// 获取系统默认边框色
defaultBorderColor = UIManager.getColor("TextField.borderColor");
if (defaultBorderColor == null) {
defaultBorderColor = new Color(180, 180, 180); // 备用默认色
}
textField = new JTextField();
textField.setBorder(BorderFactory.createEmptyBorder(6, 10, 6, 10));
textField.setOpaque(false);
textField.setFont(UIManager.getFont("TextField.font"));
// initial size
setPreferredSize(new Dimension(baseWidth, heightPx));
add(textField, BorderLayout.CENTER);
// focus listener -> expand + highlight
// 焦点监听器
textField.addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
focused = true;
animateTo(baseWidth + 80);
glowTimer.start();
}
@Override
public void focusLost(FocusEvent e) {
focused = false;
animateTo(baseWidth);
glowTimer.stop();
repaint();
}
});
// mouse click on panel focuses textfield
// 点击面板聚焦文本框
addMouseListener(new MouseAdapter() {
@Override public void mouseClicked(MouseEvent e) { textField.requestFocusInWindow(); }
@Override public void mouseClicked(MouseEvent e) {
textField.requestFocusInWindow();
}
});
// animation timer
// 尺寸动画定时器
animTimer = new Timer(16, ae -> {
// smooth progress towards target width
int curW = getWidth();
int diff = targetWidth - curW;
if (Math.abs(diff) <= 1) {
@@ -337,6 +355,65 @@ public class MainWindow extends JFrame {
repaint();
}
});
// 发光动画定时器
glowTimer = new Timer(30, e -> {
glowPosition = (glowPosition + 0.03f) % 1f;
repaint();
});
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
int arc = heightPx / 2; // 圆角半径
int borderThickness = focused ? 2 : 1;
// 绘制背景
g2d.setColor(getBackground());
g2d.fillRoundRect(0, 0, getWidth(), getHeight(), arc, arc);
// 绘制边框
if (focused) {
// 流动彩虹渐变
float[] fractions = {0f, 0.25f, 0.5f, 0.75f, 1f};
Color[] colors = {
new Color(255, 0, 0, 200), // 红
new Color(255, 165, 0, 200), // 橙
new Color(0, 255, 0, 200), // 绿
new Color(0, 191, 255, 200), // 蓝
new Color(148, 0, 211, 200) // 紫
};
// 创建循环渐变
Point2D start = new Point2D.Float(getWidth() * glowPosition, 0);
Point2D end = new Point2D.Float(getWidth() * glowPosition + getWidth(), 0);
LinearGradientPaint gradient = new LinearGradientPaint(
start, end, fractions, colors
);
g2d.setPaint(gradient);
g2d.setStroke(new BasicStroke(2.5f));
} else {
g2d.setColor(defaultBorderColor);
g2d.setStroke(new BasicStroke(1f));
}
g2d.drawRoundRect(borderThickness/2, borderThickness/2,
getWidth() - borderThickness, getHeight() - borderThickness,
arc, arc);
// 添加发光效果
if (focused) {
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f));
g2d.setStroke(new BasicStroke(4f));
g2d.drawRoundRect(0, 0, getWidth(), getHeight(), arc, arc);
}
g2d.dispose();
}
void animateTo(int w) {