fix: 修改文件名大小写
- 添加反编译工具新的功能:**本地注解** 修正混淆表加载逻辑让他能快速打开文件 - 重构**ProgressBarManager(启动窗口的任务系统)** 增强视觉效果
This commit is contained in:
@@ -163,6 +163,10 @@ dependencies {
|
|||||||
|
|
||||||
implementation 'com.github.javaparser:javaparser-symbol-solver-core:3.25.9'
|
implementation 'com.github.javaparser:javaparser-symbol-solver-core:3.25.9'
|
||||||
|
|
||||||
|
implementation 'org.bitbucket.mstrobel:procyon-core:0.6.0'
|
||||||
|
implementation 'org.bitbucket.mstrobel:procyon-compilertools:0.6.0'
|
||||||
|
//implementation 'org.jetbrains.java.decompiler:fernflower:1.9.0'
|
||||||
|
|
||||||
// 中文拼音处理
|
// 中文拼音处理
|
||||||
implementation 'com.belerweb:pinyin4j:2.5.1'
|
implementation 'com.belerweb:pinyin4j:2.5.1'
|
||||||
|
|
||||||
|
|||||||
@@ -827,13 +827,11 @@ public class AxisInnovatorsBox {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void run(String[] args, boolean isDebug) {
|
public static void run(String[] args, boolean isDebug) {
|
||||||
|
|
||||||
Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> {
|
Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> {
|
||||||
if (main != null) {
|
if (main != null) {
|
||||||
main.organizingCrashReports(throwable instanceof Exception ?
|
main.organizingCrashReports(throwable instanceof Exception ?
|
||||||
(Exception) throwable : new Exception(throwable));
|
(Exception) throwable : new Exception(throwable));
|
||||||
} else {
|
} else {
|
||||||
// 如果主类尚未初始化,创建临时实例处理崩溃
|
|
||||||
new AxisInnovatorsBox(args, isDebug)
|
new AxisInnovatorsBox(args, isDebug)
|
||||||
.organizingCrashReports(throwable instanceof Exception ?
|
.organizingCrashReports(throwable instanceof Exception ?
|
||||||
(Exception) throwable : new Exception(throwable));
|
(Exception) throwable : new Exception(throwable));
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ public class Log4j2OutputStream extends OutputStream {
|
|||||||
systemOutContent.write(b, off, len);
|
systemOutContent.write(b, off, len);
|
||||||
String message = new String(b, off, len).trim();
|
String message = new String(b, off, len).trim();
|
||||||
logger.info(message);
|
logger.info(message);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -28,19 +28,12 @@ public class Main {
|
|||||||
private static FileChannel lockChannel = null;
|
private static FileChannel lockChannel = null;
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
if (!acquireLock()) {
|
// 清理日志文件(最大日志为10)
|
||||||
JOptionPane.showMessageDialog(
|
|
||||||
null,
|
|
||||||
"程序已在运行中,无法启动多个实例",
|
|
||||||
"错误",
|
|
||||||
JOptionPane.ERROR_MESSAGE
|
|
||||||
);
|
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
FolderCleaner.cleanFolder(FolderCreator.getLogsFolder(), 10);
|
FolderCleaner.cleanFolder(FolderCreator.getLogsFolder(), 10);
|
||||||
|
|
||||||
|
// 加载保存的语言
|
||||||
LanguageManager.loadSavedLanguage();
|
LanguageManager.loadSavedLanguage();
|
||||||
|
// 如果没有加载的语言,则加载默认的语言
|
||||||
if (LanguageManager.getLoadedLanguages() == null) {
|
if (LanguageManager.getLoadedLanguages() == null) {
|
||||||
LanguageManager.loadLanguage("system:zh_CN");
|
LanguageManager.loadLanguage("system:zh_CN");
|
||||||
}
|
}
|
||||||
@@ -84,6 +77,10 @@ public class Main {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!acquireLock()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
AxisInnovatorsBox.run(args, debugWindowEnabled);
|
AxisInnovatorsBox.run(args, debugWindowEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -125,7 +125,7 @@ public class MainWindow extends JFrame {
|
|||||||
*/
|
*/
|
||||||
public void initUI() {
|
public void initUI() {
|
||||||
setTitle(LanguageManager.getLoadedLanguages().getText("mainWindow.title"));
|
setTitle(LanguageManager.getLoadedLanguages().getText("mainWindow.title"));
|
||||||
setDefaultCloseOperation(EXIT_ON_CLOSE);
|
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
|
||||||
setSize(1200, 800);
|
setSize(1200, 800);
|
||||||
setLocationRelativeTo(null);
|
setLocationRelativeTo(null);
|
||||||
|
|
||||||
|
|||||||
@@ -2,17 +2,20 @@ package com.axis.innovators.box.gui;
|
|||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.awt.event.*;
|
||||||
|
import java.awt.geom.*;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 启动窗口的任务系统
|
* 启动窗口的任务系统(已改造为现代流畅动画视觉效果)
|
||||||
* @author tzdwindows 7
|
* 注意:保留了原有对外方法和签名(updateMainProgress/updateSubProgress/setTotalTasks/close)
|
||||||
|
* 作者: tzdwindows 7(UI 改造版)
|
||||||
*/
|
*/
|
||||||
public class ProgressBarManager extends WindowsJDialog {
|
public class ProgressBarManager extends WindowsJDialog {
|
||||||
private JFrame loadingFrame;
|
private JFrame loadingFrame;
|
||||||
private JProgressBar mainProgressBar;
|
private SmoothProgressBar mainProgressBar;
|
||||||
private JProgressBar subProgressBar;
|
private SmoothProgressBar subProgressBar;
|
||||||
private JLabel statusLabel;
|
private JLabel statusLabel;
|
||||||
private JLabel timeLabel;
|
private JLabel timeLabel;
|
||||||
private long startTime;
|
private long startTime;
|
||||||
@@ -21,81 +24,208 @@ public class ProgressBarManager extends WindowsJDialog {
|
|||||||
private int completedTasks;
|
private int completedTasks;
|
||||||
private Map<String, Integer> subTasks = new HashMap<>();
|
private Map<String, Integer> subTasks = new HashMap<>();
|
||||||
|
|
||||||
|
// 动画计时器(60FPS)
|
||||||
|
private Timer animationTimer;
|
||||||
|
|
||||||
|
// 视觉参数
|
||||||
|
private Color accentColor = new Color(0x00C2FF); // 科技感青蓝
|
||||||
|
private Font uiFont;
|
||||||
|
|
||||||
public ProgressBarManager(String title, int totalTasks) {
|
public ProgressBarManager(String title, int totalTasks) {
|
||||||
this.totalTasks = totalTasks;
|
this.totalTasks = Math.max(1, totalTasks);
|
||||||
this.completedTasks = 0;
|
this.completedTasks = 0;
|
||||||
this.startTime = System.currentTimeMillis();
|
this.startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
// 尝试设置现代中文友好字体(Windows 常见)
|
||||||
|
try {
|
||||||
|
uiFont = new Font("Microsoft YaHei UI", Font.PLAIN, 13);
|
||||||
|
// 若系统无该字体则 fallback
|
||||||
|
if (!uiFont.getFamily().toLowerCase().contains("microsoft") &&
|
||||||
|
!uiFont.getFamily().toLowerCase().contains("yahei")) {
|
||||||
|
uiFont = new Font("Segoe UI", Font.PLAIN, 13);
|
||||||
|
}
|
||||||
|
} catch (Throwable t) {
|
||||||
|
uiFont = new Font(Font.SANS_SERIF, Font.PLAIN, 13);
|
||||||
|
}
|
||||||
|
|
||||||
loadingFrame = new JFrame(title);
|
loadingFrame = new JFrame(title);
|
||||||
|
loadingFrame.setUndecorated(true);
|
||||||
|
loadingFrame.setBackground(new Color(0, 0, 0, 0)); // 允许圆角透明背景
|
||||||
loadingFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
|
loadingFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
|
||||||
loadingFrame.setSize(400, 250);
|
loadingFrame.setSize(520, 300);
|
||||||
loadingFrame.setLocationRelativeTo(null);
|
loadingFrame.setLocationRelativeTo(null);
|
||||||
loadingFrame.setIconImage(LoadIcon.loadIcon("logo.png", 64).getImage());
|
loadingFrame.setIconImage(LoadIcon.loadIcon("logo.png", 64).getImage());
|
||||||
|
|
||||||
JPanel loadingPanel = new JPanel(new BorderLayout());
|
// 主容器(带动画背景和圆角卡片)
|
||||||
|
AnimatedBackgroundPanel root = new AnimatedBackgroundPanel();
|
||||||
|
root.setLayout(new GridBagLayout());
|
||||||
|
root.setBorder(BorderFactory.createEmptyBorder(18, 18, 18, 18));
|
||||||
|
|
||||||
mainProgressBar = new JProgressBar(0, 100);
|
// 卡片面板
|
||||||
mainProgressBar.setStringPainted(true);
|
JPanel card = new JPanel() {
|
||||||
|
@Override
|
||||||
|
protected void paintComponent(Graphics g) {
|
||||||
|
Graphics2D g2 = (Graphics2D) g.create();
|
||||||
|
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
|
|
||||||
subProgressBar = new JProgressBar(0, 100);
|
// 卡片阴影(简单外发光)
|
||||||
subProgressBar.setStringPainted(true);
|
int arc = 18;
|
||||||
subProgressBar.setString("Subtask Progress");
|
int w = getWidth();
|
||||||
|
int h = getHeight();
|
||||||
|
|
||||||
statusLabel = new JLabel("Initializing...", SwingConstants.CENTER);
|
// 背景渐变
|
||||||
timeLabel = new JLabel("Time elapsed: 0s", SwingConstants.CENTER);
|
GradientPaint gp = new GradientPaint(0, 0, new Color(20, 22, 25, 230),
|
||||||
|
0, h, new Color(14, 16, 19, 230));
|
||||||
|
g2.setPaint(gp);
|
||||||
|
|
||||||
JLabel logoLabel = new JLabel(LoadIcon.loadIcon("logo.png", 64));
|
// 圆角矩形
|
||||||
|
RoundRectangle2D rr = new RoundRectangle2D.Float(6, 6, w - 12, h - 12, arc, arc);
|
||||||
|
g2.fill(rr);
|
||||||
|
|
||||||
JPanel progressPanel = new JPanel(new GridLayout(2, 1));
|
// 细微边框
|
||||||
progressPanel.add(mainProgressBar);
|
g2.setStroke(new BasicStroke(1f));
|
||||||
progressPanel.add(subProgressBar);
|
g2.setColor(new Color(255, 255, 255, 10));
|
||||||
|
g2.draw(rr);
|
||||||
|
|
||||||
loadingPanel.add(logoLabel, BorderLayout.NORTH);
|
g2.dispose();
|
||||||
loadingPanel.add(progressPanel, BorderLayout.CENTER);
|
super.paintComponent(g);
|
||||||
loadingPanel.add(statusLabel, BorderLayout.SOUTH);
|
}
|
||||||
loadingPanel.add(timeLabel, BorderLayout.SOUTH);
|
};
|
||||||
|
card.setOpaque(false);
|
||||||
|
card.setLayout(new BorderLayout(12, 12));
|
||||||
|
card.setPreferredSize(new Dimension(480, 240));
|
||||||
|
card.setBorder(BorderFactory.createEmptyBorder(14, 14, 14, 14));
|
||||||
|
|
||||||
|
// 顶部 logo + 标题
|
||||||
|
JPanel top = new JPanel(new BorderLayout());
|
||||||
|
top.setOpaque(false);
|
||||||
|
JLabel logoLabel = new JLabel(LoadIcon.loadIcon("logo.png", 48));
|
||||||
|
logoLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 12));
|
||||||
|
JLabel titleLabel = new JLabel(title);
|
||||||
|
titleLabel.setFont(uiFont.deriveFont(Font.BOLD, 18f));
|
||||||
|
titleLabel.setForeground(Color.WHITE);
|
||||||
|
|
||||||
|
top.add(logoLabel, BorderLayout.WEST);
|
||||||
|
top.add(titleLabel, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
// 中间进度区
|
||||||
|
JPanel center = new JPanel(new GridBagLayout());
|
||||||
|
center.setOpaque(false);
|
||||||
|
GridBagConstraints c = new GridBagConstraints();
|
||||||
|
c.gridx = 0;
|
||||||
|
c.gridy = 0;
|
||||||
|
c.weightx = 1;
|
||||||
|
c.fill = GridBagConstraints.HORIZONTAL;
|
||||||
|
|
||||||
|
mainProgressBar = new SmoothProgressBar(0);
|
||||||
|
mainProgressBar.setPreferredSize(new Dimension(420, 26));
|
||||||
|
mainProgressBar.setAccentColor(accentColor);
|
||||||
|
|
||||||
|
subProgressBar = new SmoothProgressBar(0);
|
||||||
|
subProgressBar.setPreferredSize(new Dimension(420, 18));
|
||||||
|
subProgressBar.setAccentColor(new Color(0x6EE7FF));
|
||||||
|
subProgressBar.setShowStripe(true);
|
||||||
|
|
||||||
|
center.add(mainProgressBar, c);
|
||||||
|
c.gridy++;
|
||||||
|
c.insets = new Insets(8, 0, 0, 0);
|
||||||
|
center.add(subProgressBar, c);
|
||||||
|
|
||||||
|
// 底部文本
|
||||||
|
JPanel bottom = new JPanel(new BorderLayout());
|
||||||
|
bottom.setOpaque(false);
|
||||||
|
statusLabel = new JLabel("Initializing...", SwingConstants.LEFT);
|
||||||
|
statusLabel.setFont(uiFont.deriveFont(Font.PLAIN, 12f));
|
||||||
|
statusLabel.setForeground(new Color(220, 230, 240));
|
||||||
|
|
||||||
|
timeLabel = new JLabel("Elapsed: 0s", SwingConstants.RIGHT);
|
||||||
|
timeLabel.setFont(uiFont.deriveFont(Font.PLAIN, 12f));
|
||||||
|
timeLabel.setForeground(new Color(180, 200, 215));
|
||||||
|
|
||||||
|
bottom.add(statusLabel, BorderLayout.WEST);
|
||||||
|
bottom.add(timeLabel, BorderLayout.EAST);
|
||||||
|
bottom.setBorder(BorderFactory.createEmptyBorder(8, 2, 2, 2));
|
||||||
|
|
||||||
|
card.add(top, BorderLayout.NORTH);
|
||||||
|
card.add(center, BorderLayout.CENTER);
|
||||||
|
card.add(bottom, BorderLayout.SOUTH);
|
||||||
|
|
||||||
|
root.add(card);
|
||||||
|
loadingFrame.setContentPane(root);
|
||||||
|
|
||||||
|
// 拖动窗口支持(在无边框下)
|
||||||
|
WindowDragger.makeDraggable(loadingFrame, card);
|
||||||
|
|
||||||
|
// 启动动画定时器
|
||||||
|
animationTimer = new Timer(1000 / 60, e -> {
|
||||||
|
boolean repaintNeeded = false;
|
||||||
|
if (mainProgressBar.animateStep()) repaintNeeded = true;
|
||||||
|
if (subProgressBar.animateStep()) repaintNeeded = true;
|
||||||
|
root.advanceAnimation();
|
||||||
|
updateTimeLabel();
|
||||||
|
if (repaintNeeded) {
|
||||||
|
root.repaint();
|
||||||
|
} else {
|
||||||
|
// 仍需刷新背景动画
|
||||||
|
root.repaint();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
animationTimer.start();
|
||||||
|
|
||||||
loadingFrame.add(loadingPanel);
|
|
||||||
loadingFrame.setVisible(true);
|
loadingFrame.setVisible(true);
|
||||||
|
|
||||||
|
// 防止用户误操作关闭(保持原行为)
|
||||||
|
loadingFrame.addWindowListener(new WindowAdapter() {
|
||||||
|
@Override
|
||||||
|
public void windowClosing(WindowEvent e) {
|
||||||
|
// DO NOTHING
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新主任务进度
|
* 更新主任务进度(对外接口保持不变)
|
||||||
* @param completedTasks 已完成的主任务数量
|
* @param completedTasks 已完成的主任务数量
|
||||||
*/
|
*/
|
||||||
public void updateMainProgress(int completedTasks) {
|
public void updateMainProgress(int completedTasks) {
|
||||||
this.completedTasks = completedTasks;
|
this.completedTasks = completedTasks;
|
||||||
int progress = (int) ((completedTasks / (double) totalTasks) * 100);
|
double progress = (completedTasks / (double) Math.max(1, totalTasks)) * 100.0;
|
||||||
mainProgressBar.setValue(progress);
|
if (progress < 0) progress = 0;
|
||||||
statusLabel.setText("Main Progress: " + progress + "%");
|
if (progress > 100) progress = 100;
|
||||||
updateTimeLabel();
|
mainProgressBar.setTarget((int) Math.round(progress));
|
||||||
|
statusLabel.setText("主任务: " + completedTasks + " / " + totalTasks + " (" + (int) progress + "%)");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新子任务进度
|
* 更新子任务进度(对外接口保持不变)
|
||||||
* @param subTaskName 子任务名称
|
* @param subTaskName 子任务名称
|
||||||
* @param subTaskCompleted 已完成的子任务数量
|
* @param subTaskCompleted 已完成的子任务数量
|
||||||
* @param subTaskTotal 子任务总数
|
* @param subTaskTotal 子任务总数
|
||||||
*/
|
*/
|
||||||
public void updateSubProgress(String subTaskName, int subTaskCompleted, int subTaskTotal) {
|
public void updateSubProgress(String subTaskName, int subTaskCompleted, int subTaskTotal) {
|
||||||
|
if (subTaskTotal <= 0) subTaskTotal = 1;
|
||||||
subTasks.put(subTaskName, subTaskCompleted);
|
subTasks.put(subTaskName, subTaskCompleted);
|
||||||
int progress = (int) ((subTaskCompleted / (double) subTaskTotal) * 100);
|
double progress = (subTaskCompleted / (double) subTaskTotal) * 100.0;
|
||||||
subProgressBar.setValue(progress);
|
if (progress < 0) progress = 0;
|
||||||
subProgressBar.setString(subTaskName + ": " + progress + "%");
|
if (progress > 100) progress = 100;
|
||||||
updateTimeLabel();
|
subProgressBar.setTarget((int) Math.round(progress));
|
||||||
|
subProgressBar.setLabel(subTaskName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新总任务数
|
* 更新总任务数
|
||||||
*/
|
*/
|
||||||
public void setTotalTasks(int totalTasks) {
|
public void setTotalTasks(int totalTasks) {
|
||||||
this.totalTasks = totalTasks;
|
this.totalTasks = Math.max(1, totalTasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 关闭加载窗口
|
* 关闭加载窗口
|
||||||
*/
|
*/
|
||||||
public void close() {
|
public void close() {
|
||||||
|
if (animationTimer != null && animationTimer.isRunning()) {
|
||||||
|
animationTimer.stop();
|
||||||
|
}
|
||||||
loadingFrame.dispose();
|
loadingFrame.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,6 +234,229 @@ public class ProgressBarManager extends WindowsJDialog {
|
|||||||
*/
|
*/
|
||||||
private void updateTimeLabel() {
|
private void updateTimeLabel() {
|
||||||
long elapsedTime = (System.currentTimeMillis() - startTime) / 1000;
|
long elapsedTime = (System.currentTimeMillis() - startTime) / 1000;
|
||||||
timeLabel.setText("Time elapsed: " + elapsedTime + "s");
|
long hours = elapsedTime / 3600;
|
||||||
|
long mins = (elapsedTime % 3600) / 60;
|
||||||
|
long secs = elapsedTime % 60;
|
||||||
|
if (hours > 0) {
|
||||||
|
timeLabel.setText(String.format("Elapsed: %dh %02dm %02ds", hours, mins, secs));
|
||||||
|
} else if (mins > 0) {
|
||||||
|
timeLabel.setText(String.format("Elapsed: %dm %02ds", mins, secs));
|
||||||
|
} else {
|
||||||
|
timeLabel.setText(String.format("Elapsed: %ds", secs));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// --------------------------
|
||||||
|
// 内部类:平滑进度条(支持插值动画、条纹、标签)
|
||||||
|
// --------------------------
|
||||||
|
private static class SmoothProgressBar extends JComponent {
|
||||||
|
private int target = 0;
|
||||||
|
private double displayed = 0.0;
|
||||||
|
private int height = 20;
|
||||||
|
private Color base = new Color(255, 255, 255, 18);
|
||||||
|
private Color fill = new Color(0x00C2FF);
|
||||||
|
private String label = "";
|
||||||
|
private boolean showStripe = false;
|
||||||
|
private Color stripeColor = new Color(255, 255, 255, 30);
|
||||||
|
private double stripeOffset = 0.0;
|
||||||
|
|
||||||
|
public SmoothProgressBar(int initial) {
|
||||||
|
this.target = Math.max(0, Math.min(100, initial));
|
||||||
|
this.displayed = this.target;
|
||||||
|
setOpaque(false);
|
||||||
|
setPreferredSize(new Dimension(200, height));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccentColor(Color c) {
|
||||||
|
this.fill = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLabel(String label) {
|
||||||
|
this.label = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setShowStripe(boolean v) {
|
||||||
|
this.showStripe = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTarget(int t) {
|
||||||
|
t = Math.max(0, Math.min(100, t));
|
||||||
|
this.target = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 每帧推进插值,返回是否需要重绘
|
||||||
|
*/
|
||||||
|
public boolean animateStep() {
|
||||||
|
// 平滑插值(阻尼)
|
||||||
|
double diff = target - displayed;
|
||||||
|
if (Math.abs(diff) < 0.02) {
|
||||||
|
displayed = target;
|
||||||
|
} else {
|
||||||
|
displayed += diff * 0.18; // 阻尼因子(调整流畅度)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 条纹动画
|
||||||
|
if (showStripe) {
|
||||||
|
stripeOffset += 1.8;
|
||||||
|
if (stripeOffset > 60) stripeOffset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 是否需要重绘
|
||||||
|
return Math.abs(diff) > 0.001 || showStripe;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintComponent(Graphics g) {
|
||||||
|
int w = getWidth();
|
||||||
|
int h = getHeight();
|
||||||
|
Graphics2D g2 = (Graphics2D) g.create();
|
||||||
|
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
|
|
||||||
|
// 背景轨道
|
||||||
|
RoundRectangle2D bg = new RoundRectangle2D.Float(0, 0, w, h, h, h);
|
||||||
|
g2.setColor(base);
|
||||||
|
g2.fill(bg);
|
||||||
|
|
||||||
|
// 阴影(内阴影模拟)
|
||||||
|
g2.setColor(new Color(0, 0, 0, 30));
|
||||||
|
g2.setStroke(new BasicStroke(1f));
|
||||||
|
g2.draw(bg);
|
||||||
|
|
||||||
|
// 填充(渐变)
|
||||||
|
int fillW = (int) Math.round((displayed / 100.0) * w);
|
||||||
|
if (fillW > 0) {
|
||||||
|
GradientPaint gp = new GradientPaint(0, 0, fill.brighter(), w, 0, fill.darker());
|
||||||
|
RoundRectangle2D fg = new RoundRectangle2D.Float(0, 0, fillW, h, h, h);
|
||||||
|
g2.setPaint(gp);
|
||||||
|
g2.fill(fg);
|
||||||
|
|
||||||
|
// 发光边缘
|
||||||
|
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.25f));
|
||||||
|
g2.setColor(fill);
|
||||||
|
g2.fill(new RoundRectangle2D.Float(0, -h / 3f, fillW, h + h / 3f, h, h));
|
||||||
|
g2.setComposite(AlphaComposite.SrcOver);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 条纹效果
|
||||||
|
if (showStripe && fillW > 6) {
|
||||||
|
Shape clip = g2.getClip();
|
||||||
|
g2.setClip(new RoundRectangle2D.Float(0, 0, fillW, h, h, h));
|
||||||
|
int stripeW = 18;
|
||||||
|
for (int x = -stripeW * 2; x < w + stripeW * 2; x += stripeW) {
|
||||||
|
int sx = (int) (x + stripeOffset);
|
||||||
|
Polygon p = new Polygon();
|
||||||
|
p.addPoint(sx, 0);
|
||||||
|
p.addPoint(sx + stripeW, 0);
|
||||||
|
p.addPoint(sx + stripeW - 8, h);
|
||||||
|
p.addPoint(sx - 8, h);
|
||||||
|
g2.setColor(stripeColor);
|
||||||
|
g2.fill(p);
|
||||||
|
}
|
||||||
|
g2.setClip(clip);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文本显示(居中)
|
||||||
|
String text;
|
||||||
|
if (label != null && !label.isEmpty()) {
|
||||||
|
text = label + " " + Math.round(displayed) + "%";
|
||||||
|
} else {
|
||||||
|
text = Math.round(displayed) + "%";
|
||||||
|
}
|
||||||
|
g2.setFont(new Font(Font.SANS_SERIF, Font.BOLD, Math.max(11, h - 6)));
|
||||||
|
FontMetrics fm = g2.getFontMetrics();
|
||||||
|
int tx = (w - fm.stringWidth(text)) / 2;
|
||||||
|
int ty = (h + fm.getAscent() - fm.getDescent()) / 2;
|
||||||
|
g2.setColor(new Color(255, 255, 255, 210));
|
||||||
|
g2.drawString(text, tx, ty);
|
||||||
|
|
||||||
|
g2.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------
|
||||||
|
// 内部类:带动画效果的背景面板(流动扫描线 + 颗粒/渐变)
|
||||||
|
// --------------------------
|
||||||
|
private class AnimatedBackgroundPanel extends JPanel {
|
||||||
|
private double offset = 0;
|
||||||
|
private double particlePhase = 0;
|
||||||
|
|
||||||
|
public AnimatedBackgroundPanel() {
|
||||||
|
setOpaque(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void advanceAnimation() {
|
||||||
|
offset += 0.9;
|
||||||
|
if (offset > 2000) offset = 0;
|
||||||
|
particlePhase += 0.02;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintComponent(Graphics g) {
|
||||||
|
int w = getWidth();
|
||||||
|
int h = getHeight();
|
||||||
|
Graphics2D g2 = (Graphics2D) g.create();
|
||||||
|
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
|
|
||||||
|
// 背景渐变(深色)
|
||||||
|
Paint p = new GradientPaint(0, 0, new Color(8, 10, 12), w, h, new Color(18, 20, 24));
|
||||||
|
g2.setPaint(p);
|
||||||
|
g2.fillRect(0, 0, w, h);
|
||||||
|
|
||||||
|
// 斜向扫描线(细微)
|
||||||
|
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.06f));
|
||||||
|
g2.setColor(Color.WHITE);
|
||||||
|
for (int i = -200; i < w + h; i += 40) {
|
||||||
|
int x1 = i + (int) offset;
|
||||||
|
int y1 = 0;
|
||||||
|
int x2 = i - h + (int) offset;
|
||||||
|
int y2 = h;
|
||||||
|
g2.setStroke(new BasicStroke(2f));
|
||||||
|
g2.drawLine(x1, y1, x2, y2);
|
||||||
|
}
|
||||||
|
g2.setComposite(AlphaComposite.SrcOver);
|
||||||
|
|
||||||
|
// 轻微颗粒(科技光斑)
|
||||||
|
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.08f));
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
float px = (float) ((Math.sin(particlePhase + i) + 1) / 2.0 * w);
|
||||||
|
float py = (float) ((Math.cos(particlePhase * 0.7 + i * 0.3) + 1) / 2.0 * h);
|
||||||
|
int size = 6 + (i % 3) * 4;
|
||||||
|
g2.fillOval((int) px, (int) py, size, size);
|
||||||
|
}
|
||||||
|
g2.setComposite(AlphaComposite.SrcOver);
|
||||||
|
|
||||||
|
g2.dispose();
|
||||||
|
super.paintComponent(g);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------
|
||||||
|
// 工具:使无边框窗口可拖动
|
||||||
|
// --------------------------
|
||||||
|
private static class WindowDragger {
|
||||||
|
public static void makeDraggable(Window wnd, Component dragRegion) {
|
||||||
|
final Point[] mouseDown = {null};
|
||||||
|
dragRegion.addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
mouseDown[0] = e.getPoint();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseReleased(MouseEvent e) {
|
||||||
|
mouseDown[0] = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
dragRegion.addMouseMotionListener(new MouseMotionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mouseDragged(MouseEvent e) {
|
||||||
|
if (mouseDown[0] != null) {
|
||||||
|
Point curr = e.getLocationOnScreen();
|
||||||
|
wnd.setLocation(curr.x - mouseDown[0].x, curr.y - mouseDown[0].y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user