feat(system-tools): 添加任务栏外观设置工具

- 新增 LocalCall 类实现任务栏外观设置功能- 添加 TaskbarAppearanceWindow 界面类
- 在 MainWindow 中集成任务栏主题设置工具
-优化图标路径处理逻辑
This commit is contained in:
tzdwindows 7
2025-08-19 12:37:50 +08:00
parent 5df14e353a
commit e6df4fe4b2
7 changed files with 823 additions and 13 deletions

View File

@@ -6,6 +6,7 @@ import com.axis.innovators.box.window.FridaWindow;
import com.axis.innovators.box.window.JarApiProfilingWindow;
import com.axis.innovators.box.window.MainWindow;
import com.axis.innovators.box.plugins.PluginDescriptor;
import com.axis.innovators.box.window.TaskbarAppearanceWindow;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.tzd.lm.LM;
@@ -47,7 +48,6 @@ public class RegistrationTool {
}
}));
MainWindow.ToolCategory programmingToolsCategory = new MainWindow.ToolCategory("编程工具",
"programming/programming.png",
"编程工具");
@@ -108,9 +108,23 @@ public class RegistrationTool {
}
}));
MainWindow.ToolCategory systemCategory = new MainWindow.ToolCategory("系统工具",
"windows/windows.png",
"系统工具");
systemCategory.addTool(new MainWindow.ToolItem("任务栏主题设置", "windows/windowsOptimization/windowsOptimization.png",
"可以设置Windows任务栏的颜色等各种信息",++id, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
Window owner = SwingUtilities.windowForComponent((Component) e.getSource());
TaskbarAppearanceWindow taskbarAppearanceWindow = new TaskbarAppearanceWindow(owner);
main.popupWindow(taskbarAppearanceWindow);
}
}));
addToolCategory(debugCategory, "system:debugTools");
addToolCategory(aICategory,"system:fridaTools");
addToolCategory(programmingToolsCategory, "system:programmingTools");
addToolCategory(systemCategory, "system:systemTools");
}
/**

View File

@@ -1186,14 +1186,7 @@ public class MainWindow extends JFrame {
public String getDescription() { return description; }
public String getIcon() {
if (isDarkTheme()) {
int lastDotIndex = 0;
if (icon != null) {
lastDotIndex = icon.lastIndexOf('.');
}
if (lastDotIndex > 0) {
return icon.substring(0, lastDotIndex) + "_dark" + icon.substring(lastDotIndex);
}
return icon + "_dark";
return icon.replace(".png", "_dark.png");
}
return icon;
}

View File

@@ -0,0 +1,657 @@
package com.axis.innovators.box.window;
import com.axis.innovators.box.window.WindowsJDialog;
import org.tzd.explorer.LocalCall;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.geom.Point2D;
import java.awt.RadialGradientPaint;
import java.io.IOException;
import java.util.Map;
/**
* @author tzdwindows 7
*/
public class TaskbarAppearanceWindow extends WindowsJDialog {
private final JComboBox<LocalCall.TaskbarAccentMode> modeCombo;
private final JButton colorButton;
private final JSlider alphaSlider;
private final JButton applyButton;
private final JButton helpButton;
private final PreviewPanel previewPanel;
private final JButton sysTextColorButton;
private final JButton applySysTextColorButton;
private Color sysTextColor = Color.BLACK;
// 动画平滑过渡参数
private Color currentColor = new Color(0, 0, 0);
private Color targetColor = new Color(0, 0, 0);
private int currentAlpha = 255; // 用于动画(实际 0-255
private int targetAlpha = 255; // 用于动画(实际 0-255
private LocalCall.TaskbarAccentMode currentMode = LocalCall.TaskbarAccentMode.ACCENT_DISABLED;
private LocalCall.TaskbarAccentMode targetMode = LocalCall.TaskbarAccentMode.ACCENT_DISABLED;
private Timer animationTimer = new Timer(16, e -> {});
// UI 元素引用(需要动态修改标签)
private JPanel alphaLabeledPanel;
private JLabel alphaLabel;
private static final Map<LocalCall.TaskbarAccentMode, String> MODE_LABELS = Map.of(
LocalCall.TaskbarAccentMode.ACCENT_DISABLED, "禁用特效(无额外效果)",
LocalCall.TaskbarAccentMode.ACCENT_ENABLE_GRADIENT, "渐变(纯色/渐变)",
LocalCall.TaskbarAccentMode.ACCENT_ENABLE_TRANSPARENTGRADIENT, "透明渐变(半透明)",
LocalCall.TaskbarAccentMode.ACCENT_ENABLE_BLURBEHIND, "毛玻璃模糊(高档模糊)",
LocalCall.TaskbarAccentMode.ACCENT_ENABLE_ACRYLICBLURBEHIND, "亚克力模糊Fluent 风格)",
LocalCall.TaskbarAccentMode.ACCENT_INVALID_STATE, "无效状态(保留)"
);
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
TaskbarAppearanceWindow w = new TaskbarAppearanceWindow(null);
w.setVisible(true);
});
}
public TaskbarAppearanceWindow(Window owner) {
super(owner, "任务栏外观设置", ModalityType.MODELESS);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
// 基本窗口设置
setSize(1220, 750);
setLocationRelativeTo(owner);
((JComponent) getContentPane()).setBorder(new EmptyBorder(12, 12, 12, 12));
setLayout(new BorderLayout(12, 12));
// 顶部标题
JPanel top = new JPanel(new BorderLayout());
top.setOpaque(false);
JLabel header = new JLabel("任务栏外观 - 高级设置");
header.setFont(header.getFont().deriveFont(Font.BOLD, 18f));
JLabel sub = new JLabel("可实时预览任务栏效果。");
sub.setFont(sub.getFont().deriveFont(12f));
top.add(header, BorderLayout.NORTH);
top.add(sub, BorderLayout.SOUTH);
add(top, BorderLayout.NORTH);
// 左侧:控制区
JPanel left = new JPanel();
left.setLayout(new BoxLayout(left, BoxLayout.Y_AXIS));
left.setOpaque(false);
left.setPreferredSize(new Dimension(400, getHeight()));
left.setMaximumSize(new Dimension(420, Integer.MAX_VALUE));
left.setBorder(new EmptyBorder(6, 6, 6, 6));
// 模式选择
modeCombo = new JComboBox<>(LocalCall.TaskbarAccentMode.values());
modeCombo.setMaximumSize(new Dimension(Integer.MAX_VALUE, 34));
modeCombo.setRenderer((list, value, index, isSelected, cellHasFocus) -> {
JLabel lab = new JLabel();
if (value instanceof LocalCall.TaskbarAccentMode) {
LocalCall.TaskbarAccentMode m = (LocalCall.TaskbarAccentMode) value;
lab.setText(MODE_LABELS.getOrDefault(m, m.name()));
} else {
lab.setText(String.valueOf(value));
}
lab.setOpaque(isSelected);
if (isSelected) {
lab.setBackground(new Color(0, 120, 215, 40));
}
lab.setBorder(new EmptyBorder(4, 4, 4, 4));
return lab;
});
left.add(labeledComponent("模式", modeCombo));
left.add(Box.createVerticalStrut(10));
// 颜色选择
colorButton = new JButton("选择任务栏颜色");
colorButton.setMaximumSize(new Dimension(Integer.MAX_VALUE, 34));
colorButton.setPreferredSize(new Dimension(200, 32));
colorButton.setFocusPainted(false);
colorButton.addActionListener(e -> {
Color chosen = JColorChooser.showDialog(this, "选择任务栏颜色", targetColor);
if (chosen != null) {
setTargetColor(chosen);
}
});
left.add(labeledComponent("颜色", colorButton));
left.add(Box.createVerticalStrut(10));
// alpha 滑块(我们要能动态修改其标签和范围)
alphaSlider = new JSlider(0, 255, 255);
alphaSlider.setMajorTickSpacing(64);
alphaSlider.setMinorTickSpacing(16);
alphaSlider.setPaintTicks(true);
alphaSlider.setPaintLabels(true);
alphaSlider.setMaximumSize(new Dimension(Integer.MAX_VALUE, 64));
alphaSlider.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
// 根据当前模式决定如何解释滑块值如果是毛玻璃degree 0-64映射到 0-255否则直接为 alpha
int v = alphaSlider.getValue();
if (targetMode == LocalCall.TaskbarAccentMode.ACCENT_ENABLE_BLURBEHIND) {
// degree -> alpha (scale 0-64 to 0-255)
float ratio = Math.max(0f, Math.min(1f, v / 64f));
targetAlpha = Math.round(ratio * 255f);
} else {
targetAlpha = clamp(v);
}
targetSliderChanged(v);
}
});
// 用一个可变标签面板包裹
alphaLabeledPanel = createAlphaLabeledPanel("不透明度 (Alpha)", alphaSlider);
left.add(alphaLabeledPanel);
left.add(Box.createVerticalStrut(10));
// 去掉字节序提示(按要求删除)
// left.add(Box.createVerticalStrut(10)); // 不再添加提示
// 按钮行
JPanel btnRow = new JPanel(new FlowLayout(FlowLayout.RIGHT, 8, 0));
btnRow.setOpaque(false);
applyButton = new JButton("应用到任务栏");
helpButton = new JButton("查看帮助");
Dimension smallBtn = new Dimension(140, 30);
applyButton.setPreferredSize(smallBtn);
helpButton.setPreferredSize(smallBtn);
applyButton.setMaximumSize(smallBtn);
helpButton.setMaximumSize(smallBtn);
applyButton.setFocusable(false);
helpButton.setFocusable(false);
applyButton.setMargin(new Insets(6, 10, 6, 10));
helpButton.setMargin(new Insets(6, 10, 6, 10));
btnRow.add(helpButton);
btnRow.add(applyButton);
btnRow.setAlignmentX(Component.LEFT_ALIGNMENT);
left.add(btnRow);
left.add(Box.createVerticalStrut(14));
// 系统文字颜色(实验性)
sysTextColorButton = new JButton("选择系统文字颜色");
sysTextColorButton.setMaximumSize(new Dimension(Integer.MAX_VALUE, 34));
sysTextColorButton.setPreferredSize(new Dimension(180, 30));
sysTextColorButton.setBackground(sysTextColor);
sysTextColorButton.setForeground(contrast(sysTextColor));
sysTextColorButton.setFocusPainted(false);
sysTextColorButton.addActionListener(e -> {
Color chosen = JColorChooser.showDialog(this, "选择要设置的系统文字颜色", sysTextColor);
if (chosen != null) {
sysTextColor = chosen;
sysTextColorButton.setBackground(sysTextColor);
sysTextColorButton.setForeground(contrast(sysTextColor));
}
});
left.add(labeledComponent("系统文字颜色(实验性)", sysTextColorButton));
left.add(Box.createVerticalStrut(8));
applySysTextColorButton = new JButton("应用系统文字颜色(修改注册表)");
applySysTextColorButton.setAlignmentX(Component.LEFT_ALIGNMENT);
applySysTextColorButton.setPreferredSize(new Dimension(220, 30));
applySysTextColorButton.setMaximumSize(new Dimension(Integer.MAX_VALUE, 34));
applySysTextColorButton.setFocusPainted(false);
left.add(applySysTextColorButton);
left.add(Box.createVerticalGlue());
// 右侧:实时预览区
previewPanel = new PreviewPanel();
previewPanel.setPreferredSize(new Dimension(720, 520));
JPanel previewWrap = new JPanel(new BorderLayout());
previewWrap.setBorder(BorderFactory.createTitledBorder("实时预览"));
previewWrap.add(previewPanel, BorderLayout.CENTER);
// 主布局
JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, left, previewWrap);
split.setResizeWeight(0);
split.setDividerLocation(420);
split.setOneTouchExpandable(false);
add(split, BorderLayout.CENTER);
// 事件绑定:模式切换时更新控件状态
modeCombo.addActionListener(e -> {
LocalCall.TaskbarAccentMode sel = (LocalCall.TaskbarAccentMode) modeCombo.getSelectedItem();
if (sel != null) {
setTargetMode(sel);
updateControlsForMode(sel);
}
});
// apply 按钮行为(在后台线程执行 LocalCall
applyButton.addActionListener(e -> {
setControlsEnabled(false);
LocalCall.TaskbarAccentMode mode = targetMode;
String colorArg = buildColorArg(targetColor); // 0xRRGGBB
int alphaToSend = targetAlpha; // targetAlpha 已经是 0-255如果毛玻璃按 degree 映射)
boolean restartExplorerAlways = false;
if (mode == LocalCall.TaskbarAccentMode.ACCENT_INVALID_STATE) {
restartExplorerAlways = true;
}
boolean finalRestartExplorerAlways = restartExplorerAlways;
SwingWorker<Void, Void> worker = new SwingWorker<>() {
Exception ex = null;
@Override
protected Void doInBackground() {
try {
LocalCall.setTaskbarAppearance(mode, colorArg, alphaToSend, finalRestartExplorerAlways);
} catch (IOException | InterruptedException e1) {
ex = e1;
}
return null;
}
@Override
protected void done() {
setControlsEnabled(true);
if (ex != null) {
JOptionPane.showMessageDialog(TaskbarAppearanceWindow.this,
"应用到任务栏失败: " + ex.getMessage(),
"错误", JOptionPane.ERROR_MESSAGE);
} else {
JOptionPane.showMessageDialog(TaskbarAppearanceWindow.this,
"已尝试应用设置。若未生效可能需要 Explorer 重启或注销。", "完成",
JOptionPane.INFORMATION_MESSAGE);
}
}
};
worker.execute();
});
// 帮助按钮
helpButton.addActionListener(e -> {
SwingWorker<Void, Void> w = new SwingWorker<>() {
Exception ex = null;
@Override
protected Void doInBackground() {
try {
LocalCall.showTaskbarHelp();
} catch (IOException | InterruptedException ioException) {
ex = ioException;
}
return null;
}
@Override
protected void done() {
if (ex != null) {
JOptionPane.showMessageDialog(TaskbarAppearanceWindow.this,
"调用帮助失败:" + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
}
}
};
w.execute();
});
// 应用系统文字颜色
applySysTextColorButton.addActionListener(e -> {
applySysTextColorButton.setEnabled(false);
sysTextColorButton.setEnabled(false);
SwingWorker<Void, Void> worker = new SwingWorker<>() {
Exception ex = null;
@Override
protected Void doInBackground() {
try {
setWindowsTextColor(sysTextColor);
} catch (IOException | InterruptedException ioException) {
ex = ioException;
}
return null;
}
@Override
protected void done() {
applySysTextColorButton.setEnabled(true);
sysTextColorButton.setEnabled(true);
if (ex != null) {
JOptionPane.showMessageDialog(TaskbarAppearanceWindow.this,
"应用系统文字颜色失败:" + ex.getMessage(),
"错误", JOptionPane.ERROR_MESSAGE);
} else {
JOptionPane.showMessageDialog(TaskbarAppearanceWindow.this,
"已尝试修改注册表并刷新用户外观参数(可能需要注销/重启以完全生效)。",
"提示", JOptionPane.INFORMATION_MESSAGE);
}
}
};
worker.execute();
});
// 双击预览快速体验
previewPanel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
modeCombo.setSelectedItem(LocalCall.TaskbarAccentMode.ACCENT_ENABLE_BLURBEHIND);
// 设置滑块为中等程度示例
alphaSlider.setValue(32);
applyButton.doClick();
}
}
});
// 初始化目标并启动动画 Timer
setTargetColor(currentColor);
// 初始化 slider 为 255默认
alphaSlider.setValue(255);
// 默认模式更新 UI
updateControlsForMode(currentMode);
animationTimer = new Timer(16, e -> {
boolean changed = false;
int rCur = currentColor.getRed(), gCur = currentColor.getGreen(), bCur = currentColor.getBlue();
int rT = targetColor.getRed(), gT = targetColor.getGreen(), bT = targetColor.getBlue();
int rNew = lerp(rCur, rT, 0.12f);
int gNew = lerp(gCur, gT, 0.12f);
int bNew = lerp(bCur, bT, 0.12f);
Color newColor = new Color(clamp(rNew), clamp(gNew), clamp(bNew));
if (!newColor.equals(currentColor)) {
currentColor = newColor;
changed = true;
}
int aNew = lerp(currentAlpha, targetAlpha, 0.14f);
if (aNew != currentAlpha) {
currentAlpha = aNew;
changed = true;
}
if (currentMode != targetMode) {
if (Math.abs(currentAlpha - targetAlpha) < 3 &&
Math.abs(currentColor.getRed() - targetColor.getRed()) < 3 &&
Math.abs(currentColor.getGreen() - targetColor.getGreen()) < 3 &&
Math.abs(currentColor.getBlue() - targetColor.getBlue()) < 3) {
currentMode = targetMode;
changed = true;
}
}
if (changed) {
previewPanel.setPreviewState(currentColor, currentAlpha, currentMode);
} else {
animationTimer.stop();
}
});
}
// Enable / disable 控件
private void setControlsEnabled(boolean enabled) {
// 模式选择保持可用(用户可以改变)
modeCombo.setEnabled(true);
//applyButton.setEnabled(enabled);
helpButton.setEnabled(enabled);
colorButton.setEnabled(enabled && targetMode != LocalCall.TaskbarAccentMode.ACCENT_ENABLE_BLURBEHIND
&& targetMode != LocalCall.TaskbarAccentMode.ACCENT_INVALID_STATE);
alphaSlider.setEnabled(enabled && targetMode != LocalCall.TaskbarAccentMode.ACCENT_INVALID_STATE);
applySysTextColorButton.setEnabled(enabled);
sysTextColorButton.setEnabled(enabled);
}
// 带标签的组件包装(左对齐)
private JPanel labeledComponent(String label, JComponent comp) {
JPanel p = new JPanel();
p.setLayout(new BorderLayout(8, 8));
p.setOpaque(false);
JLabel l = new JLabel(label);
l.setPreferredSize(new Dimension(140, 24));
p.add(l, BorderLayout.WEST);
p.add(comp, BorderLayout.CENTER);
p.setAlignmentX(Component.LEFT_ALIGNMENT);
return p;
}
// 创建 alpha 带可变标签的面板
private JPanel createAlphaLabeledPanel(String labelText, JComponent comp) {
JPanel p = new JPanel(new BorderLayout(8, 8));
p.setOpaque(false);
alphaLabel = new JLabel(labelText);
alphaLabel.setPreferredSize(new Dimension(140, 24));
p.add(alphaLabel, BorderLayout.WEST);
p.add(comp, BorderLayout.CENTER);
p.setAlignmentX(Component.LEFT_ALIGNMENT);
return p;
}
private void setTargetColor(Color c) {
if (c == null) return;
targetColor = c;
colorButton.setBackground(c);
colorButton.setForeground(contrast(c));
previewPanel.setPreviewState(targetColor, targetAlpha, targetMode);
startAnimationIfNeeded();
}
// 当滑块值改变v 为滑块上的值:可能是 0-255 或 0-64
private void targetSliderChanged(int v) {
// 更新预览targetAlpha 已在 ChangeListener 中计算)
previewPanel.setPreviewState(targetColor, targetAlpha, targetMode);
startAnimationIfNeeded();
}
private void setTargetMode(LocalCall.TaskbarAccentMode mode) {
if (mode == null) return;
targetMode = mode;
// 如果进入毛玻璃模式,确保 targetAlpha 基于当前 slider映射
if (targetMode == LocalCall.TaskbarAccentMode.ACCENT_ENABLE_BLURBEHIND) {
int degree = alphaSlider.getValue();
float ratio = Math.max(0f, Math.min(1f, degree / 64f));
targetAlpha = Math.round(ratio * 255f);
}
previewPanel.setPreviewState(targetColor, targetAlpha, targetMode);
startAnimationIfNeeded();
}
private void updateControlsForMode(LocalCall.TaskbarAccentMode mode) {
// 默认启用全部(模式选择除外)
boolean disableAll = (mode == LocalCall.TaskbarAccentMode.ACCENT_INVALID_STATE);
boolean isBlur = (mode == LocalCall.TaskbarAccentMode.ACCENT_ENABLE_BLURBEHIND);
// 如果无效状态:什么都不能设置(除模式之外)
colorButton.setEnabled(!disableAll && !isBlur);
sysTextColorButton.setEnabled(!disableAll);
applySysTextColorButton.setEnabled(!disableAll);
helpButton.setEnabled(!disableAll);
//applyButton.setEnabled(!disableAll);
// 配置滑块范围与标签
if (isBlur) {
// 毛玻璃:滑块行为为 程度 0-64
alphaLabel.setText("程度 (0-64)");
alphaSlider.setMinimum(0);
alphaSlider.setMaximum(64);
alphaSlider.setMajorTickSpacing(16);
alphaSlider.setMinorTickSpacing(4);
alphaSlider.setPaintLabels(true);
// 如果之前值超范围则设置为上限
if (alphaSlider.getValue() > 64) alphaSlider.setValue(32);
// 计算 targetAlpha映射到 0-255
int degree = alphaSlider.getValue();
float ratio = Math.max(0f, Math.min(1f, degree / 64f));
targetAlpha = Math.round(ratio * 255f);
} else {
// 常规模式:不透明度 0-255
alphaLabel.setText("不透明度 (Alpha)");
alphaSlider.setMinimum(0);
alphaSlider.setMaximum(255);
alphaSlider.setMajorTickSpacing(64);
alphaSlider.setMinorTickSpacing(16);
alphaSlider.setPaintLabels(true);
// 若当前 slider 值超过 255调整
if (alphaSlider.getValue() > 255) alphaSlider.setValue(255);
targetAlpha = clamp(alphaSlider.getValue());
}
// 预览和控件可用性
alphaSlider.setEnabled(!disableAll);
setControlsEnabled(!disableAll);
// 立即更新预览状态
previewPanel.setPreviewState(targetColor, targetAlpha, mode);
startAnimationIfNeeded();
}
private void startAnimationIfNeeded() {
if (!animationTimer.isRunning()) animationTimer.start();
}
private static int lerp(int a, int b, float t) {
return Math.round(a + (b - a) * t);
}
private static int clamp(int v) {
return Math.min(255, Math.max(0, v));
}
private static Color contrast(Color bg) {
double luminance = (0.299 * bg.getRed() + 0.587 * bg.getGreen() + 0.114 * bg.getBlue()) / 255.0;
return luminance > 0.6 ? Color.BLACK : Color.WHITE;
}
/**
* 构建传入本地工具的颜色字符串(固定为 0xRRGGBB
* 说明为避免字节序混淆Java 端始终发送 RGB不包含 alpha例如 #0099CC -> 0x0099CC
*/
private static String buildColorArg(Color c) {
if (c == null) return "0x000000";
int r = c.getRed();
int g = c.getGreen();
int b = c.getBlue();
return String.format("0x%02X%02X%02X", r, g, b);
}
/**
* 通过修改注册表设置系统文字颜色(实验性)
*/
private static void setWindowsTextColor(Color c) throws IOException, InterruptedException {
String rgb = String.format("%d %d %d", c.getRed(), c.getGreen(), c.getBlue());
String key = "HKCU\\Control Panel\\Colors";
String[] values = new String[]{"WindowText", "HilightText", "ButtonText"};
for (String v : values) {
String cmd = String.format("reg add \"%s\" /v %s /t REG_SZ /d \"%s\" /f", key, v, rgb);
Process p = Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", cmd});
p.waitFor();
}
Process refresh = Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c",
"RUNDLL32.EXE user32.dll,UpdatePerUserSystemParameters"});
refresh.waitFor();
}
/**
* 预览面板:绘制模拟任务栏效果(更现代的表现)
*/
private static class PreviewPanel extends JPanel {
private Color previewColor = new Color(0, 0, 0);
private int previewAlpha = 255;
private LocalCall.TaskbarAccentMode previewMode = LocalCall.TaskbarAccentMode.ACCENT_DISABLED;
PreviewPanel() {
setOpaque(true);
setBackground(new Color(0xF4F7FB));
}
void setPreviewState(Color color, int alpha, LocalCall.TaskbarAccentMode mode) {
this.previewColor = color != null ? color : new Color(0,0,0);
this.previewAlpha = clamp(alpha);
this.previewMode = mode != null ? mode : LocalCall.TaskbarAccentMode.ACCENT_DISABLED;
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int w = getWidth();
int h = getHeight();
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// 背景渐变
GradientPaint bg = new GradientPaint(0, 0, new Color(0xEAF3FF), 0, h, new Color(0xE6F0FF));
g2.setPaint(bg);
g2.fillRect(0, 0, w, h);
// 任务栏容器
int barH = Math.max(76, h / 6);
int barY = h - barH - 36;
int margin = 36;
int barX = margin;
int barW = w - margin * 2;
RoundRectangle2D.Float barRect = new RoundRectangle2D.Float(barX, barY, barW, barH, 18, 18);
// 根据模式绘制
switch (previewMode) {
case ACCENT_DISABLED:
Color solid = new Color(previewColor.getRed(), previewColor.getGreen(), previewColor.getBlue(),
Math.max(200, previewAlpha));
g2.setPaint(solid);
g2.fill(barRect);
break;
case ACCENT_ENABLE_GRADIENT:
case ACCENT_ENABLE_TRANSPARENTGRADIENT:
Color c1 = new Color(previewColor.getRed(), previewColor.getGreen(), previewColor.getBlue(),
Math.max(60, previewAlpha / 2));
Color c2 = new Color(clamp(previewColor.getRed() + 30), clamp(previewColor.getGreen() + 30),
clamp(previewColor.getBlue() + 30), Math.max(60, previewAlpha / 2));
GradientPaint gp = new GradientPaint(barX, barY, c1, barX + barW, barY + barH, c2);
g2.setPaint(gp);
g2.fill(barRect);
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.08f));
g2.fill(new RoundRectangle2D.Float(barX, barY, barW, barH / 2f, 16, 16));
g2.setComposite(AlphaComposite.SrcOver);
break;
case ACCENT_ENABLE_BLURBEHIND:
Color base = new Color(previewColor.getRed(), previewColor.getGreen(), previewColor.getBlue(),
Math.max(8, previewAlpha / 3));
g2.setPaint(base);
g2.fill(barRect);
Point2D center = new Point2D.Float(barX + barW / 2f, barY + barH / 2f);
float radius = Math.max(barW, barH);
RadialGradientPaint rgp = new RadialGradientPaint(center, radius,
new float[]{0f, 1f},
new Color[]{new Color(255, 255, 255, Math.min(100, previewAlpha / 2)),
new Color(0, 0, 0, Math.min(40, previewAlpha / 6))});
g2.setPaint(rgp);
g2.fill(barRect);
g2.setStroke(new BasicStroke(1.2f));
for (int i = 0; i < 5; i++) {
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.04f + i * 0.02f));
g2.draw(new RoundRectangle2D.Float(barX + i, barY + i, barW - i * 2f, barH - i * 2f, 16, 16));
}
g2.setComposite(AlphaComposite.SrcOver);
break;
case ACCENT_ENABLE_ACRYLICBLURBEHIND:
case ACCENT_INVALID_STATE:
default:
Color acr = new Color(previewColor.getRed(), previewColor.getGreen(), previewColor.getBlue(),
Math.max(20, previewAlpha / 2));
g2.setPaint(acr);
g2.fill(barRect);
GradientPaint spot = new GradientPaint(barX, barY, new Color(255, 255, 255, 140),
barX + barW / 2, barY + barH / 2, new Color(255, 255, 255, 0));
g2.setPaint(spot);
g2.fill(new RoundRectangle2D.Float(barX, barY, barW / 2f, barH, 16, 16));
for (int i = 0; i < barW; i += 10) {
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.03f));
g2.drawLine(barX + i, barY + 6, barX + i + 6, barY + barH - 6);
}
g2.setComposite(AlphaComposite.SrcOver);
break;
}
// 绘制图标占位
int iconY = barY + 14;
int iconSize = Math.min(36, barH - 28);
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.95f));
g2.setColor(new Color(255, 255, 255, 200));
g2.fillOval(barX + 16, iconY, iconSize, iconSize);
int trayX = barX + barW - 18 - (iconSize + 10) * 4;
for (int i = 0; i < 4; i++) {
int x = trayX + i * (iconSize + 10);
g2.fillRoundRect(x, iconY, iconSize, iconSize, 8, 8);
}
g2.dispose();
}
}
}

