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

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) {