摸鱼好友神奇,小绿点

如果你的饭搭子与你对坐的话,那么这个程序非常适合。
程序效果
当你们两个同时开启时,小绿点会在屏幕上,当你点击小绿点就会变成红色,提醒你的好友生后有老板或者领导,并且小绿点支持同步位置,你移动你好友屏幕上的绿点也会跟着移到

package org.example;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;

public class SyncFloatingApp {
    private static final int PORT = 6000;
    private static final String BROADCAST_ADDRESS = "255.255.255.255";

    private JWindow window;
    private JButton button;
    private boolean isRed = false;
    private DatagramSocket socket;
    private Point lastPos = new Point(0, 0);
    private boolean isDragging;

    public static void main(String[] args) {
        new SyncFloatingApp().initialize();
    }

    private void initialize() {
        setupUI();
        setupNetwork();
    }

    private void setupUI() {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            e.printStackTrace();
        }

        window = new JWindow();
        window.setAlwaysOnTop(true);
        window.setBackground(new Color(0, 0, 0, 0));

        button = new JButton("●") {
            @Override
            protected void paintComponent(Graphics g) {
                Graphics2D g2 = (Graphics2D) g.create();
                g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                g2.setColor(getBackground());
                g2.fillOval(0, 0, getWidth(), getHeight());
                super.paintComponent(g2);
                g2.dispose();
            }
        };

        // 按钮样式
        button.setOpaque(false);
        button.setContentAreaFilled(false);
        button.setBorderPainted(false);
        button.setForeground(Color.WHITE);
        button.setBackground(Color.GREEN);
        button.setFont(new Font("Arial", Font.BOLD, 24));
        button.setPreferredSize(new Dimension(50, 50));

        // 事件监听
        button.addActionListener(e -> toggleColor());
        setupDragListener();

        window.add(button);
        window.pack();
        window.setLocationRelativeTo(null);
        window.setVisible(true);
    }

    private void setupDragListener() {
        MouseAdapter adapter = new MouseAdapter() {
            private Point dragStart;
            private Timer posTimer = new Timer(50, evt -> sendPosition());

            @Override
            public void mousePressed(MouseEvent e) {
                dragStart = e.getPoint();
                isDragging = true;
            }

            @Override
            public void mouseDragged(MouseEvent e) {
                Point newPos = window.getLocation();
                newPos.translate(e.getX() - dragStart.x, e.getY() - dragStart.y);
                window.setLocation(newPos);

                if (!posTimer.isRunning()) {
                    posTimer.start();
                }
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                isDragging = false;
                sendPosition();
                posTimer.stop();
            }
        };

        button.addMouseListener(adapter);
        button.addMouseMotionListener(adapter);
    }

    private void toggleColor() {
        isRed = !isRed;
        updateColor();
        sendColor();
    }

    private void updateColor() {
        button.setBackground(isRed ? Color.RED : Color.GREEN);
        button.repaint();
    }

    private void setupNetwork() {
        try {
            socket = new DatagramSocket(PORT);
            socket.setBroadcast(true);

            new Thread(() -> {
                byte[] buffer = new byte[1024];
                while (!socket.isClosed()) {
                    try {
                        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
                        socket.receive(packet);
                        processPacket(packet);
                    } catch (Exception e) {
                        if (!socket.isClosed()) e.printStackTrace();
                    }
                }
            }).start();
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    private void processPacket(DatagramPacket packet) {
        String message = new String(packet.getData(), 0, packet.getLength());
        String[] parts = message.split(":");

        if (parts.length == 0) return;

        switch (parts[0]) {
            case "COLOR":
                if (parts.length >= 2) {
                    boolean newRed = "RED".equals(parts[1]);
                    SwingUtilities.invokeLater(() -> {
                        if (newRed != isRed) {
                            isRed = newRed;
                            updateColor();
                        }
                    });
                }
                break;

            case "POS":
                if (parts.length >= 3) {
                    int x = Integer.parseInt(parts[1]);
                    int y = Integer.parseInt(parts[2]);
                    SwingUtilities.invokeLater(() -> {
                        if (!isDragging) {
                            window.setLocation(x, y);
                            lastPos = new Point(x, y);
                        }
                    });
                }
                break;
        }
    }

    private void sendColor() {
        sendMessage("COLOR:" + (isRed ? "RED" : "GREEN"));
    }

    private void sendPosition() {
        Point current = window.getLocation();
        if (!current.equals(lastPos)) {
            sendMessage("POS:" + current.x + ":" + current.y);
            lastPos = current;
        }
    }

    private void sendMessage(String msg) {
        try {
            byte[] data = msg.getBytes();
            DatagramPacket packet = new DatagramPacket(
                data,
                data.length,
                InetAddress.getByName(BROADCAST_ADDRESS),
                PORT
            );
            socket.send(packet);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值