View File

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

View File

@@ -0,0 +1,150 @@
package org.tzd.explorer;
import com.axis.innovators.box.tools.FolderCreator;
import java.io.IOException;
/**
* @author tzdwindows 7
*/
public class LocalCall {
private static final String LIBRARY = FolderCreator.getLibraryFolder();
private static final String TASKBAR_EXE = "TaskbarTranslucentConsole.exe";
/**
* Enum representing the different taskbar accent modes
*/
public enum TaskbarAccentMode {
/** Disables any accent effect 需要将restartExplorer设置为真*/
@Description("Disables any accent effect")
ACCENT_DISABLED(0),
/** Enables gradient effect 纯色任务栏设置的alpha无效*/
@Description("Enables gradient effect")
ACCENT_ENABLE_GRADIENT(1),
/** Enables transparent gradient effect 纯色任务栏设置的alpha有效*/
@Description("Enables transparent gradient effect")
ACCENT_ENABLE_TRANSPARENTGRADIENT(2),
/** Enables blur behind effect (设置alpha为0可实现透明任务栏) */
@Description("Enables blur behind effect")
ACCENT_ENABLE_BLURBEHIND(3),
/** Enables acrylic blur behind effect (Windows 10 Fluent Design) 模糊设置的alpha无效*/
@Description("Enables acrylic blur behind effect (Windows 10 Fluent Design)")
ACCENT_ENABLE_ACRYLICBLURBEHIND(4),
/** Invalid state 需要将restartExplorer设置为真*/
@Description("Invalid state")
ACCENT_INVALID_STATE(5);
private final int value;
TaskbarAccentMode(int value) {
this.value = value;
}
public int getValue() {
return value;
}
/**
* Gets the enum value from an integer
* @param value The integer value to convert
* @return Corresponding TaskbarAccentMode
* @throws IllegalArgumentException if the value is invalid
*/
public static TaskbarAccentMode fromValue(int value) {
for (TaskbarAccentMode mode : values()) {
if (mode.value == value) {
return mode;
}
}
throw new IllegalArgumentException("Invalid TaskbarAccentMode value: " + value);
}
}
/**
* Changes the taskbar appearance
* @param mode The accent mode to apply
* @param color The color in hex format (0xRRGGBB)
* @param alpha The alpha value (0-255)
* @param restartExplorer Whether to restart explorer.exe
* @throws IOException If the process fails to start
* @throws InterruptedException If the process is interrupted
*/
public static void setTaskbarAppearance(TaskbarAccentMode mode, String color, int alpha, boolean restartExplorer)
throws IOException, InterruptedException {
if (color == null) color = "0x000000";
String raw = color.trim();
if (raw.startsWith("#")) raw = raw.substring(1);
if (raw.startsWith("0x") || raw.startsWith("0X")) raw = raw.substring(2);
if (raw.length() > 6) {
raw = raw.substring(raw.length() - 6);
}
while (raw.length() < 6) raw = "0" + raw;
String colorArg = "0x" + raw.toUpperCase();
String exePath = LIBRARY + "\\" + TASKBAR_EXE;
java.util.List<String> cmd = new java.util.ArrayList<>();
cmd.add(exePath);
cmd.add("--mode");
cmd.add(String.valueOf(mode.getValue()));
cmd.add("--color");
cmd.add(colorArg);
cmd.add("--alpha");
cmd.add(String.valueOf(alpha));
if (restartExplorer) {
cmd.add("--restart");
}
System.out.println("Exec: " + String.join(" ", cmd));
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.redirectErrorStream(true);
Process process = pb.start();
StringBuilder output = new StringBuilder();
try (java.io.BufferedReader reader = new java.io.BufferedReader(
new java.io.InputStreamReader(process.getInputStream(), java.nio.charset.StandardCharsets.UTF_8))) {
String line;
while ((line = reader.readLine()) != null) {
output.append(line).append(System.lineSeparator());
System.out.println(line);
}
}
int exit = process.waitFor();
if (exit != 0) {
throw new IOException("TaskbarTranslucentConsole exit code: " + exit + "\nOutput:\n" + output.toString());
}
}
/**
* Shows the help message for TaskbarTranslucentConsole.exe
* @throws IOException If the process fails to start
* @throws InterruptedException If the process is interrupted
*/
public static void showTaskbarHelp() throws IOException, InterruptedException {
String command = LIBRARY + "\\" + TASKBAR_EXE + " --help";
Process process = Runtime.getRuntime().exec(command);
process.waitFor();
}
public static void main(String[] args) throws IOException, InterruptedException {
LocalCall.setTaskbarAppearance(
LocalCall.TaskbarAccentMode.ACCENT_ENABLE_BLURBEHIND,
"0x000000",
0,
false
);
}
}
/**
* Custom annotation for enum descriptions
*/
@interface Description {
String value();
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB