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