连点器在现在很常见,但是也许不简单明了有些要VIP。这里提供一种简单的Java源码为基础,后面提供jar供大家使用。阅读愉快:
下面是代码,只为模板具体要求具体改变。
今天之说只包括鼠标的,关注我之后更新键盘不错过。
import javax.swing.*;
import javax.swing.plaf.basic.BasicButtonUI;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class AutoClickerGUI extends JFrame {
private Robot robot;
private JTextField cpsLeftField, cpsRightField, durationField;
private JComboBox<String> durationUnitComboBox;
private JButton startButton, pauseButton, stopButton, colorButton, settingsButton;
private JLabel timeLabel;
private JRadioButton leftClickOption, rightClickOption, bothClickOption;
private ButtonGroup clickOptions;
private Color backgroundColor = Color.LIGHT_GRAY;
private Color buttonColor = new Color(200, 200, 200);
private Color pauseButtonColor = new Color(255, 100, 100);
private Color continueButtonColor = new Color(100, 255, 100);
private volatile boolean isRunning;
private volatile boolean isPaused;
private ScheduledExecutorService scheduler;
private long timeRemainingMillis;
private long interval;
private int windowWidth = 350;
private int windowHeight = 300;
private String selectedFont = "微软雅黑";
private String selectedLanguage = "English";
private boolean isRoundedButtons = true;
private Map<String, Integer> shortcuts = new HashMap<>();
public AutoClickerGUI() throws AWTException {
robot = new Robot();
loadSettings();
initializeUI();
}
private void initializeUI() {
setTitle("连点器");
setSize(windowWidth, windowHeight);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new GridLayout(11, 2, 5, 5));
timeLabel = new JLabel("剩余时间:00:00", SwingConstants.CENTER);
timeLabel.setFont(new Font(selectedFont, Font.BOLD, 18));
cpsLeftField = new JTextField("10");
cpsRightField = new JTextField("10");
durationField = new JTextField("10");
durationUnitComboBox = new JComboBox<>(new String[]{"毫秒", "秒", "分钟", "小时"});
startButton = createCustomButton("开始", buttonColor);
pauseButton = createCustomButton("暂停", pauseButtonColor);
stopButton = createCustomButton("终止", buttonColor);
colorButton = createCustomButton("选择颜色", buttonColor);
settingsButton = createCustomButton("设置", buttonColor);
leftClickOption = new JRadioButton("左键点击", true);
rightClickOption = new JRadioButton("右键点击");
bothClickOption = new JRadioButton("双键点击");
clickOptions = new ButtonGroup();
clickOptions.add(leftClickOption);
clickOptions.add(rightClickOption);
clickOptions.add(bothClickOption);
add(settingsButton);
add(new JLabel(""));
add(new JLabel("左键CPS:"));
add(cpsLeftField);
add(new JLabel("右键CPS:"));
add(cpsRightField);
add(new JLabel("持续时间:"));
add(durationField);
add(new JLabel("单位:"));
add(durationUnitComboBox);
add(leftClickOption);
add(rightClickOption);
add(bothClickOption);
add(colorButton);
add(startButton);
add(pauseButton);
add(stopButton);
add(timeLabel);
colorButton.addActionListener(this::changeColors);
startButton.addActionListener(this::startClicker);
pauseButton.addActionListener(this::pauseOrResumeClicker);
stopButton.addActionListener(e -> stopClicker());
settingsButton.addActionListener(e -> showSettingsDialog());
setVisible(true);
registerGlobalHotkeys();
}
private JButton createCustomButton(String text, Color color) {
JButton button = new JButton(text);
button.setFont(new Font(selectedFont, Font.PLAIN, 14));
button.setBackground(color);
button.setFocusPainted(false);
button.setBorder(BorderFactory.createEmptyBorder(10, 15, 10, 15));
button.setOpaque(true);
button.setContentAreaFilled(false);
button.setBorderPainted(false);
button.setForeground(Color.BLACK);
button.setUI(new BasicButtonUI() {
@Override
public void paint(Graphics g, JComponent c) {
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(c.getBackground());
if (isRoundedButtons) {
g2.fillRoundRect(0, 0, c.getWidth(), c.getHeight(), 15, 15);
} else {
g2.fillRect(0, 0, c.getWidth(), c.getHeight());
}
super.paint(g, c);
}
});
return button;
}
private void showSettingsDialog() {
JDialog settingsDialog = new JDialog(this, "设置", true);
settingsDialog.setLayout(new GridLayout(8, 2, 10, 10));
settingsDialog.add(new JLabel("窗口宽度:"));
JSlider widthSlider = new JSlider(300, 800, windowWidth);
settingsDialog.add(widthSlider);
settingsDialog.add(new JLabel("窗口高度:"));
JSlider heightSlider = new JSlider(300, 600, windowHeight);
settingsDialog.add(heightSlider);
settingsDialog.add(new JLabel("字体:"));
String[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
JComboBox<String> fontComboBox = new JComboBox<>(fonts);
fontComboBox.setSelectedItem(selectedFont);
settingsDialog.add(fontComboBox);
settingsDialog.add(new JLabel("语言:"));
String[] languages = {"English", "French", "中文"};
JComboBox<String> languageComboBox = new JComboBox<>(languages);
languageComboBox.setSelectedItem(selectedLanguage);
settingsDialog.add(languageComboBox);
settingsDialog.add(new JLabel("按钮形状:"));
String[] shapes = {"方形", "圆形"};
JComboBox<String> shapeComboBox = new JComboBox<>(shapes);
shapeComboBox.setSelectedItem(isRoundedButtons ? "圆形" : "方形");
settingsDialog.add(shapeComboBox);
settingsDialog.add(new JLabel("设置快捷键:"));
JButton setHotkeysButton = new JButton("设置快捷键");
setHotkeysButton.addActionListener(e -> configureHotkeys());
settingsDialog.add(setHotkeysButton);
JButton saveButton = new JButton("保存设置");
saveButton.addActionListener(e -> {
windowWidth = widthSlider.getValue();
windowHeight = heightSlider.getValue();
selectedFont = (String) fontComboBox.getSelectedItem();
selectedLanguage = (String) languageComboBox.getSelectedItem();
isRoundedButtons = "圆形".equals(shapeComboBox.getSelectedItem());
saveSettings();
applySettings();
settingsDialog.dispose();
});
settingsDialog.add(saveButton);
settingsDialog.pack();
settingsDialog.setLocationRelativeTo(this);
settingsDialog.setVisible(true);
}
private void configureHotkeys() {
JDialog hotkeyDialog = new JDialog(this, "设置快捷键", true);
hotkeyDialog.setLayout(new GridLayout(4, 2, 10, 10));
hotkeyDialog.add(new JLabel("开始快捷键:"));
JTextField startKeyField = new JTextField(KeyEvent.getKeyText(shortcuts.getOrDefault("start", KeyEvent.VK_F5)));
hotkeyDialog.add(startKeyField);
hotkeyDialog.add(new JLabel("暂停快捷键:"));
JTextField pauseKeyField = new JTextField(KeyEvent.getKeyText(shortcuts.getOrDefault("pause", KeyEvent.VK_F6)));
hotkeyDialog.add(pauseKeyField);
hotkeyDialog.add(new JLabel("终止快捷键:"));
JTextField stopKeyField = new JTextField(KeyEvent.getKeyText(shortcuts.getOrDefault("stop", KeyEvent.VK_F7)));
hotkeyDialog.add(stopKeyField);
JButton saveHotkeysButton = new JButton("保存快捷键");
saveHotkeysButton.addActionListener(e -> {
shortcuts.put("start", KeyEvent.getExtendedKeyCodeForChar(startKeyField.getText().charAt(0)));
shortcuts.put("pause", KeyEvent.getExtendedKeyCodeForChar(pauseKeyField.getText().charAt(0)));
shortcuts.put("stop", KeyEvent.getExtendedKeyCodeForChar(stopKeyField.getText().charAt(0)));
hotkeyDialog.dispose();
});
hotkeyDialog.add(saveHotkeysButton);
hotkeyDialog.pack();
hotkeyDialog.setLocationRelativeTo(this);
hotkeyDialog.setVisible(true);
}
private void applySettings() {
setSize(windowWidth, windowHeight);
timeLabel.setFont(new Font(selectedFont, Font.BOLD, 18));
startButton.setFont(new Font(selectedFont, Font.PLAIN, 14));
pauseButton.setFont(new Font(selectedFont, Font.PLAIN, 14));
stopButton.setFont(new Font(selectedFont, Font.PLAIN, 14));
colorButton.setFont(new Font(selectedFont, Font.PLAIN, 14));
settingsButton.setFont(new Font(selectedFont, Font.PLAIN, 14));
switch (selectedLanguage) {
case "French":
startButton.setText("Démarrer");
pauseButton.setText("Pause");
stopButton.setText("Arrêter");
colorButton.setText("Choisir la couleur");
settingsButton.setText("Paramètres");
timeLabel.setText("Temps restant : 00:00");
break;
case "中文":
startButton.setText("开始");
pauseButton.setText("暂停");
stopButton.setText("终止");
colorButton.setText("选择颜色");
settingsButton.setText("设置");
timeLabel.setText("剩余时间:00:00");
break;
default:
startButton.setText("Start");
pauseButton.setText("Pause");
stopButton.setText("Stop");
colorButton.setText("Choose Color");
settingsButton.setText("Settings");
timeLabel.setText("Time Remaining: 00:00");
break;
}
repaint();
}
private void registerGlobalHotkeys() {
Toolkit.getDefaultToolkit().addAWTEventListener(event -> {
if (event instanceof KeyEvent) {
KeyEvent keyEvent = (KeyEvent) event;
if (keyEvent.getID() == KeyEvent.KEY_PRESSED) {
if (shortcuts.getOrDefault("start", KeyEvent.VK_F5) == keyEvent.getKeyCode()) {
startClicker(null);
} else if (shortcuts.getOrDefault("pause", KeyEvent.VK_F6) == keyEvent.getKeyCode()) {
pauseOrResumeClicker(null);
} else if (shortcuts.getOrDefault("stop", KeyEvent.VK_F7) == keyEvent.getKeyCode()) {
stopClicker();
}
}
}
}, AWTEvent.KEY_EVENT_MASK);
}
@SuppressWarnings("unchecked")
private void saveSettings() {
try (FileOutputStream fileOut = new FileOutputStream("auto_clicker_settings.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut)) {
out.writeObject(windowWidth);
out.writeObject(windowHeight);
out.writeObject(selectedFont);
out.writeObject(selectedLanguage);
out.writeObject(isRoundedButtons);
out.writeObject(backgroundColor);
out.writeObject(buttonColor);
out.writeObject(shortcuts);
} catch (IOException i) {
i.printStackTrace();
}
}
@SuppressWarnings("unchecked")
private void loadSettings() {
try (FileInputStream fileIn = new FileInputStream("auto_clicker_settings.ser");
ObjectInputStream in = new ObjectInputStream(fileIn)) {
windowWidth = (Integer) in.readObject();
windowHeight = (Integer) in.readObject();
selectedFont = (String) in.readObject();
selectedLanguage = (String) in.readObject();
isRoundedButtons = (Boolean) in.readObject();
backgroundColor = (Color) in.readObject();
buttonColor = (Color) in.readObject();
shortcuts = (Map<String, Integer>) in.readObject();
} catch (IOException | ClassNotFoundException e) {
windowWidth = 350;
windowHeight = 300;
selectedFont = "微软雅黑";
selectedLanguage = "English";
isRoundedButtons = true;
backgroundColor = Color.LIGHT_GRAY;
buttonColor = new Color(200, 200, 200);
shortcuts.put("start", KeyEvent.VK_F5);
shortcuts.put("pause", KeyEvent.VK_F6);
shortcuts.put("stop", KeyEvent.VK_F7);
}
}
private void changeColors(ActionEvent e) {
Color newColor = JColorChooser.showDialog(this, "选择背景颜色", backgroundColor);
if (newColor != null) {
backgroundColor = newColor;
buttonColor = new Color(
Math.min(255, (int)(backgroundColor.getRed() * 1.2)),
Math.min(255, (int)(backgroundColor.getGreen() * 1.2)),
Math.min(255, (int)(backgroundColor.getBlue() * 1.2))
);
continueButtonColor = new Color(
Math.max(0, (int)(buttonColor.getRed() * 0.8)),
Math.max(0, (int)(buttonColor.getGreen() * 0.8)),
Math.max(0, (int)(buttonColor.getBlue() * 0.8))
);
pauseButtonColor = new Color(
255 - continueButtonColor.getRed(),
255 - continueButtonColor.getGreen(),
255 - continueButtonColor.getBlue()
);
getContentPane().setBackground(backgroundColor);
updateButtonColors();
}
}
private void updateButtonColors() {
startButton.setBackground(buttonColor);
stopButton.setBackground(buttonColor);
colorButton.setBackground(buttonColor);
if (isPaused) {
pauseButton.setBackground(continueButtonColor);
} else {
pauseButton.setBackground(pauseButtonColor);
}
}
private void startClicker(ActionEvent e) {
if (isRunning) {
stopClicker();
}
isRunning = true;
isPaused = false;
double cpsLeft, cpsRight, duration;
try {
cpsLeft = Double.parseDouble(cpsLeftField.getText());
cpsRight = Double.parseDouble(cpsRightField.getText());
duration = Double.parseDouble(durationField.getText());
} catch (NumberFormatException ex) {
JOptionPane.showMessageDialog(this, "请输入有效的数字", "输入错误", JOptionPane.ERROR_MESSAGE);
return;
}
String unit = (String) durationUnitComboBox.getSelectedItem();
double multiplier;
switch (unit) {
case "毫秒":
multiplier = 1;
break;
case "秒":
multiplier = 1000;
break;
case "分钟":
multiplier = 60000;
break;
case "小时":
multiplier = 3600000;
break;
default:
throw new IllegalStateException("Unexpected value: " + unit);
}
timeRemainingMillis = (long) (duration * multiplier);
interval = (long) (1000.0 / Math.max(cpsLeft, cpsRight));
scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(() -> {
if (isRunning && !isPaused) {
if (leftClickOption.isSelected() || bothClickOption.isSelected()) {
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
}
if (rightClickOption.isSelected() || bothClickOption.isSelected()) {
robot.mousePress(InputEvent.BUTTON3_DOWN_MASK);
robot.mouseRelease(InputEvent.BUTTON3_DOWN_MASK);
}
updateRemainingTime(interval);
}
}, 0, interval, TimeUnit.MILLISECONDS);
scheduler.schedule(this::stopClicker, timeRemainingMillis, TimeUnit.MILLISECONDS);
}
private void pauseOrResumeClicker(ActionEvent e) {
if (isPaused) {
isPaused = false;
pauseButton.setText(selectedLanguage.equals("中文") ? "暂停" : "Pause");
} else {
isPaused = true;
pauseButton.setText(selectedLanguage.equals("中文") ? "继续" : "Continue");
}
updateButtonColors();
}
private void updateRemainingTime(long interval) {
timeRemainingMillis -= interval;
long seconds = timeRemainingMillis / 1000;
long milliseconds = timeRemainingMillis % 1000;
SwingUtilities.invokeLater(() -> timeLabel.setText("剩余时间:" + seconds + "." + milliseconds + " 秒"));
}
private void stopClicker() {
isRunning = false;
if (scheduler != null) {
scheduler.shutdownNow();
}
timeLabel.setText(selectedLanguage.equals("中文") ? "剩余时间:0.0 秒" : "Time Remaining: 0.0 Seconds");
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
try {
new AutoClickerGUI().setVisible(true);
} catch (AWTException e) {
e.printStackTrace();
}
});
}
}
jar下载链接:
https://wwtg.lanzouo.com/iLXoW27ni0gh
密码:7spx