package com.imyeyu.fx.utils; import javafx.collections.ListChangeListener; import javafx.geometry.BoundingBox; import javafx.geometry.Bounds; import javafx.geometry.Rectangle2D; import javafx.stage.Screen; import javafx.stage.Stage; import com.imyeyu.utils.Digest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.List; /** * 多屏操作,可在所有屏幕显示标识,并提供选择参考 * * @author 夜雨 * @since 2021-11-11 21:02 */ public class ScreenFX extends Stage { /** 主屏幕 */ public static final Screen primary = Screen.getPrimary(); /** 所有屏幕 */ public static final List SCREENS; static { SCREENS = new ArrayList<>(Screen.getScreens()); SCREENS.sort((s1, s2) -> (int) (s2.getBounds().getMinX() - s1.getBounds().getMinX())); Screen.getScreens().addListener((ListChangeListener) c -> { SCREENS.clear(); SCREENS.addAll(Screen.getScreens()); SCREENS.sort((s1, s2) -> (int) (s2.getBounds().getMinX() - s1.getBounds().getMinX())); }); } // ---------- 静态功能 ---------- /** * 此屏幕参数 MD5 * * @param screen 屏幕 * @return MD5 */ public static String md5(Screen screen) throws NoSuchAlgorithmException { Rectangle2D r = screen.getBounds(); return Digest.md5(String.valueOf(r.getMinX()) + r.getMinY() + r.getMaxX() + r.getMaxY() + r.getWidth() + r.getHeight()); } /** * 获取坐标所在屏幕 * * @param x 坐标 * @param y 坐标 * @return 屏幕(在所有屏幕之外时返回 null) */ public static Screen getScreenByXY(double x, double y) { for (int i = 0; i < SCREENS.size(); i++) { if (isInScreen(SCREENS.get(i), x, y)) { return SCREENS.get(i); } } return null; } /** * 该坐标是否溢出屏幕 * * @param x 坐标 * @param y 坐标 * @return true 为溢出 */ public static boolean outOfScreen(double x, double y) { return getScreenByXY(x, y) == null; } /** * 判定该坐标是否在屏幕内 * * @param screen 屏幕 * @param x 坐标 * @param y 坐标 * @return true 为存在 */ public static boolean isInScreen(Screen screen, double x, double y) { final Rectangle2D r = screen.getBounds(); return !(x < r.getMinX() || r.getMaxX() < x || y < r.getMinY() || r.getMaxY() < y); } /** * 获取任务栏属性 * * @param screen 屏幕 * @return 任务栏属性 */ public static Bounds getTaskbarBounds(Screen screen) { if (screen == null) { return null; } Rectangle2D sb = screen.getBounds(); Rectangle2D vb = screen.getVisualBounds(); if (sb.getMinY() < vb.getMinY()) { // 顶 return new BoundingBox(sb.getMinX(), sb.getMinY(), sb.getWidth(), sb.getHeight() - vb.getHeight()); } if (vb.getMaxY() < sb.getMaxY()) { // 底 return new BoundingBox(sb.getMinX(), vb.getMaxY(), sb.getWidth(), sb.getHeight() - vb.getHeight()); } if (sb.getMinX() < vb.getMinX()) { // 左 return new BoundingBox(sb.getMinX(), sb.getMinY(), sb.getWidth() - vb.getWidth(), sb.getHeight()); } if (vb.getMaxX() < sb.getMaxX()) { // 右 return new BoundingBox(vb.getMaxX(), sb.getMinY(), sb.getWidth() - vb.getWidth(), sb.getHeight()); } return null; } }