新增国际化

This commit is contained in:
lifangliang 2025-07-10 17:43:32 +08:00
parent 110ee99978
commit 3c4e72cd58
16 changed files with 1173 additions and 128 deletions

View File

@ -0,0 +1,40 @@
package com.goeing.printserver.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import java.util.Locale;
/**
* 国际化配置类
*/
@Configuration
@ComponentScan(basePackages = {"com.goeing.printserver.main.utils"})
public class MessageConfig {
/**
* 配置消息源
*/
@Bean
public ResourceBundleMessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasenames("messages");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
/**
* 配置区域解析器
*/
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver resolver = new SessionLocaleResolver();
resolver.setDefaultLocale(Locale.getDefault());
return resolver;
}
}

View File

@ -5,20 +5,36 @@ import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.util.Locale;
import com.goeing.printserver.main.utils.LocaleChangeListener;
import com.goeing.printserver.main.utils.LocaleManager;
import com.goeing.printserver.main.utils.MessageUtils;
/**
* 关于对话框显示应用程序信息
*/
public class AboutDialog extends JDialog {
public class AboutDialog extends JDialog implements LocaleChangeListener {
private JLabel titleLabel;
private JLabel versionLabel;
private JLabel buildDateLabel;
private JLabel jdkVersionLabel;
private JLabel osVersionLabel;
private JLabel copyrightLabel;
private JButton closeButton;
/**
* 创建关于对话框
*
* @param parent 父窗口
*/
public AboutDialog(Window parent) {
super(parent, "关于打印服务器", ModalityType.APPLICATION_MODAL);
super(parent, MessageUtils.getMessage("about.title"), ModalityType.APPLICATION_MODAL);
initializeUI();
// 注册语言变更监听器
LocaleManager.getInstance().addLocaleChangeListener(this);
}
/**
@ -47,24 +63,28 @@ public class AboutDialog extends JDialog {
infoPanel.setBorder(BorderFactory.createEmptyBorder(10, 20, 10, 20));
// 添加应用信息
addInfoLabel(infoPanel, "打印服务器", Font.BOLD, 16);
addInfoLabel(infoPanel, "版本: 1.0.0", Font.PLAIN, 12);
addInfoLabel(infoPanel, "构建日期: " + java.time.LocalDate.now().toString(), Font.PLAIN, 12);
addInfoLabel(infoPanel, "JDK版本: " + System.getProperty("java.version"), Font.PLAIN, 12);
addInfoLabel(infoPanel, "操作系统: " + System.getProperty("os.name") + " " + System.getProperty("os.version"), Font.PLAIN, 12);
titleLabel = addInfoLabel(infoPanel, MessageUtils.getMessage("about.app.name"), Font.BOLD, 16);
versionLabel = addInfoLabel(infoPanel, MessageUtils.getMessage("about.version", new Object[]{"1.0.0"}), Font.PLAIN, 12);
buildDateLabel = addInfoLabel(infoPanel, MessageUtils.getMessage("about.build.date", new Object[]{java.time.LocalDate.now().toString()}), Font.PLAIN, 12);
jdkVersionLabel = addInfoLabel(infoPanel, MessageUtils.getMessage("about.jdk.version", new Object[]{System.getProperty("java.version")}), Font.PLAIN, 12);
osVersionLabel = addInfoLabel(infoPanel, MessageUtils.getMessage("about.os.version", new Object[]{System.getProperty("os.name") + " " + System.getProperty("os.version")}), Font.PLAIN, 12);
// 添加空白间隔
infoPanel.add(Box.createVerticalStrut(10));
// 添加版权信息
addInfoLabel(infoPanel, "© " + java.time.Year.now().getValue() + " Goeing. 保留所有权利。", Font.ITALIC, 12);
copyrightLabel = addInfoLabel(infoPanel, MessageUtils.getMessage("about.copyright", new Object[]{java.time.Year.now().getValue()}), Font.ITALIC, 12);
add(infoPanel, BorderLayout.CENTER);
// 创建按钮面板
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
JButton closeButton = new JButton("关闭");
closeButton.addActionListener(e -> dispose());
closeButton = new JButton(MessageUtils.getMessage("button.close"));
closeButton.addActionListener(e -> {
// 移除语言变更监听器
LocaleManager.getInstance().removeLocaleChangeListener(this);
dispose();
});
buttonPanel.add(closeButton);
add(buttonPanel, BorderLayout.SOUTH);
@ -78,12 +98,13 @@ public class AboutDialog extends JDialog {
* @param fontStyle 字体样式
* @param fontSize 字体大小
*/
private void addInfoLabel(JPanel panel, String text, int fontStyle, int fontSize) {
private JLabel addInfoLabel(JPanel panel, String text, int fontStyle, int fontSize) {
JLabel label = new JLabel(text);
label.setFont(new Font(label.getFont().getName(), fontStyle, fontSize));
label.setAlignmentX(0.5f); // CENTER_ALIGNMENT = 0.5f
panel.add(label);
panel.add(Box.createVerticalStrut(5));
return label;
}
/**
@ -134,4 +155,25 @@ public class AboutDialog extends JDialog {
AboutDialog dialog = new AboutDialog(parent);
dialog.setVisible(true);
}
/**
* 当语言变更时更新UI元素
* @param newLocale 新的语言区域
*/
@Override
public void onLocaleChanged(Locale newLocale) {
// 更新窗口标题
setTitle(MessageUtils.getMessage("about.title"));
// 更新标签文本
titleLabel.setText(MessageUtils.getMessage("about.app.name"));
versionLabel.setText(MessageUtils.getMessage("about.version", new Object[]{"1.0.0"}));
buildDateLabel.setText(MessageUtils.getMessage("about.build.date", new Object[]{java.time.LocalDate.now().toString()}));
jdkVersionLabel.setText(MessageUtils.getMessage("about.jdk.version", new Object[]{System.getProperty("java.version")}));
osVersionLabel.setText(MessageUtils.getMessage("about.os.version", new Object[]{System.getProperty("os.name") + " " + System.getProperty("os.version")}));
copyrightLabel.setText(MessageUtils.getMessage("about.copyright", new Object[]{java.time.Year.now().getValue()}));
// 更新按钮文本
closeButton.setText(MessageUtils.getMessage("button.close"));
}
}

View File

@ -14,13 +14,12 @@ import java.awt.*;
@Slf4j
public class PrintNotificationService {
private final PrintServerTray printServerTray;
private PrintServerTray printServerTray;
private final PrintSettingsPanel settingsPanel;
private boolean headless = false;
@Autowired
public PrintNotificationService(PrintServerTray printServerTray, PrintSettingsPanel settingsPanel) {
this.printServerTray = printServerTray;
public PrintNotificationService(PrintSettingsPanel settingsPanel) {
this.settingsPanel = settingsPanel;
// 检查是否在无头模式下运行
this.headless = GraphicsEnvironment.isHeadless() || Boolean.getBoolean("app.headless.mode");
@ -28,6 +27,11 @@ public class PrintNotificationService {
log.info("系统运行在无头模式下,通知功能将被禁用");
}
}
@Autowired
public void setPrintServerTray(PrintServerTray printServerTray) {
this.printServerTray = printServerTray;
}
/**
* 通知打印任务已添加到队列

View File

@ -1,6 +1,9 @@
package com.goeing.printserver.main.gui;
import com.goeing.printserver.main.service.PrintQueueService;
import com.goeing.printserver.main.utils.LocaleChangeListener;
import com.goeing.printserver.main.utils.LocaleManager;
import com.goeing.printserver.main.utils.MessageUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import jakarta.annotation.PreDestroy;
@ -13,6 +16,7 @@ import java.awt.event.WindowEvent;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
@ -22,10 +26,10 @@ import java.util.concurrent.TimeUnit;
* 打印队列图形界面
*/
@Component
public class PrintQueueGUI {
public class PrintQueueGUI implements LocaleChangeListener {
private final PrintQueueService printQueueService;
private final PrinterStatusPanel printerStatusPanel;
private PrinterStatusPanel printerStatusPanel;
private final PrintStatisticsPanel statisticsPanel;
private final PrintTaskSearchPanel searchPanel;
private final PrintSettingsPanel settingsPanel;
@ -37,29 +41,36 @@ public class PrintQueueGUI {
private JLabel statusLabel;
private final ScheduledExecutorService refreshExecutor = Executors.newSingleThreadScheduledExecutor();
private final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@Autowired
public PrintQueueGUI(PrintQueueService printQueueService, PrinterStatusPanel printerStatusPanel,
public PrintQueueGUI(PrintQueueService printQueueService,
PrintStatisticsPanel statisticsPanel, PrintTaskSearchPanel searchPanel,
PrintSettingsPanel settingsPanel) {
this.printQueueService = printQueueService;
this.printerStatusPanel = printerStatusPanel;
this.statisticsPanel = statisticsPanel;
this.searchPanel = searchPanel;
this.settingsPanel = settingsPanel;
// 注册语言变更监听器
LocaleManager.getInstance().addLocaleChangeListener(this);
// 只有在非无头模式下才初始化GUI
if (!GraphicsEnvironment.isHeadless() && !Boolean.getBoolean("app.headless.mode")) {
SwingUtilities.invokeLater(this::initializeGUI);
}
}
@Autowired
public void setPrinterStatusPanel(PrinterStatusPanel printerStatusPanel) {
this.printerStatusPanel = printerStatusPanel;
}
/**
* 初始化图形界面
*/
private void initializeGUI() {
// 创建主窗口
frame = new JFrame("打印队列监控");
frame = new JFrame(MessageUtils.getMessage("main.title"));
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.setSize(800, 600);
frame.setLayout(new BorderLayout());
@ -79,12 +90,12 @@ public class PrintQueueGUI {
// 创建顶部面板
JPanel topPanel = new JPanel(new BorderLayout());
statusLabel = new JLabel("队列状态: 空闲");
statusLabel = new JLabel(MessageUtils.getMessage("queue.status.idle"));
statusLabel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
topPanel.add(statusLabel, BorderLayout.WEST);
// 创建刷新按钮
JButton refreshButton = new JButton("刷新");
JButton refreshButton = new JButton(MessageUtils.getMessage("button.refresh"));
refreshButton.addActionListener(e -> refreshData());
topPanel.add(refreshButton, BorderLayout.EAST);
@ -95,23 +106,23 @@ public class PrintQueueGUI {
// 创建当前任务面板
JPanel currentTaskPanel = createCurrentTaskPanel();
tabbedPane.addTab("当前任务", currentTaskPanel);
tabbedPane.addTab(MessageUtils.getMessage("tab.current.task"), currentTaskPanel);
// 创建队列任务面板
JPanel queuedTasksPanel = createQueuedTasksPanel();
tabbedPane.addTab("队列任务", queuedTasksPanel);
tabbedPane.addTab(MessageUtils.getMessage("tab.queued.tasks"), queuedTasksPanel);
// 添加打印机状态面板
tabbedPane.addTab("打印机状态", printerStatusPanel);
tabbedPane.addTab(MessageUtils.getMessage("tab.printer.status"), printerStatusPanel);
// 添加统计面板
tabbedPane.addTab("统计信息", statisticsPanel);
tabbedPane.addTab(MessageUtils.getMessage("tab.statistics"), statisticsPanel);
// 添加任务搜索面板
tabbedPane.addTab("任务搜索", searchPanel);
tabbedPane.addTab(MessageUtils.getMessage("tab.task.search"), searchPanel);
// 添加设置面板
tabbedPane.addTab("设置", settingsPanel);
tabbedPane.addTab(MessageUtils.getMessage("tab.settings"), settingsPanel);
frame.add(tabbedPane, BorderLayout.CENTER);
@ -131,7 +142,14 @@ public class PrintQueueGUI {
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
// 创建表格模型
String[] columnNames = {"文件URL", "打印机", "状态", "队列时间", "开始时间", "结束时间"};
String[] columnNames = {
MessageUtils.getMessage("table.header.file.url"),
MessageUtils.getMessage("table.header.printer"),
MessageUtils.getMessage("table.header.status"),
MessageUtils.getMessage("table.header.queued.time"),
MessageUtils.getMessage("table.header.start.time"),
MessageUtils.getMessage("table.header.end.time")
};
currentTaskModel = new DefaultTableModel(columnNames, 0) {
@Override
public boolean isCellEditable(int row, int column) {
@ -169,7 +187,12 @@ public class PrintQueueGUI {
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
// 创建表格模型
String[] columnNames = {"文件URL", "打印机", "状态", "队列时间"};
String[] columnNames = {
MessageUtils.getMessage("table.header.file.url"),
MessageUtils.getMessage("table.header.printer"),
MessageUtils.getMessage("table.header.status"),
MessageUtils.getMessage("table.header.queued.time")
};
queuedTasksModel = new DefaultTableModel(columnNames, 0) {
@Override
public boolean isCellEditable(int row, int column) {
@ -217,11 +240,11 @@ public class PrintQueueGUI {
Map<String, Object> currentTask = printQueueService.getCurrentTaskInfo();
if (currentTask != null) {
statusLabel.setText("队列状态: 正在处理任务 (队列中还有 " + queueSize + " 个任务)");
statusLabel.setText(MessageUtils.getMessage("queue.status.processing", new Object[]{queueSize}));
} else if (queueSize > 0) {
statusLabel.setText("队列状态: 等待处理 (队列中有 " + queueSize + " 个任务)");
statusLabel.setText(MessageUtils.getMessage("queue.status.waiting", new Object[]{queueSize}));
} else {
statusLabel.setText("队列状态: 空闲");
statusLabel.setText(MessageUtils.getMessage("queue.status.idle"));
}
// 更新当前任务表格
@ -232,7 +255,7 @@ public class PrintQueueGUI {
updateQueuedTasksTable(queuedTasks);
} catch (Exception e) {
e.printStackTrace();
statusLabel.setText("刷新数据时发生错误: " + e.getMessage());
statusLabel.setText(MessageUtils.getMessage("error.refresh.data", new Object[]{e.getMessage()}));
}
});
}
@ -307,9 +330,9 @@ public class PrintQueueGUI {
JMenuBar menuBar = new JMenuBar();
// 文件菜单
JMenu fileMenu = new JMenu("文件");
JMenuItem refreshItem = new JMenuItem("刷新");
JMenuItem exitItem = new JMenuItem("退出");
JMenu fileMenu = new JMenu(MessageUtils.getMessage("menu.file"));
JMenuItem refreshItem = new JMenuItem(MessageUtils.getMessage("menu.file.refresh"));
JMenuItem exitItem = new JMenuItem(MessageUtils.getMessage("menu.file.exit"));
refreshItem.addActionListener(e -> refreshData());
exitItem.addActionListener(e -> System.exit(0));
@ -319,8 +342,8 @@ public class PrintQueueGUI {
fileMenu.add(exitItem);
// 视图菜单
JMenu viewMenu = new JMenu("视图");
JMenuItem alwaysOnTopItem = new JCheckBoxMenuItem("窗口置顶");
JMenu viewMenu = new JMenu(MessageUtils.getMessage("menu.view"));
JMenuItem alwaysOnTopItem = new JCheckBoxMenuItem(MessageUtils.getMessage("menu.view.always.on.top"));
alwaysOnTopItem.addActionListener(e -> {
boolean selected = ((JCheckBoxMenuItem) e.getSource()).isSelected();
@ -329,9 +352,22 @@ public class PrintQueueGUI {
viewMenu.add(alwaysOnTopItem);
// 语言菜单
JMenu languageMenu = new JMenu(MessageUtils.getMessage("menu.language"));
// 添加语言选项
ButtonGroup languageGroup = new ButtonGroup();
for (Locale locale : LocaleManager.getInstance().getSupportedLocales()) {
JRadioButtonMenuItem languageItem = new JRadioButtonMenuItem(locale.getDisplayName());
languageItem.setSelected(locale.equals(LocaleManager.getInstance().getCurrentLocale()));
languageItem.addActionListener(e -> LocaleManager.getInstance().setCurrentLocale(locale));
languageGroup.add(languageItem);
languageMenu.add(languageItem);
}
// 帮助菜单
JMenu helpMenu = new JMenu("帮助");
JMenuItem aboutItem = new JMenuItem("关于");
JMenu helpMenu = new JMenu(MessageUtils.getMessage("menu.help"));
JMenuItem aboutItem = new JMenuItem(MessageUtils.getMessage("menu.help.about"));
aboutItem.addActionListener(e -> AboutDialog.showDialog(frame));
@ -340,6 +376,7 @@ public class PrintQueueGUI {
// 添加菜单到菜单栏
menuBar.add(fileMenu);
menuBar.add(viewMenu);
menuBar.add(languageMenu);
menuBar.add(helpMenu);
return menuBar;
@ -381,8 +418,75 @@ public class PrintQueueGUI {
refreshExecutor.shutdownNow();
printerStatusPanel.shutdown();
statisticsPanel.shutdown();
searchPanel.shutdown();
settingsPanel.shutdown();
LocaleManager.getInstance().removeLocaleChangeListener(this);
if (frame != null) {
frame.dispose();
}
}
/**
* 当语言变更时更新界面
*/
@Override
public void onLocaleChanged(Locale newLocale) {
if (frame != null) {
SwingUtilities.invokeLater(() -> {
// 更新窗口标题
frame.setTitle(MessageUtils.getMessage("main.title"));
// 更新状态标签
refreshData();
// 更新菜单栏
frame.setJMenuBar(createMenuBar());
// 更新选项卡标题
JTabbedPane tabbedPane = (JTabbedPane) frame.getContentPane().getComponent(1);
tabbedPane.setTitleAt(0, MessageUtils.getMessage("tab.current.task"));
tabbedPane.setTitleAt(1, MessageUtils.getMessage("tab.queued.tasks"));
tabbedPane.setTitleAt(2, MessageUtils.getMessage("tab.printer.status"));
tabbedPane.setTitleAt(3, MessageUtils.getMessage("tab.statistics"));
tabbedPane.setTitleAt(4, MessageUtils.getMessage("tab.task.search"));
tabbedPane.setTitleAt(5, MessageUtils.getMessage("tab.settings"));
// 更新表格列名
updateTableHeaders();
});
}
}
/**
* 更新表格列名
*/
private void updateTableHeaders() {
// 更新当前任务表格列名
String[] currentTaskColumnNames = {
MessageUtils.getMessage("table.header.file.url"),
MessageUtils.getMessage("table.header.printer"),
MessageUtils.getMessage("table.header.status"),
MessageUtils.getMessage("table.header.queued.time"),
MessageUtils.getMessage("table.header.start.time"),
MessageUtils.getMessage("table.header.end.time")
};
for (int i = 0; i < currentTaskColumnNames.length; i++) {
currentTaskTable.getColumnModel().getColumn(i).setHeaderValue(currentTaskColumnNames[i]);
}
// 更新队列任务表格列名
String[] queuedTasksColumnNames = {
MessageUtils.getMessage("table.header.file.url"),
MessageUtils.getMessage("table.header.printer"),
MessageUtils.getMessage("table.header.status"),
MessageUtils.getMessage("table.header.queued.time")
};
for (int i = 0; i < queuedTasksColumnNames.length; i++) {
queuedTasksTable.getColumnModel().getColumn(i).setHeaderValue(queuedTasksColumnNames[i]);
}
// 刷新表格头
currentTaskTable.getTableHeader().repaint();
queuedTasksTable.getTableHeader().repaint();
}
}

View File

@ -18,15 +18,19 @@ import java.awt.image.BufferedImage;
@Slf4j
public class PrintServerTray {
private final PrintQueueGUI printQueueGUI;
private PrintQueueGUI printQueueGUI;
private TrayIcon trayIcon;
private SystemTray systemTray;
private boolean traySupported;
@Autowired
public PrintServerTray(PrintQueueGUI printQueueGUI) {
public PrintServerTray() {
// 移除构造函数中的PrintQueueGUI依赖改为在initialize方法中注入
}
@Autowired
public void setPrintQueueGUI(PrintQueueGUI printQueueGUI) {
this.printQueueGUI = printQueueGUI;
// 初始化逻辑移至initialize()方法
}
/**

View File

@ -2,6 +2,9 @@ package com.goeing.printserver.main.gui;
import com.goeing.printserver.main.PrintController;
import com.goeing.printserver.main.config.PrintServerConfig;
import com.goeing.printserver.main.utils.LocaleChangeListener;
import com.goeing.printserver.main.utils.LocaleManager;
import com.goeing.printserver.main.utils.MessageUtils;
import com.goeing.printserver.main.service.PrintQueueService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -9,6 +12,7 @@ import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Locale;
import com.goeing.printserver.main.gui.PrinterStatusPanel.PrinterListUpdatedEvent;
import javax.swing.*;
@ -19,7 +23,7 @@ import java.awt.*;
*/
@Component
@Slf4j
public class PrintSettingsPanel extends JPanel {
public class PrintSettingsPanel extends JPanel implements LocaleChangeListener {
private final PrintQueueService printQueueService;
private final PrintServerConfig config;
@ -31,6 +35,13 @@ public class PrintSettingsPanel extends JPanel {
private JCheckBox enableNotificationsCheckBox;
private JCheckBox startMinimizedCheckBox;
private JCheckBox autoStartCheckBox;
// 标签和按钮
private JLabel titleLabel;
private JLabel defaultPrinterLabel;
private JLabel maxQueueSizeLabel;
private JButton saveButton;
private JButton resetButton;
@Autowired
public PrintSettingsPanel(PrintQueueService printQueueService, PrintServerConfig config, PrintController printController) {
@ -39,6 +50,9 @@ public class PrintSettingsPanel extends JPanel {
this.printController = printController;
initializeUI();
loadSettings();
// 注册语言变更监听器
LocaleManager.getInstance().addLocaleChangeListener(this);
}
/**
@ -49,7 +63,8 @@ public class PrintSettingsPanel extends JPanel {
setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
// 创建标题
JLabel titleLabel = new JLabel("打印服务器设置");
String message = MessageUtils.getMessage("settings.title");
titleLabel = new JLabel(message);
titleLabel.setFont(new Font(titleLabel.getFont().getName(), Font.BOLD, 16));
titleLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0));
add(titleLabel, BorderLayout.NORTH);
@ -65,7 +80,8 @@ public class PrintSettingsPanel extends JPanel {
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 1;
settingsPanel.add(new JLabel("默认打印机:"), gbc);
defaultPrinterLabel = new JLabel(MessageUtils.getMessage("settings.defaultPrinter"));
settingsPanel.add(defaultPrinterLabel, gbc);
gbc.gridx = 1;
gbc.weightx = 1.0;
@ -77,7 +93,8 @@ public class PrintSettingsPanel extends JPanel {
gbc.gridx = 0;
gbc.gridy = 1;
gbc.weightx = 0.0;
settingsPanel.add(new JLabel("最大队列大小:"), gbc);
maxQueueSizeLabel = new JLabel(MessageUtils.getMessage("settings.maxQueueSize"));
settingsPanel.add(maxQueueSizeLabel, gbc);
gbc.gridx = 1;
gbc.weightx = 1.0;
@ -89,19 +106,19 @@ public class PrintSettingsPanel extends JPanel {
gbc.gridx = 0;
gbc.gridy = 2;
gbc.gridwidth = 2;
enableNotificationsCheckBox = new JCheckBox("启用系统通知");
enableNotificationsCheckBox = new JCheckBox(MessageUtils.getMessage("settings.notifications"));
settingsPanel.add(enableNotificationsCheckBox, gbc);
// 启动时最小化设置
gbc.gridx = 0;
gbc.gridy = 3;
startMinimizedCheckBox = new JCheckBox("启动时最小化到系统托盘");
startMinimizedCheckBox = new JCheckBox(MessageUtils.getMessage("settings.startMinimized"));
settingsPanel.add(startMinimizedCheckBox, gbc);
// 开机自启动设置
gbc.gridx = 0;
gbc.gridy = 4;
autoStartCheckBox = new JCheckBox("开机自动启动");
autoStartCheckBox = new JCheckBox(MessageUtils.getMessage("settings.autoStart"));
settingsPanel.add(autoStartCheckBox, gbc);
// 添加一个弹性空间
@ -117,11 +134,11 @@ public class PrintSettingsPanel extends JPanel {
// 创建按钮面板
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
JButton saveButton = new JButton("保存设置");
saveButton = new JButton(MessageUtils.getMessage("settings.save"));
saveButton.addActionListener(e -> saveSettings());
buttonPanel.add(saveButton);
JButton resetButton = new JButton("重置默认");
resetButton = new JButton(MessageUtils.getMessage("settings.reset"));
resetButton.addActionListener(e -> resetSettings());
buttonPanel.add(resetButton);
@ -168,10 +185,10 @@ public class PrintSettingsPanel extends JPanel {
// 应用设置到服务
applySettings();
JOptionPane.showMessageDialog(this, "设置已保存", "成功", JOptionPane.INFORMATION_MESSAGE);
JOptionPane.showMessageDialog(this, MessageUtils.getMessage("settings.saved"), MessageUtils.getMessage("dialog.success"), JOptionPane.INFORMATION_MESSAGE);
} catch (Exception e) {
log.error("保存设置时发生错误", e);
JOptionPane.showMessageDialog(this, "保存设置失败: " + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
log.error(MessageUtils.getMessage("log.settings.save.error"), e);
JOptionPane.showMessageDialog(this, MessageUtils.getMessage("settings.save.error", new Object[]{e.getMessage()}), MessageUtils.getMessage("dialog.error"), JOptionPane.ERROR_MESSAGE);
}
}
@ -179,7 +196,7 @@ public class PrintSettingsPanel extends JPanel {
* 重置设置为默认值
*/
private void resetSettings() {
int option = JOptionPane.showConfirmDialog(this, "确定要重置所有设置为默认值吗?", "确认", JOptionPane.YES_NO_OPTION);
int option = JOptionPane.showConfirmDialog(this, MessageUtils.getMessage("settings.reset.confirm"), MessageUtils.getMessage("dialog.confirm"), JOptionPane.YES_NO_OPTION);
if (option == JOptionPane.YES_OPTION) {
try {
// 重置配置对象到默认值
@ -191,10 +208,10 @@ public class PrintSettingsPanel extends JPanel {
// 应用默认设置
applySettings();
JOptionPane.showMessageDialog(this, "设置已重置为默认值", "成功", JOptionPane.INFORMATION_MESSAGE);
JOptionPane.showMessageDialog(this, MessageUtils.getMessage("settings.reset.success"), MessageUtils.getMessage("dialog.success"), JOptionPane.INFORMATION_MESSAGE);
} catch (Exception e) {
log.error("重置设置时发生错误", e);
JOptionPane.showMessageDialog(this, "重置设置失败: " + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
log.error(MessageUtils.getMessage("log.settings.reset.error"), e);
JOptionPane.showMessageDialog(this, MessageUtils.getMessage("settings.reset.error", new Object[]{e.getMessage()}), MessageUtils.getMessage("dialog.error"), JOptionPane.ERROR_MESSAGE);
}
}
}
@ -208,7 +225,7 @@ public class PrintSettingsPanel extends JPanel {
printQueueService.setMaxQueueSize(config.getMaxQueueSize());
// 通知设置变更
log.info("应用设置: 默认打印机={}, 最大队列大小={}, 启用通知={}, 启动时最小化={}, 开机自启动={}",
log.info(MessageUtils.getMessage("log.settings.applied"),
config.getDefaultPrinter(),
config.getMaxQueueSize(),
config.isEnableNotifications(),
@ -267,7 +284,7 @@ public class PrintSettingsPanel extends JPanel {
List<String> printers = printController.printerList();
updatePrinterComboBox(printers, selectedPrinter);
} catch (Exception e) {
log.error("更新打印机列表时发生错误", e);
log.error(MessageUtils.getMessage("log.printer.list.update.error"), e);
}
}
@ -295,7 +312,7 @@ public class PrintSettingsPanel extends JPanel {
}
// 使用debug级别记录日志减少info日志输出
log.debug("已更新打印机列表,共{}个打印机", printers.size());
log.debug(MessageUtils.getMessage("log.printer.list.updated"), printers.size());
}
}
@ -316,7 +333,35 @@ public class PrintSettingsPanel extends JPanel {
updatePrinterComboBox(event.getPrinters(), selectedPrinter);
// 使用debug级别记录日志减少info日志输出
log.debug("收到打印机列表更新事件,已更新打印机下拉列表");
log.debug(MessageUtils.getMessage("log.printer.list.event.received"));
});
}
/**
* 当语言变更时更新UI元素
*/
@Override
public void onLocaleChanged(Locale newLocale) {
// 更新标题和标签
titleLabel.setText(MessageUtils.getMessage("settings.title"));
defaultPrinterLabel.setText(MessageUtils.getMessage("settings.defaultPrinter"));
maxQueueSizeLabel.setText(MessageUtils.getMessage("settings.maxQueueSize"));
// 更新复选框
enableNotificationsCheckBox.setText(MessageUtils.getMessage("settings.notifications"));
startMinimizedCheckBox.setText(MessageUtils.getMessage("settings.startMinimized"));
autoStartCheckBox.setText(MessageUtils.getMessage("settings.autoStart"));
// 更新按钮
saveButton.setText(MessageUtils.getMessage("settings.save"));
resetButton.setText(MessageUtils.getMessage("settings.reset"));
}
/**
* 关闭资源
*/
public void shutdown() {
// 移除语言变更监听器
LocaleManager.getInstance().removeLocaleChangeListener(this);
}
}

View File

@ -1,6 +1,9 @@
package com.goeing.printserver.main.gui;
import com.goeing.printserver.main.service.PrintQueueService;
import com.goeing.printserver.main.utils.LocaleChangeListener;
import com.goeing.printserver.main.utils.LocaleManager;
import com.goeing.printserver.main.utils.MessageUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -9,6 +12,7 @@ import javax.swing.*;
import java.awt.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@ -19,7 +23,7 @@ import java.util.concurrent.atomic.AtomicInteger;
*/
@Component
@Slf4j
public class PrintStatisticsPanel extends JPanel {
public class PrintStatisticsPanel extends JPanel implements LocaleChangeListener {
private final PrintQueueService printQueueService;
private final ScheduledExecutorService refreshExecutor = Executors.newSingleThreadScheduledExecutor();
@ -44,6 +48,9 @@ public class PrintStatisticsPanel extends JPanel {
this.printQueueService = printQueueService;
initializeUI();
startRefreshTimer();
// 注册语言变更监听器
LocaleManager.getInstance().addLocaleChangeListener(this);
}
/**
@ -55,12 +62,12 @@ public class PrintStatisticsPanel extends JPanel {
// 创建顶部面板
JPanel topPanel = new JPanel(new BorderLayout());
JLabel titleLabel = new JLabel("打印统计");
JLabel titleLabel = new JLabel(MessageUtils.getMessage("statistics.title"));
titleLabel.setFont(new Font(titleLabel.getFont().getName(), Font.BOLD, 14));
topPanel.add(titleLabel, BorderLayout.WEST);
// 创建刷新按钮
JButton refreshButton = new JButton("刷新");
JButton refreshButton = new JButton(MessageUtils.getMessage("button.refresh"));
refreshButton.addActionListener(e -> refreshStatistics());
topPanel.add(refreshButton, BorderLayout.EAST);
@ -72,12 +79,12 @@ public class PrintStatisticsPanel extends JPanel {
statsPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
// 添加统计信息
totalTasksLabel = createStatLabel("总任务数: 0");
completedTasksLabel = createStatLabel("已完成任务: 0");
failedTasksLabel = createStatLabel("失败任务: 0");
queueSizeLabel = createStatLabel("当前队列长度: 0");
upTimeLabel = createStatLabel("运行时间: 0小时0分钟");
currentTimeLabel = createStatLabel("当前时间: " + LocalDateTime.now().format(dateFormatter));
totalTasksLabel = createStatLabel(MessageUtils.getMessage("statistics.total.tasks", new Object[]{0}));
completedTasksLabel = createStatLabel(MessageUtils.getMessage("statistics.completed.tasks", new Object[]{0}));
failedTasksLabel = createStatLabel(MessageUtils.getMessage("statistics.failed.tasks", new Object[]{0}));
queueSizeLabel = createStatLabel(MessageUtils.getMessage("statistics.queue.size", new Object[]{0}));
upTimeLabel = createStatLabel(MessageUtils.getMessage("statistics.uptime", new Object[]{0, 0}));
currentTimeLabel = createStatLabel(MessageUtils.getMessage("statistics.current.time", new Object[]{LocalDateTime.now().format(dateFormatter)}));
statsPanel.add(totalTasksLabel);
statsPanel.add(Box.createVerticalStrut(10));
@ -95,7 +102,7 @@ public class PrintStatisticsPanel extends JPanel {
statsPanel.add(Box.createVerticalGlue());
// 添加重置按钮
JButton resetButton = new JButton("重置统计");
JButton resetButton = new JButton(MessageUtils.getMessage("button.reset.statistics"));
resetButton.addActionListener(e -> resetStatistics());
resetButton.setAlignmentX(0.0f); // LEFT_ALIGNMENT = 0.0f
@ -136,18 +143,18 @@ public class PrintStatisticsPanel extends JPanel {
try {
// 更新队列大小
int queueSize = printQueueService.getQueueSize();
queueSizeLabel.setText("当前队列长度: " + queueSize);
queueSizeLabel.setText(MessageUtils.getMessage("statistics.queue.size", new Object[]{queueSize}));
// 更新运行时间
LocalDateTime now = LocalDateTime.now();
long hours = java.time.Duration.between(startTime, now).toHours();
long minutes = java.time.Duration.between(startTime, now).toMinutes() % 60;
upTimeLabel.setText(String.format("运行时间: %d小时%d分钟", hours, minutes));
upTimeLabel.setText(MessageUtils.getMessage("statistics.uptime", new Object[]{hours, minutes}));
// 更新当前时间
currentTimeLabel.setText("当前时间: " + now.format(dateFormatter));
currentTimeLabel.setText(MessageUtils.getMessage("statistics.current.time", new Object[]{now.format(dateFormatter)}));
} catch (Exception e) {
log.error("刷新统计信息时发生错误", e);
log.error(MessageUtils.getMessage("log.error.refresh.statistics"), e);
}
});
}
@ -161,10 +168,10 @@ public class PrintStatisticsPanel extends JPanel {
failedTasksCount.set(0);
startTime = LocalDateTime.now();
totalTasksLabel.setText("总任务数: 0");
completedTasksLabel.setText("已完成任务: 0");
failedTasksLabel.setText("失败任务: 0");
upTimeLabel.setText("运行时间: 0小时0分钟");
totalTasksLabel.setText(MessageUtils.getMessage("statistics.total.tasks", new Object[]{0}));
completedTasksLabel.setText(MessageUtils.getMessage("statistics.completed.tasks", new Object[]{0}));
failedTasksLabel.setText(MessageUtils.getMessage("statistics.failed.tasks", new Object[]{0}));
upTimeLabel.setText(MessageUtils.getMessage("statistics.uptime", new Object[]{0, 0}));
}
/**
@ -172,7 +179,7 @@ public class PrintStatisticsPanel extends JPanel {
*/
public void incrementTotalTasks() {
int total = totalTasksCount.incrementAndGet();
SwingUtilities.invokeLater(() -> totalTasksLabel.setText("总任务数: " + total));
SwingUtilities.invokeLater(() -> totalTasksLabel.setText(MessageUtils.getMessage("statistics.total.tasks", new Object[]{total})));
}
/**
@ -180,7 +187,7 @@ public class PrintStatisticsPanel extends JPanel {
*/
public void incrementCompletedTasks() {
int completed = completedTasksCount.incrementAndGet();
SwingUtilities.invokeLater(() -> completedTasksLabel.setText("已完成任务: " + completed));
SwingUtilities.invokeLater(() -> completedTasksLabel.setText(MessageUtils.getMessage("statistics.completed.tasks", new Object[]{completed})));
}
/**
@ -188,7 +195,7 @@ public class PrintStatisticsPanel extends JPanel {
*/
public void incrementFailedTasks() {
int failed = failedTasksCount.incrementAndGet();
SwingUtilities.invokeLater(() -> failedTasksLabel.setText("失败任务: " + failed));
SwingUtilities.invokeLater(() -> failedTasksLabel.setText(MessageUtils.getMessage("statistics.failed.tasks", new Object[]{failed})));
}
/**
@ -196,5 +203,49 @@ public class PrintStatisticsPanel extends JPanel {
*/
public void shutdown() {
refreshExecutor.shutdownNow();
LocaleManager.getInstance().removeLocaleChangeListener(this);
}
/**
* 当语言变更时更新界面
*/
@Override
public void onLocaleChanged(Locale newLocale) {
SwingUtilities.invokeLater(() -> {
// 更新标题标签
java.awt.Component[] components = ((JPanel)getComponent(0)).getComponents();
for (java.awt.Component component : components) {
if (component instanceof JLabel) {
((JLabel) component).setText(MessageUtils.getMessage("statistics.title"));
break;
}
}
// 更新刷新按钮
for (java.awt.Component component : components) {
if (component instanceof JButton) {
((JButton) component).setText(MessageUtils.getMessage("button.refresh"));
break;
}
}
// 更新重置按钮
JPanel statsPanel = (JPanel) ((JScrollPane) getComponent(1)).getViewport().getView();
JPanel buttonPanel = (JPanel) statsPanel.getComponent(statsPanel.getComponentCount() - 1);
JButton resetButton = (JButton) buttonPanel.getComponent(0);
resetButton.setText(MessageUtils.getMessage("button.reset.statistics"));
// 刷新统计信息
refreshStatistics();
// 更新其他标签
int total = totalTasksCount.get();
int completed = completedTasksCount.get();
int failed = failedTasksCount.get();
totalTasksLabel.setText(MessageUtils.getMessage("statistics.total.tasks", new Object[]{total}));
completedTasksLabel.setText(MessageUtils.getMessage("statistics.completed.tasks", new Object[]{completed}));
failedTasksLabel.setText(MessageUtils.getMessage("statistics.failed.tasks", new Object[]{failed}));
});
}
}

View File

@ -1,18 +1,22 @@
package com.goeing.printserver.main.gui;
import com.goeing.printserver.main.domain.PrintTask;
import com.goeing.printserver.main.utils.LocaleChangeListener;
import com.goeing.printserver.main.utils.LocaleManager;
import com.goeing.printserver.main.utils.MessageUtils;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.Dialog.ModalityType;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import java.util.Map;
/**
* 打印任务详情对话框
*/
public class PrintTaskDetailDialog extends JDialog {
public class PrintTaskDetailDialog extends JDialog implements LocaleChangeListener {
private final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@ -23,8 +27,9 @@ public class PrintTaskDetailDialog extends JDialog {
* @param task 任务信息
*/
public PrintTaskDetailDialog(Frame parent, Map<String, Object> task) {
super(parent, "打印任务详情", true);
super(parent, MessageUtils.getMessage("dialog.task.detail.title"), true);
initializeUI(task);
LocaleManager.getInstance().addLocaleChangeListener(this);
}
/**
@ -34,8 +39,9 @@ public class PrintTaskDetailDialog extends JDialog {
* @param task 打印任务对象
*/
public PrintTaskDetailDialog(Frame parent, PrintTask task) {
super(parent, "打印任务详情", true);
super(parent, MessageUtils.getMessage("dialog.task.detail.title"), true);
initializeUI(task.toMap());
LocaleManager.getInstance().addLocaleChangeListener(this);
}
/**
@ -45,8 +51,9 @@ public class PrintTaskDetailDialog extends JDialog {
* @param task 打印任务对象
*/
public PrintTaskDetailDialog(Window parent, PrintTask task) {
super(parent, "打印任务详情", ModalityType.APPLICATION_MODAL);
super(parent, MessageUtils.getMessage("dialog.task.detail.title"), ModalityType.APPLICATION_MODAL);
initializeUI(task.toMap());
LocaleManager.getInstance().addLocaleChangeListener(this);
}
/**
@ -56,8 +63,9 @@ public class PrintTaskDetailDialog extends JDialog {
* @param task 任务信息
*/
public PrintTaskDetailDialog(Window parent, Map<String, Object> task) {
super(parent, "打印任务详情", ModalityType.APPLICATION_MODAL);
super(parent, MessageUtils.getMessage("dialog.task.detail.title"), ModalityType.APPLICATION_MODAL);
initializeUI(task);
LocaleManager.getInstance().addLocaleChangeListener(this);
}
/**
@ -84,8 +92,11 @@ public class PrintTaskDetailDialog extends JDialog {
add(scrollPane, BorderLayout.CENTER);
// 添加关闭按钮
JButton closeButton = new JButton("关闭");
closeButton.addActionListener(e -> dispose());
JButton closeButton = new JButton(MessageUtils.getMessage("common.close"));
closeButton.addActionListener(e -> {
LocaleManager.getInstance().removeLocaleChangeListener(this);
dispose();
});
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
buttonPanel.add(closeButton);
@ -100,31 +111,31 @@ public class PrintTaskDetailDialog extends JDialog {
*/
private void addTaskInfo(JPanel panel, Map<String, Object> task) {
// 添加标题
JLabel titleLabel = new JLabel("打印任务详情");
JLabel titleLabel = new JLabel(MessageUtils.getMessage("dialog.task.detail.title"));
titleLabel.setFont(new Font(titleLabel.getFont().getName(), Font.BOLD, 16));
titleLabel.setAlignmentX(0.0f); // LEFT_ALIGNMENT = 0.0f
panel.add(titleLabel);
panel.add(Box.createVerticalStrut(10));
// 添加基本信息
addInfoField(panel, "文件URL:", getStringValue(task.get("fileUrl")));
addInfoField(panel, "打印机:", getStringValue(task.get("printerName")));
addInfoField(panel, "状态:", getStringValue(task.get("status")));
addInfoField(panel, "队列时间:", formatDateTime(task.get("queuedTime")));
addInfoField(panel, MessageUtils.getMessage("dialog.task.detail.file.url"), getStringValue(task.get("fileUrl")));
addInfoField(panel, MessageUtils.getMessage("dialog.task.detail.printer"), getStringValue(task.get("printerName")));
addInfoField(panel, MessageUtils.getMessage("dialog.task.detail.status"), getStringValue(task.get("status")));
addInfoField(panel, MessageUtils.getMessage("dialog.task.detail.queued.time"), formatDateTime(task.get("queuedTime")));
// 添加开始和结束时间如果有
if (task.containsKey("startTime") && task.get("startTime") != null) {
addInfoField(panel, "开始时间:", formatDateTime(task.get("startTime")));
addInfoField(panel, MessageUtils.getMessage("dialog.task.detail.start.time"), formatDateTime(task.get("startTime")));
}
if (task.containsKey("endTime") && task.get("endTime") != null) {
addInfoField(panel, "结束时间:", formatDateTime(task.get("endTime")));
addInfoField(panel, MessageUtils.getMessage("dialog.task.detail.end.time"), formatDateTime(task.get("endTime")));
}
// 添加打印选项如果有
if (task.containsKey("printOption") && task.get("printOption") != null) {
panel.add(Box.createVerticalStrut(10));
JLabel optionsLabel = new JLabel("打印选项");
JLabel optionsLabel = new JLabel(MessageUtils.getMessage("dialog.task.detail.print.options"));
optionsLabel.setFont(new Font(optionsLabel.getFont().getName(), Font.BOLD, 14));
optionsLabel.setAlignmentX(0.0f); // LEFT_ALIGNMENT = 0.0f
panel.add(optionsLabel);
@ -190,4 +201,53 @@ public class PrintTaskDetailDialog extends JDialog {
return dateTimeObj.toString();
}
/**
* 当语言变更时更新界面
*/
@Override
public void onLocaleChanged(Locale newLocale) {
SwingUtilities.invokeLater(() -> {
// 更新对话框标题
setTitle(MessageUtils.getMessage("dialog.task.detail.title"));
// 更新标题标签
Container contentPane = getContentPane();
JScrollPane scrollPane = (JScrollPane) contentPane.getComponent(0);
JPanel contentPanel = (JPanel) scrollPane.getViewport().getView();
JLabel titleLabel = (JLabel) contentPanel.getComponent(0);
titleLabel.setText(MessageUtils.getMessage("dialog.task.detail.title"));
// 更新字段标签
for (int i = 2; i < contentPanel.getComponentCount(); i++) {
Component comp = contentPanel.getComponent(i);
if (comp instanceof JPanel) {
JPanel fieldPanel = (JPanel) comp;
JLabel label = (JLabel) fieldPanel.getComponent(0);
String labelText = label.getText();
if (labelText.contains("文件URL") || labelText.contains("File URL")) {
label.setText(MessageUtils.getMessage("dialog.task.detail.file.url"));
} else if (labelText.contains("打印机") || labelText.contains("Printer")) {
label.setText(MessageUtils.getMessage("dialog.task.detail.printer"));
} else if (labelText.contains("状态") || labelText.contains("Status")) {
label.setText(MessageUtils.getMessage("dialog.task.detail.status"));
} else if (labelText.contains("队列时间") || labelText.contains("Queued Time")) {
label.setText(MessageUtils.getMessage("dialog.task.detail.queued.time"));
} else if (labelText.contains("开始时间") || labelText.contains("Start Time")) {
label.setText(MessageUtils.getMessage("dialog.task.detail.start.time"));
} else if (labelText.contains("结束时间") || labelText.contains("End Time")) {
label.setText(MessageUtils.getMessage("dialog.task.detail.end.time"));
} else if (labelText.contains("打印选项") || labelText.contains("Print Options")) {
label.setText(MessageUtils.getMessage("dialog.task.detail.print.options"));
}
}
}
// 更新关闭按钮
JPanel buttonPanel = (JPanel) contentPane.getComponent(1);
JButton closeButton = (JButton) buttonPanel.getComponent(0);
closeButton.setText(MessageUtils.getMessage("common.close"));
});
}
}

View File

@ -3,6 +3,9 @@ package com.goeing.printserver.main.gui;
import com.goeing.printserver.main.domain.PrintTask;
import com.goeing.printserver.main.service.PrintQueueService;
import com.goeing.printserver.main.service.PrintHistoryService;
import com.goeing.printserver.main.utils.LocaleChangeListener;
import com.goeing.printserver.main.utils.LocaleManager;
import com.goeing.printserver.main.utils.MessageUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -13,17 +16,19 @@ import java.awt.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Locale;
/**
* 打印任务搜索面板
*/
@Component
@Slf4j
public class PrintTaskSearchPanel extends JPanel {
public class PrintTaskSearchPanel extends JPanel implements LocaleChangeListener {
private final PrintQueueService printQueueService;
private final PrintHistoryService historyService;
private final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
private String allText;
// UI组件
private JComboBox<String> printerComboBox;
@ -37,7 +42,11 @@ public class PrintTaskSearchPanel extends JPanel {
public PrintTaskSearchPanel(PrintQueueService printQueueService, PrintHistoryService historyService) {
this.printQueueService = printQueueService;
this.historyService = historyService;
this.allText = MessageUtils.getMessage("common.all");
initializeUI();
// 注册语言变更监听器
LocaleManager.getInstance().addLocaleChangeListener(this);
}
/**
@ -56,29 +65,29 @@ public class PrintTaskSearchPanel extends JPanel {
// 打印机选择
gbc.gridx = 0;
gbc.gridy = 0;
searchPanel.add(new JLabel("打印机:"), gbc);
searchPanel.add(new JLabel(MessageUtils.getMessage("search.printer")), gbc);
gbc.gridx = 1;
gbc.weightx = 1.0;
printerComboBox = new JComboBox<>(new String[]{"全部", "打印机1", "打印机2", "打印机3"});
printerComboBox = new JComboBox<>(new String[]{MessageUtils.getMessage("common.all"), "打印机1", "打印机2", "打印机3"});
searchPanel.add(printerComboBox, gbc);
// 状态选择
gbc.gridx = 0;
gbc.gridy = 1;
gbc.weightx = 0.0;
searchPanel.add(new JLabel("状态:"), gbc);
searchPanel.add(new JLabel(MessageUtils.getMessage("search.status")), gbc);
gbc.gridx = 1;
gbc.weightx = 1.0;
statusComboBox = new JComboBox<>(new String[]{"全部", "queued", "processing", "completed", "failed"});
statusComboBox = new JComboBox<>(new String[]{MessageUtils.getMessage("common.all"), "queued", "processing", "completed", "failed"});
searchPanel.add(statusComboBox, gbc);
// 文件URL
gbc.gridx = 0;
gbc.gridy = 2;
gbc.weightx = 0.0;
searchPanel.add(new JLabel("文件URL:"), gbc);
searchPanel.add(new JLabel(MessageUtils.getMessage("search.fileUrl")), gbc);
gbc.gridx = 1;
gbc.weightx = 1.0;
@ -89,7 +98,7 @@ public class PrintTaskSearchPanel extends JPanel {
gbc.gridx = 0;
gbc.gridy = 3;
gbc.gridwidth = 2;
includeHistoryCheckBox = new JCheckBox("包含历史记录");
includeHistoryCheckBox = new JCheckBox(MessageUtils.getMessage("search.includeHistory"));
includeHistoryCheckBox.setSelected(true);
searchPanel.add(includeHistoryCheckBox, gbc);
@ -99,14 +108,21 @@ public class PrintTaskSearchPanel extends JPanel {
gbc.gridwidth = 2;
gbc.weightx = 1.0;
gbc.anchor = GridBagConstraints.CENTER;
JButton searchButton = new JButton("搜索");
JButton searchButton = new JButton(MessageUtils.getMessage("common.search"));
searchButton.addActionListener(e -> performSearch());
searchPanel.add(searchButton, gbc);
add(searchPanel, BorderLayout.NORTH);
// 创建结果表格
String[] columnNames = {"文件URL", "打印机", "状态", "队列时间", "开始时间", "结束时间"};
String[] columnNames = {
MessageUtils.getMessage("table.header.file.url"),
MessageUtils.getMessage("table.header.printer"),
MessageUtils.getMessage("table.header.status"),
MessageUtils.getMessage("table.header.queued.time"),
MessageUtils.getMessage("table.header.start.time"),
MessageUtils.getMessage("table.header.end.time")
};
tableModel = new DefaultTableModel(columnNames, 0) {
@Override
public boolean isCellEditable(int row, int column) {
@ -132,11 +148,11 @@ public class PrintTaskSearchPanel extends JPanel {
// 创建按钮面板
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
JButton detailsButton = new JButton("查看详情");
JButton detailsButton = new JButton(MessageUtils.getMessage("search.viewDetails"));
detailsButton.addActionListener(e -> showTaskDetails());
buttonPanel.add(detailsButton);
JButton clearButton = new JButton("清空结果");
JButton clearButton = new JButton(MessageUtils.getMessage("search.clearResults"));
clearButton.addActionListener(e -> clearResults());
buttonPanel.add(clearButton);
@ -185,10 +201,10 @@ public class PrintTaskSearchPanel extends JPanel {
private void addTasksToResults(List<PrintTask> tasks, String printer, String status, String fileUrl) {
for (PrintTask task : tasks) {
// 应用筛选条件
if (!"全部".equals(printer) && !printer.equals(task.getPrinter())) {
if (!allText.equals(printer) && !printer.equals(task.getPrinter())) {
continue;
}
if (!"全部".equals(status) && !status.equals(task.getStatus())) {
if (!allText.equals(status) && !status.equals(task.getStatus())) {
continue;
}
if (!fileUrl.isEmpty() && !task.getFileUrl().contains(fileUrl)) {
@ -224,7 +240,7 @@ public class PrintTaskSearchPanel extends JPanel {
private void updateStatus() {
int resultCount = tableModel.getRowCount();
if (resultCount == 0) {
JOptionPane.showMessageDialog(this, "没有找到符合条件的任务", "搜索结果", JOptionPane.INFORMATION_MESSAGE);
JOptionPane.showMessageDialog(this, MessageUtils.getMessage("search.noResults"), MessageUtils.getMessage("dialog.title.search.results"), JOptionPane.INFORMATION_MESSAGE);
}
}
@ -268,7 +284,7 @@ public class PrintTaskSearchPanel extends JPanel {
dialog.setVisible(true);
}
} else {
JOptionPane.showMessageDialog(this, "请先选择一个任务", "提示", JOptionPane.INFORMATION_MESSAGE);
JOptionPane.showMessageDialog(this, MessageUtils.getMessage("search.selectTask"), MessageUtils.getMessage("dialog.title.prompt"), JOptionPane.INFORMATION_MESSAGE);
}
}
@ -279,6 +295,17 @@ public class PrintTaskSearchPanel extends JPanel {
* @return 任务对象如果未找到则返回null
*/
private PrintTask findTaskByFileUrl(String fileUrl) {
return findTaskByFileUrl(fileUrl, true);
}
/**
* 根据文件URL查找任务可选是否包含历史记录
*
* @param fileUrl 文件URL
* @param includeHistory 是否包含历史记录
* @return 任务对象如果未找到则返回null
*/
private PrintTask findTaskByFileUrl(String fileUrl, boolean includeHistory) {
// 检查当前任务
PrintTask currentTask = printQueueService.getCurrentTask();
if (currentTask != null && currentTask.getFileUrl().equals(fileUrl)) {
@ -293,7 +320,7 @@ public class PrintTaskSearchPanel extends JPanel {
}
// 检查历史记录中的任务
if (includeHistoryCheckBox.isSelected()) {
if (includeHistory && includeHistoryCheckBox.isSelected()) {
List<PrintTask> historyTasks = historyService.getHistoryByFileUrl(fileUrl);
if (!historyTasks.isEmpty()) {
return historyTasks.get(0);
@ -302,4 +329,76 @@ public class PrintTaskSearchPanel extends JPanel {
return null;
}
/**
* 当语言变更时更新界面
*/
@Override
public void onLocaleChanged(Locale newLocale) {
SwingUtilities.invokeLater(() -> {
// 更新 allText 变量
allText = MessageUtils.getMessage("common.all");
// 更新标签文本
java.awt.Component[] searchPanelComponents = ((JPanel)getComponent(0)).getComponents();
for (java.awt.Component component : searchPanelComponents) {
if (component instanceof JLabel) {
JLabel label = (JLabel) component;
if (label.getText().contains("打印机") || label.getText().contains("Printer")) {
label.setText(MessageUtils.getMessage("search.printer"));
} else if (label.getText().contains("状态") || label.getText().contains("Status")) {
label.setText(MessageUtils.getMessage("search.status"));
} else if (label.getText().contains("URL")) {
label.setText(MessageUtils.getMessage("search.fileUrl"));
}
} else if (component instanceof JCheckBox) {
((JCheckBox) component).setText(MessageUtils.getMessage("search.includeHistory"));
} else if (component instanceof JButton) {
((JButton) component).setText(MessageUtils.getMessage("common.search"));
} else if (component instanceof JComboBox) {
JComboBox<String> comboBox = (JComboBox<String>) component;
if (comboBox.getItemAt(0).toString().equals("全部") ||
comboBox.getItemAt(0).toString().equals("All")) {
comboBox.removeItemAt(0);
comboBox.insertItemAt(MessageUtils.getMessage("common.all"), 0);
comboBox.setSelectedIndex(0);
}
}
}
// 更新按钮文本
JPanel buttonPanel = (JPanel) getComponent(2);
java.awt.Component[] buttonComponents = buttonPanel.getComponents();
for (java.awt.Component component : buttonComponents) {
if (component instanceof JButton) {
JButton button = (JButton) component;
if (button.getText().contains("详情") || button.getText().contains("Details")) {
button.setText(MessageUtils.getMessage("search.viewDetails"));
} else if (button.getText().contains("清空") || button.getText().contains("Clear")) {
button.setText(MessageUtils.getMessage("search.clearResults"));
}
}
}
// 更新表格列名
String[] columnNames = {
MessageUtils.getMessage("table.header.file.url"),
MessageUtils.getMessage("table.header.printer"),
MessageUtils.getMessage("table.header.status"),
MessageUtils.getMessage("table.header.queued.time"),
MessageUtils.getMessage("table.header.start.time"),
MessageUtils.getMessage("table.header.end.time")
};
for (int i = 0; i < columnNames.length; i++) {
resultsTable.getColumnModel().getColumn(i).setHeaderValue(columnNames[i]);
}
resultsTable.getTableHeader().repaint();
});
}
/**
* 关闭资源
*/
public void shutdown() {
LocaleManager.getInstance().removeLocaleChangeListener(this);
}
}

View File

@ -2,6 +2,9 @@ package com.goeing.printserver.main.gui;
import com.goeing.printserver.main.PrintController;
import com.goeing.printserver.main.config.PrintServerConfig;
import com.goeing.printserver.main.utils.LocaleChangeListener;
import com.goeing.printserver.main.utils.LocaleManager;
import com.goeing.printserver.main.utils.MessageUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -10,6 +13,7 @@ import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@ -19,9 +23,9 @@ import java.util.concurrent.TimeUnit;
*/
@Component
@Slf4j
public class PrinterStatusPanel extends JPanel {
public class PrinterStatusPanel extends JPanel implements LocaleChangeListener {
private final PrintController printController;
private PrintController printController;
private final PrintServerConfig config;
private JTable printerTable;
private DefaultTableModel printerModel;
@ -30,11 +34,19 @@ public class PrinterStatusPanel extends JPanel {
// 使用ApplicationEventPublisher来发布事件避免循环依赖
@Autowired
private org.springframework.context.ApplicationEventPublisher eventPublisher;
@Autowired
public PrinterStatusPanel(PrintController printController, PrintServerConfig config) {
this.printController = printController;
public PrinterStatusPanel(PrintServerConfig config) {
this.config = config;
// 注册语言变更监听器
LocaleManager.getInstance().addLocaleChangeListener(this);
}
@Autowired
public void setPrintController(PrintController printController) {
this.printController = printController;
// 在设置完依赖后初始化UI和定时器
initializeUI();
startRefreshTimer();
}
@ -48,19 +60,23 @@ public class PrinterStatusPanel extends JPanel {
// 创建顶部面板
JPanel topPanel = new JPanel(new BorderLayout());
JLabel titleLabel = new JLabel("打印机状态");
JLabel titleLabel = new JLabel(MessageUtils.getMessage("printer.status.title"));
titleLabel.setFont(new Font(titleLabel.getFont().getName(), Font.BOLD, 14));
topPanel.add(titleLabel, BorderLayout.WEST);
// 创建刷新按钮
JButton refreshButton = new JButton("刷新");
JButton refreshButton = new JButton(MessageUtils.getMessage("button.refresh"));
refreshButton.addActionListener(e -> refreshPrinterList());
topPanel.add(refreshButton, BorderLayout.EAST);
add(topPanel, BorderLayout.NORTH);
// 创建表格模型
String[] columnNames = {"打印机名称", "状态", "默认"};
String[] columnNames = {
MessageUtils.getMessage("table.header.printer.name"),
MessageUtils.getMessage("table.header.status"),
MessageUtils.getMessage("table.header.default")
};
printerModel = new DefaultTableModel(columnNames, 0) {
@Override
public boolean isCellEditable(int row, int column) {
@ -120,7 +136,7 @@ public class PrinterStatusPanel extends JPanel {
for (String printer : printers) {
Object[] rowData = new Object[3];
rowData[0] = printer;
rowData[1] = "可用"; // 默认状态为可用
rowData[1] = MessageUtils.getMessage("printer.status.available"); // 默认状态为可用
rowData[2] = printer.equals(defaultPrinter); // 是否为默认打印机
printerModel.addRow(rowData);
}
@ -139,7 +155,7 @@ public class PrinterStatusPanel extends JPanel {
// 发布打印机列表更新事件
eventPublisher.publishEvent(new PrinterListUpdatedEvent(printers));
// 使用debug级别记录日志减少info日志输出
log.debug("已发布打印机列表更新事件,共{}个打印机", printers.size());
log.debug(MessageUtils.getMessage("log.printer.list.updated"), printers.size());
}
/**
@ -162,5 +178,45 @@ public class PrinterStatusPanel extends JPanel {
*/
public void shutdown() {
refreshExecutor.shutdownNow();
LocaleManager.getInstance().removeLocaleChangeListener(this);
}
/**
* 当语言变更时更新界面
*/
@Override
public void onLocaleChanged(Locale newLocale) {
SwingUtilities.invokeLater(() -> {
// 更新标题标签
java.awt.Component[] components = ((JPanel)getComponent(0)).getComponents();
for (java.awt.Component component : components) {
if (component instanceof JLabel) {
((JLabel) component).setText(MessageUtils.getMessage("printer.status.title"));
break;
}
}
// 更新刷新按钮
for (java.awt.Component component : components) {
if (component instanceof JButton) {
((JButton) component).setText(MessageUtils.getMessage("button.refresh"));
break;
}
}
// 更新表格列名
String[] columnNames = {
MessageUtils.getMessage("table.header.printer.name"),
MessageUtils.getMessage("table.header.status"),
MessageUtils.getMessage("table.header.default")
};
for (int i = 0; i < columnNames.length; i++) {
printerTable.getColumnModel().getColumn(i).setHeaderValue(columnNames[i]);
}
printerTable.getTableHeader().repaint();
// 刷新打印机列表以更新状态文本
refreshPrinterList();
});
}
}

View File

@ -0,0 +1,14 @@
package com.goeing.printserver.main.utils;
import java.util.Locale;
/**
* 语言变更监听器接口
*/
public interface LocaleChangeListener {
/**
* 当语言变更时调用
* @param newLocale 新的语言区域
*/
void onLocaleChanged(Locale newLocale);
}

View File

@ -0,0 +1,79 @@
package com.goeing.printserver.main.utils;
import org.springframework.context.i18n.LocaleContextHolder;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
/**
* 语言管理器
*/
public class LocaleManager {
private static final LocaleManager instance = new LocaleManager();
private final List<LocaleChangeListener> listeners = new ArrayList<>();
private Locale currentLocale;
private LocaleManager() {
// 初始化为系统默认语言
currentLocale = Locale.getDefault();
LocaleContextHolder.setLocale(currentLocale);
}
public static LocaleManager getInstance() {
return instance;
}
/**
* 获取当前语言
*/
public Locale getCurrentLocale() {
return currentLocale;
}
/**
* 设置当前语言
*/
public void setCurrentLocale(Locale locale) {
if (locale != null && !locale.equals(currentLocale)) {
this.currentLocale = locale;
LocaleContextHolder.setLocale(locale);
notifyListeners();
}
}
/**
* 添加语言变更监听器
*/
public void addLocaleChangeListener(LocaleChangeListener listener) {
if (listener != null && !listeners.contains(listener)) {
listeners.add(listener);
}
}
/**
* 移除语言变更监听器
*/
public void removeLocaleChangeListener(LocaleChangeListener listener) {
listeners.remove(listener);
}
/**
* 通知所有监听器语言已变更
*/
private void notifyListeners() {
for (LocaleChangeListener listener : listeners) {
listener.onLocaleChanged(currentLocale);
}
}
/**
* 获取支持的语言列表
*/
public List<Locale> getSupportedLocales() {
List<Locale> locales = new ArrayList<>();
locales.add(Locale.CHINESE);
locales.add(Locale.ENGLISH);
return locales;
}
}

View File

@ -0,0 +1,84 @@
package com.goeing.printserver.main.utils;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.beans.factory.annotation.Autowired;
import jakarta.annotation.PostConstruct;
import java.util.Locale;
/**
* 国际化消息工具类
*/
@Component
public class MessageUtils {
private static MessageSource messageSource;
@Autowired
private MessageSource autowiredMessageSource;
@PostConstruct
public void init() {
messageSource = autowiredMessageSource;
// 添加日志确认初始化完成
System.out.println("MessageUtils initialized with messageSource: " + (messageSource != null));
}
/**
* 获取国际化消息
*
* @param code 消息代码
* @return 国际化消息
*/
public static String getMessage(String code) {
return getMessage(code, null);
}
/**
* 获取国际化消息
*
* @param code 消息代码
* @param args 参数
* @return 国际化消息
*/
public static String getMessage(String code, Object[] args) {
return getMessage(code, args, "");
}
/**
* 获取国际化消息
*
* @param code 消息代码
* @param args 参数
* @param defaultMessage 默认消息
* @return 国际化消息
*/
public static String getMessage(String code, Object[] args, String defaultMessage) {
// 添加空检查如果messageSource为null返回默认消息或代码
if (messageSource == null) {
System.err.println("Warning: MessageSource is null when getting message for code: " + code);
return defaultMessage.isEmpty() ? code : defaultMessage;
}
Locale locale = LocaleContextHolder.getLocale();
return messageSource.getMessage(code, args, defaultMessage, locale);
}
/**
* 获取国际化消息指定语言
*
* @param code 消息代码
* @param args 参数
* @param locale 区域
* @return 国际化消息
*/
public static String getMessage(String code, Object[] args, Locale locale) {
// 添加空检查如果messageSource为null返回代码
if (messageSource == null) {
System.err.println("Warning: MessageSource is null when getting message for code: " + code);
return code;
}
return messageSource.getMessage(code, args, "", locale);
}
}

View File

@ -0,0 +1,121 @@
# Default Messages (English)
# Common
common.close=Close
common.save=Save
common.reset=Reset
common.refresh=Refresh
common.search=Search
common.exit=Exit
common.about=About
common.view=View
common.file=File
common.help=Help
common.status=Status
common.available=Available
common.default=Default
common.all=All
common.success=Success
common.error=Error
common.warning=Warning
common.info=Information
common.confirm=Confirm
common.cancel=Cancel
common.yes=Yes
common.no=No
# Main Window
main.title=Print Queue Monitor
main.status.idle=Queue Status: Idle
main.status.processing=Queue Status: Processing Task (Queue has {0} more tasks)
main.status.waiting=Queue Status: Waiting (Queue has {0} tasks)
# Tabs
tab.current=Current Task
tab.queued=Queued Tasks
tab.printers=Printer Status
tab.statistics=Statistics
tab.search=Task Search
tab.settings=Settings
# Table Headers
table.fileUrl=File URL
table.printer=Printer
table.status=Status
table.queuedTime=Queued Time
table.startTime=Start Time
table.endTime=End Time
table.printerName=Printer Name
# Printer Status Panel
printer.status=Printer Status
printer.refresh=Refresh
# Statistics Panel
stats.title=Print Statistics
stats.totalTasks=Total Tasks: {0}
stats.completedTasks=Completed Tasks: {0}
stats.failedTasks=Failed Tasks: {0}
stats.queueSize=Current Queue Size: {0}
stats.uptime=Uptime: {0} hours {1} minutes
stats.currentTime=Current Time: {0}
stats.reset=Reset Statistics
# Search Panel
search.printer=Printer:
search.status=Status:
search.fileUrl=File URL:
search.includeHistory=Include History
search.clearResults=Clear Results
search.viewDetails=View Details
search.noResults=No tasks found matching the criteria
search.selectTask=Please select a task first
# Settings Panel
settings.title=Print Server Settings
settings.defaultPrinter=Default Printer:
settings.maxQueueSize=Max Queue Size:
settings.notifications=Enable System Notifications
settings.startMinimized=Start Minimized to System Tray
settings.autoStart=Start Automatically at Login
settings.save=Save Settings
settings.reset=Reset to Defaults
settings.saved=Settings have been saved
settings.reset.confirm=Are you sure you want to reset all settings to default values?
settings.reset.success=Settings have been reset to default values
settings.save.error=Failed to save settings: {0}
settings.reset.error=Failed to reset settings: {0}
# Dialog titles
dialog.success=Success
dialog.error=Error
dialog.confirm=Confirm
# Log messages
log.settings.save.error=Error occurred while saving settings
log.settings.reset.error=Error occurred while resetting settings
log.settings.applied=Applied settings: Default printer={0}, Max queue size={1}, Enable notifications={2}, Start minimized={3}, Auto start={4}
log.printer.list.update.error=Error occurred while updating printer list
log.printer.list.updated=Updated printer list, total {0} printers
log.printer.list.event.received=Received printer list update event, updated printer dropdown list
# Task Detail Dialog
taskDetail.title=Print Task Details
taskDetail.options=Print Options
# About Dialog
about.title=About Print Server
about.version=Version: {0}
about.buildDate=Build Date: {0}
about.jdkVersion=JDK Version: {0}
about.os=Operating System: {0} {1}
about.copyright=© {0} Goeing. All rights reserved.
# Menu Items
menu.file=File
menu.refresh=Refresh
menu.exit=Exit
menu.view=View
menu.alwaysOnTop=Always on Top
menu.help=Help
menu.about=About

View File

@ -0,0 +1,121 @@
# English Messages
# Common
common.close=Close
common.save=Save
common.reset=Reset
common.refresh=Refresh
common.search=Search
common.exit=Exit
common.about=About
common.view=View
common.file=File
common.help=Help
common.status=Status
common.available=Available
common.default=Default
common.all=All
common.success=Success
common.error=Error
common.warning=Warning
common.info=Information
common.confirm=Confirm
common.cancel=Cancel
common.yes=Yes
common.no=No
# Main Window
main.title=Print Queue Monitor
main.status.idle=Queue Status: Idle
main.status.processing=Queue Status: Processing Task (Queue has {0} more tasks)
main.status.waiting=Queue Status: Waiting (Queue has {0} tasks)
# Tabs
tab.current=Current Task
tab.queued=Queued Tasks
tab.printers=Printer Status
tab.statistics=Statistics
tab.search=Task Search
tab.settings=Settings
# Table Headers
table.fileUrl=File URL
table.printer=Printer
table.status=Status
table.queuedTime=Queued Time
table.startTime=Start Time
table.endTime=End Time
table.printerName=Printer Name
# Printer Status Panel
printer.status=Printer Status
printer.refresh=Refresh
# Statistics Panel
stats.title=Print Statistics
stats.totalTasks=Total Tasks: {0}
stats.completedTasks=Completed Tasks: {0}
stats.failedTasks=Failed Tasks: {0}
stats.queueSize=Current Queue Size: {0}
stats.uptime=Uptime: {0} hours {1} minutes
stats.currentTime=Current Time: {0}
stats.reset=Reset Statistics
# Search Panel
search.printer=Printer:
search.status=Status:
search.fileUrl=File URL:
search.includeHistory=Include History
search.clearResults=Clear Results
search.viewDetails=View Details
search.noResults=No tasks found matching the criteria
search.selectTask=Please select a task first
# Settings Panel
settings.title=Print Server Settings
settings.defaultPrinter=Default Printer:
settings.maxQueueSize=Max Queue Size:
settings.notifications=Enable System Notifications
settings.startMinimized=Start Minimized to System Tray
settings.autoStart=Start Automatically at Login
settings.save=Save Settings
settings.reset=Reset to Defaults
settings.saved=Settings have been saved
settings.reset.confirm=Are you sure you want to reset all settings to default values?
settings.reset.success=Settings have been reset to default values
settings.save.error=Failed to save settings: {0}
settings.reset.error=Failed to reset settings: {0}
# Dialog titles
dialog.success=Success
dialog.error=Error
dialog.confirm=Confirm
# Log messages
log.settings.save.error=Error occurred while saving settings
log.settings.reset.error=Error occurred while resetting settings
log.settings.applied=Applied settings: Default printer={0}, Max queue size={1}, Enable notifications={2}, Start minimized={3}, Auto start={4}
log.printer.list.update.error=Error occurred while updating printer list
log.printer.list.updated=Updated printer list, total {0} printers
log.printer.list.event.received=Received printer list update event, updated printer dropdown list
# Task Detail Dialog
taskDetail.title=Print Task Details
taskDetail.options=Print Options
# About Dialog
about.title=About Print Server
about.version=Version: {0}
about.buildDate=Build Date: {0}
about.jdkVersion=JDK Version: {0}
about.os=Operating System: {0} {1}
about.copyright=© {0} Goeing. All rights reserved.
# Menu Items
menu.file=File
menu.refresh=Refresh
menu.exit=Exit
menu.view=View
menu.alwaysOnTop=Always on Top
menu.help=Help
menu.about=About

View File

@ -0,0 +1,121 @@
# 中文消息 (简体中文)
# 通用
common.close=关闭
common.save=保存
common.reset=重置
common.refresh=刷新
common.search=搜索
common.exit=退出
common.about=关于
common.view=视图
common.file=文件
common.help=帮助
common.status=状态
common.available=可用
common.default=默认
common.all=全部
common.success=成功
common.error=错误
common.warning=警告
common.info=信息
common.confirm=确认
common.cancel=取消
common.yes=
common.no=
# 主窗口
main.title=打印队列监控
main.status.idle=队列状态: 空闲
main.status.processing=队列状态: 正在处理任务 (队列中还有 {0} 个任务)
main.status.waiting=队列状态: 等待处理 (队列中有 {0} 个任务)
# 选项卡
tab.current=当前任务
tab.queued=队列任务
tab.printers=打印机状态
tab.statistics=统计信息
tab.search=任务搜索
tab.settings=设置
# 表格标题
table.fileUrl=文件URL
table.printer=打印机
table.status=状态
table.queuedTime=队列时间
table.startTime=开始时间
table.endTime=结束时间
table.printerName=打印机名称
# 打印机状态面板
printer.status=打印机状态
printer.refresh=刷新
# 统计面板
stats.title=打印统计
stats.totalTasks=总任务数: {0}
stats.completedTasks=已完成任务: {0}
stats.failedTasks=失败任务: {0}
stats.queueSize=当前队列长度: {0}
stats.uptime=运行时间: {0}小时{1}分钟
stats.currentTime=当前时间: {0}
stats.reset=重置统计
# 搜索面板
search.printer=打印机:
search.status=状态:
search.fileUrl=文件URL:
search.includeHistory=包含历史记录
search.clearResults=清空结果
search.viewDetails=查看详情
search.noResults=没有找到符合条件的任务
search.selectTask=请先选择一个任务
# 设置面板
settings.title=打印服务器设置
settings.defaultPrinter=默认打印机:
settings.maxQueueSize=最大队列大小:
settings.notifications=启用系统通知
settings.startMinimized=启动时最小化到系统托盘
settings.autoStart=开机自动启动
settings.save=保存设置
settings.reset=重置默认
settings.saved=设置已保存
settings.reset.confirm=确定要重置所有设置为默认值吗?
settings.reset.success=设置已重置为默认值
settings.save.error=保存设置失败: {0}
settings.reset.error=重置设置失败: {0}
# 对话框标题
dialog.success=成功
dialog.error=错误
dialog.confirm=确认
# 日志消息
log.settings.save.error=保存设置时发生错误
log.settings.reset.error=重置设置时发生错误
log.settings.applied=应用设置: 默认打印机={0}, 最大队列大小={1}, 启用通知={2}, 启动时最小化={3}, 开机自启动={4}
log.printer.list.update.error=更新打印机列表时发生错误
log.printer.list.updated=已更新打印机列表,共{0}个打印机
log.printer.list.event.received=收到打印机列表更新事件,已更新打印机下拉列表
# 任务详情对话框
taskDetail.title=打印任务详情
taskDetail.options=打印选项
# 关于对话框
about.title=关于打印服务器
about.version=版本: {0}
about.buildDate=构建日期: {0}
about.jdkVersion=JDK版本: {0}
about.os=操作系统: {0} {1}
about.copyright=© {0} Goeing. 保留所有权利。
# 菜单项
menu.file=文件
menu.refresh=刷新
menu.exit=退出
menu.view=视图
menu.alwaysOnTop=窗口置顶
menu.help=帮助
menu.about=关于