package dialog; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Cursor; import java.awt.FlowLayout; import java.awt.Font; import java.awt.Frame; import java.io.File; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.Clip; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import javax.swing.border.EmptyBorder; /** * 定时关闭对话框 * 使用静态方法避免内存泄漏 */ public class Dingshidialog { // 添加静态标志来跟踪弹窗显示状态 private static volatile boolean isDialogShowing = false; /** * 显示定时关闭对话框 * @param parent 父窗口 * @param countdownTime 倒计时时间(秒) * @param message 提示信息 * @param audioFile MP3文件名(根目录下,无需扩展名) * @return 1-成功 0-失败 */ public static int showTimedDialog(Frame parent, int countdownTime, String message) { // 检查是否已有弹窗在显示 if (isDialogShowing) { System.out.println("已有弹窗在显示,忽略新请求"); return 0; // 返回失败 } TimedDialog dialog = new TimedDialog(parent, countdownTime, message); return dialog.showDialog(); } /** * 内部对话框类,确保使用后能被垃圾回收 */ @SuppressWarnings("serial") private static class TimedDialog extends JDialog { private JLabel countdownLabel; private int remainingTime; private int result = 0; private Clip audioClip; private volatile boolean running = true; public TimedDialog(Frame parent, int countdownTime, String message) { super(parent, "", true); this.remainingTime = countdownTime; initializeUI(message); startCountdown(); } private void initializeUI(String message) { // 设置对话框属性 setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); setResizable(false); // 创建主面板 - 使用不透明背景 JPanel mainPanel = new JPanel(new BorderLayout(10, 10)); mainPanel.setBackground(new Color(15, 28, 48)); mainPanel.setBorder(new EmptyBorder(25, 30, 25, 30)); mainPanel.setOpaque(true); // 创建标题区域 JLabel titleLabel = new JLabel(""); titleLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 20)); titleLabel.setForeground(new Color(52, 152, 219)); titleLabel.setHorizontalAlignment(SwingConstants.CENTER); titleLabel.setBorder(new EmptyBorder(0, 0, 15, 0)); // 创建消息区域面板 JPanel messagePanel = new JPanel(new BorderLayout(10, 10)); messagePanel.setBackground(new Color(15, 28, 48)); messagePanel.setOpaque(true); messagePanel.setBorder(new EmptyBorder(10, 0, 10, 0)); // 创建消息标签 JLabel messageLabel = new JLabel("
" + message + "
"); messageLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 20)); messageLabel.setForeground(new Color(52, 152, 219)); messageLabel.setHorizontalAlignment(SwingConstants.CENTER); // 创建倒计时标签 countdownLabel = new JLabel(remainingTime + "秒后自动关闭"); countdownLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 16)); countdownLabel.setForeground(new Color(231, 76, 60)); countdownLabel.setHorizontalAlignment(SwingConstants.CENTER); countdownLabel.setBorder(new EmptyBorder(15, 0, 0, 0)); // 组装消息区域 messagePanel.add(messageLabel, BorderLayout.CENTER); messagePanel.add(countdownLabel, BorderLayout.SOUTH); // 创建按钮面板 JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 0)); buttonPanel.setBackground(new Color(15, 28, 48)); buttonPanel.setOpaque(true); buttonPanel.setBorder(new EmptyBorder(15, 0, 0, 0)); // 创建立即关闭按钮 JButton closeButton = createStyledButton("立即关闭", new Color(231, 76, 60)); buttonPanel.add(closeButton); // 组装主面板 mainPanel.add(titleLabel, BorderLayout.NORTH); mainPanel.add(messagePanel, BorderLayout.CENTER); mainPanel.add(buttonPanel, BorderLayout.SOUTH); // 设置对话框内容 getContentPane().setBackground(new Color(15, 28, 48)); getContentPane().add(mainPanel); pack(); setLocationRelativeTo(getParent()); // 按钮事件处理 closeButton.addActionListener(e -> { result = 1; disposeDialog(); }); // 对话框关闭事件 addWindowListener(new java.awt.event.WindowAdapter() { @Override public void windowClosing(java.awt.event.WindowEvent e) { disposeDialog(); } @Override public void windowOpened(java.awt.event.WindowEvent e) { // 设置弹窗显示标志 isDialogShowing = true; } @Override public void windowClosed(java.awt.event.WindowEvent e) { // 确保弹窗关闭时重置标志 isDialogShowing = false; } }); } /** * 开始倒计时 */ private void startCountdown() { Thread countdownThread = new Thread(() -> { try { while (running && remainingTime > 0) { Thread.sleep(1000); remainingTime--; SwingUtilities.invokeLater(() -> { if (countdownLabel != null) { countdownLabel.setText( remainingTime + "秒后自动关闭"); } }); if (remainingTime <= 0) { SwingUtilities.invokeLater(() -> { result = 1; disposeDialog(); }); break; } } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }); countdownThread.setDaemon(true); countdownThread.start(); } /** * 播放音频文件 */ private void playAudio(String audioFileName) { if (audioFileName == null || audioFileName.trim().isEmpty()) { return; } try { String filePath = audioFileName.endsWith(".mp3") ? audioFileName : audioFileName + ".mp3"; File audioFile = new File(filePath); if (!audioFile.exists()) { System.err.println("音频文件不存在: " + audioFile.getAbsolutePath()); return; } AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(audioFile); audioClip = AudioSystem.getClip(); audioClip.open(audioInputStream); audioClip.start(); } catch (Exception e) { System.err.println("播放音频失败: " + e.getMessage()); // 实际项目中应使用支持MP3的库 } } /** * 创建样式化按钮 */ private JButton createStyledButton(String text, Color color) { JButton button = new JButton(text); button.setFont(new Font("Microsoft YaHei", Font.BOLD, 14)); button.setBackground(color); button.setForeground(Color.WHITE); button.setFocusPainted(false); button.setBorder(BorderFactory.createEmptyBorder(10, 20, 10, 20)); button.setCursor(new Cursor(Cursor.HAND_CURSOR)); button.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseEntered(java.awt.event.MouseEvent evt) { button.setBackground(brighterColor(color)); } public void mouseExited(java.awt.event.MouseEvent evt) { button.setBackground(color); } }); return button; } private Color brighterColor(Color color) { int r = Math.min(255, color.getRed() + 30); int g = Math.min(255, color.getGreen() + 30); int b = Math.min(255, color.getBlue() + 30); return new Color(r, g, b); } /** * 清理资源 */ private void disposeDialog() { running = false; // 停止音频 if (audioClip != null) { if (audioClip.isRunning()) { audioClip.stop(); } audioClip.close(); audioClip = null; } // 清理UI引用 countdownLabel = null; // 重置弹窗显示标志 isDialogShowing = false; dispose(); } /** * 显示对话框 */ public int showDialog() { // 再次检查标志,防止竞态条件 if (isDialogShowing) { System.out.println("已有弹窗在显示,取消显示"); return 0; } setVisible(true); return result; } } }