package xyz.wbsite.jmacro.tool; import cn.hutool.core.img.ImgUtil; import cn.hutool.core.io.FileUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.log.StaticLog; import xyz.wbsite.jmacro.base.Legend; import xyz.wbsite.jmacro.util.DialogUtil; import xyz.wbsite.jmacro.util.Logger; import javax.swing.*; import javax.swing.filechooser.FileNameExtensionFilter; import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.image.BufferedImage; import java.io.File; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import java.util.prefs.Preferences; /** * 辅助截屏工具 * * @author wangbing * @version 0.0.1 * @since 1.8 */ public class PickLegend extends JFrame { private static final String LAST_PATH = "capture.last.path"; /** * 参照原点x坐标 */ private int originX; /** * 参照原点y坐标 */ private int originY; /** * 全屏幕截图 */ private BufferedImage capture; /** * 背景蒙层 */ private final Color mask = new Color(0, 0, 0, 0.2f); /** * 聚焦框线条 */ private final Stroke focusWindow = new BasicStroke(1.0f); /** * 屏幕截图区域起始坐标 */ private final Point start = new Point(0, 0); /** * 屏幕截图区域结束坐标 */ private final Point end = new Point(0, 0); /** * 个人首选项配置工具 */ private Preferences preferences; /** * 有参照原点的构造器 * * @param originX 原点x * @param originY 原点y * @throws AWTException */ public PickLegend(int originX, int originY, File path) throws AWTException { this(); this.originX = originX; this.originY = originY; this.preferences.put(LAST_PATH, path.isDirectory() ? path.getAbsolutePath() : path.getParent()); } public PickLegend() throws AWTException { init(); } private void init() throws AWTException { setExtendedState(Frame.MAXIMIZED_BOTH); setLocation(0, 0);//位置 setUndecorated(true); setAlwaysOnTop(true); setBackground(mask); setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR)); // 初始化偏好设置 preferences = Preferences.userRoot().node(this.getClass().getName()); // 获取屏幕截图 Robot robot = new Robot(); Toolkit tk = Toolkit.getDefaultToolkit(); capture = robot.createScreenCapture(new Rectangle(0, 0, tk.getScreenSize().width, tk.getScreenSize().height)); // 监听窗口关闭 addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { // 关闭应用时要释放资源 dispose(); System.exit(0);//0正常退出,1非正常退出 } }); addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { super.mousePressed(e); start.setLocation(e.getX(), e.getY()); end.setLocation(e.getX(), e.getY()); Logger.info("起始坐标:{}", start); repaint(); } @Override public void mouseReleased(MouseEvent e) { super.mouseReleased(e); end.setLocation(e.getX(), e.getY()); Logger.info("结束坐标:{}", end); save(); } }); addMouseMotionListener(new MouseMotionAdapter() { @Override public void mouseDragged(MouseEvent e) { super.mouseDragged(e); end.setLocation(e.getX(), e.getY()); repaint(); } }); addKeyListener(new KeyAdapter() { @Override public void keyReleased(KeyEvent e) { switch (e.getKeyCode()) { case KeyEvent.VK_ESCAPE: { StaticLog.info("exit."); close(); } break; } } }); setVisible(true); } @Override public void doLayout() { super.doLayout(); } @Override public void paint(Graphics g) { super.paint(g); Graphics2D g2d = (Graphics2D) g; g2d.drawImage(capture, 0, 0, capture.getWidth(), capture.getHeight(), this); // 在背景图上加个蒙层 g2d.setColor(mask); g2d.fillRect(0, 0, capture.getWidth(), capture.getHeight()); int w = getCaptureWidth(); int h = getCaptureHeight(); if (w > 0 && h > 0) { g2d.setStroke(focusWindow); g2d.setColor(Color.green); g2d.drawRect(getCaptureX(), getCaptureY(), w, h); } } public int getCaptureX() { return (int) Math.min(start.getX(), end.getX()); } public int getCaptureY() { return (int) Math.min(start.getY(), end.getY()); } public int getCaptureWidth() { return (int) Math.abs(start.getX() - end.getX()); } public int getCaptureHeight() { return (int) Math.abs(start.getY() - end.getY()); } public void save() { // 上一次保存目录 String lastPath = preferences.get(LAST_PATH, ""); // 默认文件名 String filename = StrUtil.format("{}.png", System.currentTimeMillis()); JFileChooser jFileChooser = new JFileChooser(); jFileChooser.setFileFilter(new FileNameExtensionFilter("png", "png")); jFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); jFileChooser.setCurrentDirectory(new File(lastPath)); jFileChooser.setSelectedFile(new File(filename)); int returnVal = jFileChooser.showSaveDialog(this); if (returnVal == JFileChooser.APPROVE_OPTION) { File selectedFile = jFileChooser.getSelectedFile(); String legendName = selectedFile.getName(); if (!legendName.endsWith(".png")) { legendName += ".png"; } File parentDir = selectedFile.getParentFile(); String finalLegendName = legendName; // 提取公共的保存逻辑 Runnable saveAction = () -> { File targetFile = new File(parentDir, finalLegendName); doSave(targetFile); close(); }; List existingFiles = FileUtil.loopFiles(Legend.getDefaultBase(), pathname -> pathname.getName().equals(finalLegendName)); if (existingFiles.isEmpty()) { saveAction.run(); } else { DialogUtil.confirm("提示", "存在相同图例,是否覆盖?", result -> { if (result) { saveAction.run(); } else { close(); // 用户取消时也关闭窗口 } }); } } else { close(); // 用户取消选择时关闭窗口 } } private void doSave(File targetFile) { Logger.info("↓↓↓↓↓区域采集↓↓↓↓↓"); Logger.info("图例名称:{}", targetFile.getName().replaceAll("\\.png","")); Logger.info("保存路径 {}", targetFile); ImgUtil.cut(capture, targetFile, new Rectangle( getCaptureX(), getCaptureY(), getCaptureWidth(), getCaptureHeight() )); preferences.put(LAST_PATH, targetFile.getParent()); Logger.info("保存目录 {}", targetFile.getParent()); Logger.info("保存地址 {}", targetFile); Logger.info("用法示例:"); Logger.info("查找图例:findLegend(\"{}\", 0.9)",targetFile.getName().replaceAll("\\.png","")); Logger.info(""); Logger.info("↑↑↑↑↑区域采集↑↑↑↑↑"); } public void close() { setVisible(false); dispose(); } }