Вы используете устаревший браузер. Этот и другие сайты могут отображаться в нём некорректно. Вам необходимо обновить браузер или попробовать использовать другой.
Запасайтесь чипсами, ведь если вы пастер, то вы здесь на долго.
Специально для новичков каждый блок был обозначен, если вам не знакомы некоторые слова советую почитать о них в интернете.
Создаем новый проект с использованиемjava 17 если у вас чит экспенсив/экселлент и т.д.
1. Создание приложения с инициализацией всего необходимого.
После создание проекта вам нужно добавить в ваш Main класс всю основу
Java:
package loader.starter;
import loader.objects.SettingObject;
import loader.objects.SquareObject;
import javax.swing.*;
import java.awt.*;
/** @author BossThisGame for product tense
* <p>
* Version 1.0
* <p>
* Minecraft loader
*/
public class Main {
/**
* Главный класс
* Добавление классов
*/
public static void main(String[] args) {
ImageIcon icon = new ImageIcon(Main.class.getResource("/loader/assets/logo.png"));
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("Loader");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setIconImage(icon.getImage());
frame.setSize(707, 509);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
JPanel parentPanel = new JPanel(new CardLayout());
CardLayout cardLayout = (CardLayout) parentPanel.getLayout();
SquareObject mainPanel = new SquareObject(cardLayout, parentPanel);
SettingObject settingsPanel = new SettingObject(cardLayout, parentPanel);
parentPanel.add(mainPanel, "mainPanel");
parentPanel.add(settingsPanel, "settingsPanel");
frame.add(parentPanel);
frame.setVisible(true);
});
}
}
2. Создание рендера/конструкторов
Для начала нужно создать класс с цветами которые мы будем использовать, чтобы каждый раз не искать нужный цвет.
Java:
package loader.utils;
import javax.swing.*;
import java.awt.*;
/** @author BossThisGame for product tense
* <p>
* Version 1.0
* <p>
* Minecraft loader
*/
/**
* Класс, содержащий все цвета которые можно заюзать
*/
public class ColorUtil extends JPanel {
public static Color background = new Color(45, 45, 45);
public static Color headerColor = new Color(29, 29, 31);
public static Color buttonColor1 = new Color(66, 91, 129);
public static Color buttonColor2 = new Color(14, 93, 213);
}
Объект рендера главного меню
Java:
package loader.objects;
import loader.objects.buttons.StartButton;
import loader.utils.ColorUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
/** @author BossThisGame for product tense
* <p>
* Version 1.0
* <p>
* Minecraft loader
*/
/**
* Класс от части всего рендера
*/
public class SquareObject extends JPanel {
private StartButton startButton;
private ImageIcon settingsIcon;
private CardLayout cardLayout;
private JPanel parentPanel;
private boolean isRunning = false;
private boolean isHovered = false;
/**
* Конструктор инициализирует главное меню с кнопкой запуска и иконкой настроек
*
* @param cardLayout макет для переключения меню
* @param parentPanel панель для переключения
*/
public SquareObject(CardLayout cardLayout, JPanel parentPanel) {
this.cardLayout = cardLayout;
this.parentPanel = parentPanel;
/**
* Рендер заднего фона
*/
setBackground(ColorUtil.background);
setLayout(null);
/**
* Рендер кнопки "Запустить"
*/
startButton = new StartButton("Запустить");
startButton.setBackground(ColorUtil.buttonColor1);
startButton.setForeground(Color.WHITE);
startButton.setFont(new Font("Arial", Font.BOLD, 20));
startButton.setPreferredSize(new Dimension(200, 50));
startButton.setBounds((707 - 200) / 2, (509 - 50) / 2 + 50, 200, 50);
add(startButton);
startButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (!isRunning) {
startButton.setBackground(Color.GREEN);
startButton.setText("Ожидайте");
/**
* Запуск майнкрафт в отдельном потоке
*/
new Thread(() -> {
loader.starter.Start.main(new String[]{});
}).start();
isRunning = true;
/**
* Закрытие лоудера через минуту
* Можете поменять значение как вам угодно
*/
Timer timer = new Timer(60000, evt -> {
Window window = SwingUtilities.getWindowAncestor(SquareObject.this);
if (window != null) {
window.dispose();
}
});
timer.setRepeats(false);
timer.start();
}
}
@Override
public void mouseEntered(MouseEvent e) {
isHovered = true;
updateButtonAppearance();
}
@Override
public void mouseExited(MouseEvent e) {
isHovered = false;
updateButtonAppearance();
}
});
settingsIcon = new ImageIcon(SquareObject.class.getResource("/loader/assets/setting.png"));
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
int iconX = getWidth() - 50;
int iconY = 4;
int iconWidth = 47;
int iconHeight = 43;
if (e.getX() >= iconX && e.getX() <= iconX + iconWidth && e.getY() >= iconY && e.getY() <= iconY + iconHeight) {
SwingUtilities.invokeLater(() -> cardLayout.show(parentPanel, "settingsPanel"));
}
}
});
}
/**
* Отрисовка компонентов
*
* @param g объект Graphics для защиты
*/
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
/**
* Рендер полосы сверху
*/
g.setColor(ColorUtil.headerColor);
g.fillRect(0, 0, getWidth(), 50);
/**
* Рендер текста
*/
String versionText = "v1.0";
String text = "Minecraft Loader";
g.setColor(Color.WHITE);
g.setFont(new Font("Arial", Font.BOLD, 40));
FontMetrics titleMetrics = g.getFontMetrics(g.getFont());
int titleX = (getWidth() - titleMetrics.stringWidth(text)) / 2 + 15;
int titleY = titleMetrics.getHeight() - 6;
g.drawString(text, titleX, titleY);
g.setFont(new Font("Arial", Font.BOLD, 20));
FontMetrics metrics = g.getFontMetrics(g.getFont());
int x = getWidth() - metrics.stringWidth(versionText) - 10;
int y = getHeight() - metrics.getHeight() + metrics.getAscent() - 10;
g.drawString(versionText, x, y);
if (settingsIcon != null) {
int iconX = getWidth() - 50;
int iconY = 4;
g.drawImage(settingsIcon.getImage(), iconX, iconY, 47, 43, this);
}
}
private void updateButtonAppearance() {
if (isRunning) {
startButton.setBackground(Color.GREEN);
startButton.setText("Ожидайте");
} else {
if (isHovered) {
startButton.setBackground(ColorUtil.buttonColor2);
} else {
startButton.setBackground(ColorUtil.buttonColor1);
}
}
}
}
Создание класса объекта меню настроек
Java:
package loader.objects;
import loader.utils.ColorUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.URI;
/** @author BossThisGame for product tense
* <p>
* Version 1.0
* <p>
* Minecraft loader
*/
/**
* Объект настроек с возможностью возврата к главному меню
*/
public class SettingObject extends JPanel {
private CardLayout cardLayout;
private JPanel parentPanel;
private int clickableTextX = 20;
private int clickableTextY = 150;
private int clickableTextWidth = 300;
private int clickableTextHeight = 20;
/**
* Отрисовка меню
*/
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
/**
* Рендер фона и элементов интерфейса
*/
setBackground(ColorUtil.background);
setLayout(null);
g.setColor(ColorUtil.headerColor);
g.fillRect(0, 0, getWidth(), 50);
g.setColor(Color.WHITE);
g.setFont(new Font("Arial", Font.PLAIN, 20));
int textX = 20;
int textY = 100;
g.drawString("Информация", textX, textY);
g.drawString("Данный лоудер просто прототип", textX, textY + 30);
g.drawString("Вы можете наложить свою обфускацию по желанию", textX, textY + 60);
FontMetrics fm = g.getFontMetrics();
String clickableText = "Ссылка на канал Tense client";
int textWidth = fm.stringWidth(clickableText);
g.setColor(Color.WHITE);
g.drawString(clickableText, clickableTextX, clickableTextY + 35);
Rectangle clickableArea = new Rectangle(clickableTextX, clickableTextY - fm.getAscent() + 35, textWidth, fm.getHeight());
addClickableArea(clickableArea);
}
/**
* Добавляет область кликабельной зоны
*
* @param clickableArea кликабельная область
*/
private void addClickableArea(Rectangle clickableArea) {
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (clickableArea.contains(e.getPoint())) {
openBrowser("https://www.youtube.com/@rarchik/videos");
}
}
});
}
/**
* Открывает браузер с указанной ссылкой
*
* @param url URL для открытия в браузере
*/
private void openBrowser(String url) {
try {
Desktop.getDesktop().browse(new URI(url));
} catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* Конструктор кнопки возврата
*
* @param cardLayout макет для переключения панелей
* @param parentPanel панель для переключения
*/
public SettingObject(CardLayout cardLayout, JPanel parentPanel) {
this.cardLayout = cardLayout;
this.parentPanel = parentPanel;
JLabel backButton = new JLabel(new ImageIcon(SettingObject.class.getResource("/loader/assets/back_arrow.png")));
backButton.setBounds(10, 10, 100, 100);
backButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
SwingUtilities.invokeLater(() -> cardLayout.show(parentPanel, "mainPanel"));
}
});
add(backButton);
JLabel settingsLabel = new JLabel("Настройки", SwingConstants.CENTER);
settingsLabel.setFont(new Font("Arial", Font.BOLD, 40));
settingsLabel.setForeground(Color.WHITE);
settingsLabel.setBounds(0, 50, getWidth(), 50);
add(settingsLabel);
}
}
Класс кнопки старта
Java:
package loader.objects.buttons;
import loader.utils.ColorUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.RoundRectangle2D;
/** @author BossThisGame for product tense
* <p>
* Version 1.0
* <p>
* Minecraft loader
*/
/**
* Добавление кнопки "Запуск"
*/
public class StartButton extends JButton {
public StartButton(String text) {
super(text);
setContentAreaFilled(false);
setFocusPainted(false);
/**
* Установка стандартных цветов фона и текста
*/
setBackground(ColorUtil.buttonColor1);
setForeground(Color.WHITE);
/**
* Обработчик событий мыши для эффекта наведения
*/
addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
setBackground(ColorUtil.buttonColor2);
}
@Override
public void mouseExited(MouseEvent e) {
setBackground(ColorUtil.buttonColor1);
}
});
/**
* Установка шрифта для текста кнопки
*/
setFont(new Font("Arial", Font.BOLD, 20));
}
/**
* Кастомное рисование компонента кнопки
*
* @param g объект Graphics для защиты
*/
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(getBackground());
g2.fill(new RoundRectangle2D.Float(0, 0, getWidth(), getHeight(), 30, 30));
super.paintComponent(g2);
g2.dispose();
}
/**
* Обновление свойств кнопки
*/
@Override
public void updateUI() {
super.updateUI();
setOpaque(false);
setBorder(BorderFactory.createEmptyBorder(5, 15, 5, 15));
}
}
Я вам не скинул целый уже готовый проект чтобы вы поняли как это делать. Удачи. Так же вы должны учесть, что это не протект лоудер. Здесь нету проверки хвида и т.д. Систему хвида сделать не сложно, поэтому используйте лоудер как хотите
Запасайтесь чипсами, ведь если вы пастер, то вы здесь на долго.
Специально для новичков каждый блок был обозначен, если вам не знакомы некоторые слова советую почитать о них в интернете.
Создаем новый проект с использованиемjava 17 если у вас чит экспенсив/экселлент и т.д.
1. Создание приложения с инициализацией всего необходимого.
После создание проекта вам нужно добавить в ваш Main класс всю основу
Java:
package loader.starter;
import loader.objects.SettingObject;
import loader.objects.SquareObject;
import javax.swing.*;
import java.awt.*;
/** @author BossThisGame for product tense
* <p>
* Version 1.0
* <p>
* Minecraft loader
*/
public class Main {
/**
* Главный класс
* Добавление классов
*/
public static void main(String[] args) {
ImageIcon icon = new ImageIcon(Main.class.getResource("/loader/assets/logo.png"));
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("Loader");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setIconImage(icon.getImage());
frame.setSize(707, 509);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
JPanel parentPanel = new JPanel(new CardLayout());
CardLayout cardLayout = (CardLayout) parentPanel.getLayout();
SquareObject mainPanel = new SquareObject(cardLayout, parentPanel);
SettingObject settingsPanel = new SettingObject(cardLayout, parentPanel);
parentPanel.add(mainPanel, "mainPanel");
parentPanel.add(settingsPanel, "settingsPanel");
frame.add(parentPanel);
frame.setVisible(true);
});
}
}
2. Создание рендера/конструкторов
Для начала нужно создать класс с цветами которые мы будем использовать, чтобы каждый раз не искать нужный цвет.
Java:
package loader.utils;
import javax.swing.*;
import java.awt.*;
/** @author BossThisGame for product tense
* <p>
* Version 1.0
* <p>
* Minecraft loader
*/
/**
* Класс, содержащий все цвета которые можно заюзать
*/
public class ColorUtil extends JPanel {
public static Color background = new Color(45, 45, 45);
public static Color headerColor = new Color(29, 29, 31);
public static Color buttonColor1 = new Color(66, 91, 129);
public static Color buttonColor2 = new Color(14, 93, 213);
}
Объект рендера главного меню
Java:
package loader.objects;
import loader.objects.buttons.StartButton;
import loader.utils.ColorUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
/** @author BossThisGame for product tense
* <p>
* Version 1.0
* <p>
* Minecraft loader
*/
/**
* Класс от части всего рендера
*/
public class SquareObject extends JPanel {
private StartButton startButton;
private ImageIcon settingsIcon;
private CardLayout cardLayout;
private JPanel parentPanel;
private boolean isRunning = false;
private boolean isHovered = false;
/**
* Конструктор инициализирует главное меню с кнопкой запуска и иконкой настроек
*
* @param cardLayout макет для переключения меню
* @param parentPanel панель для переключения
*/
public SquareObject(CardLayout cardLayout, JPanel parentPanel) {
this.cardLayout = cardLayout;
this.parentPanel = parentPanel;
/**
* Рендер заднего фона
*/
setBackground(ColorUtil.background);
setLayout(null);
/**
* Рендер кнопки "Запустить"
*/
startButton = new StartButton("Запустить");
startButton.setBackground(ColorUtil.buttonColor1);
startButton.setForeground(Color.WHITE);
startButton.setFont(new Font("Arial", Font.BOLD, 20));
startButton.setPreferredSize(new Dimension(200, 50));
startButton.setBounds((707 - 200) / 2, (509 - 50) / 2 + 50, 200, 50);
add(startButton);
startButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (!isRunning) {
startButton.setBackground(Color.GREEN);
startButton.setText("Ожидайте");
/**
* Запуск майнкрафт в отдельном потоке
*/
new Thread(() -> {
loader.starter.Start.main(new String[]{});
}).start();
isRunning = true;
/**
* Закрытие лоудера через минуту
* Можете поменять значение как вам угодно
*/
Timer timer = new Timer(60000, evt -> {
Window window = SwingUtilities.getWindowAncestor(SquareObject.this);
if (window != null) {
window.dispose();
}
});
timer.setRepeats(false);
timer.start();
}
}
@Override
public void mouseEntered(MouseEvent e) {
isHovered = true;
updateButtonAppearance();
}
@Override
public void mouseExited(MouseEvent e) {
isHovered = false;
updateButtonAppearance();
}
});
settingsIcon = new ImageIcon(SquareObject.class.getResource("/loader/assets/setting.png"));
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
int iconX = getWidth() - 50;
int iconY = 4;
int iconWidth = 47;
int iconHeight = 43;
if (e.getX() >= iconX && e.getX() <= iconX + iconWidth && e.getY() >= iconY && e.getY() <= iconY + iconHeight) {
SwingUtilities.invokeLater(() -> cardLayout.show(parentPanel, "settingsPanel"));
}
}
});
}
/**
* Отрисовка компонентов
*
* @param g объект Graphics для защиты
*/
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
/**
* Рендер полосы сверху
*/
g.setColor(ColorUtil.headerColor);
g.fillRect(0, 0, getWidth(), 50);
/**
* Рендер текста
*/
String versionText = "v1.0";
String text = "Minecraft Loader";
g.setColor(Color.WHITE);
g.setFont(new Font("Arial", Font.BOLD, 40));
FontMetrics titleMetrics = g.getFontMetrics(g.getFont());
int titleX = (getWidth() - titleMetrics.stringWidth(text)) / 2 + 15;
int titleY = titleMetrics.getHeight() - 6;
g.drawString(text, titleX, titleY);
g.setFont(new Font("Arial", Font.BOLD, 20));
FontMetrics metrics = g.getFontMetrics(g.getFont());
int x = getWidth() - metrics.stringWidth(versionText) - 10;
int y = getHeight() - metrics.getHeight() + metrics.getAscent() - 10;
g.drawString(versionText, x, y);
if (settingsIcon != null) {
int iconX = getWidth() - 50;
int iconY = 4;
g.drawImage(settingsIcon.getImage(), iconX, iconY, 47, 43, this);
}
}
private void updateButtonAppearance() {
if (isRunning) {
startButton.setBackground(Color.GREEN);
startButton.setText("Ожидайте");
} else {
if (isHovered) {
startButton.setBackground(ColorUtil.buttonColor2);
} else {
startButton.setBackground(ColorUtil.buttonColor1);
}
}
}
}
Создание класса объекта меню настроек
Java:
package loader.objects;
import loader.utils.ColorUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.URI;
/** @author BossThisGame for product tense
* <p>
* Version 1.0
* <p>
* Minecraft loader
*/
/**
* Объект настроек с возможностью возврата к главному меню
*/
public class SettingObject extends JPanel {
private CardLayout cardLayout;
private JPanel parentPanel;
private int clickableTextX = 20;
private int clickableTextY = 150;
private int clickableTextWidth = 300;
private int clickableTextHeight = 20;
/**
* Отрисовка меню
*/
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
/**
* Рендер фона и элементов интерфейса
*/
setBackground(ColorUtil.background);
setLayout(null);
g.setColor(ColorUtil.headerColor);
g.fillRect(0, 0, getWidth(), 50);
g.setColor(Color.WHITE);
g.setFont(new Font("Arial", Font.PLAIN, 20));
int textX = 20;
int textY = 100;
g.drawString("Информация", textX, textY);
g.drawString("Данный лоудер просто прототип", textX, textY + 30);
g.drawString("Вы можете наложить свою обфускацию по желанию", textX, textY + 60);
FontMetrics fm = g.getFontMetrics();
String clickableText = "Ссылка на канал Tense client";
int textWidth = fm.stringWidth(clickableText);
g.setColor(Color.WHITE);
g.drawString(clickableText, clickableTextX, clickableTextY + 35);
Rectangle clickableArea = new Rectangle(clickableTextX, clickableTextY - fm.getAscent() + 35, textWidth, fm.getHeight());
addClickableArea(clickableArea);
}
/**
* Добавляет область кликабельной зоны
*
* @param clickableArea кликабельная область
*/
private void addClickableArea(Rectangle clickableArea) {
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (clickableArea.contains(e.getPoint())) {
openBrowser("https://www.youtube.com/@rarchik/videos");
}
}
});
}
/**
* Открывает браузер с указанной ссылкой
*
* @param url URL для открытия в браузере
*/
private void openBrowser(String url) {
try {
Desktop.getDesktop().browse(new URI(url));
} catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* Конструктор кнопки возврата
*
* @param cardLayout макет для переключения панелей
* @param parentPanel панель для переключения
*/
public SettingObject(CardLayout cardLayout, JPanel parentPanel) {
this.cardLayout = cardLayout;
this.parentPanel = parentPanel;
JLabel backButton = new JLabel(new ImageIcon(SettingObject.class.getResource("/loader/assets/back_arrow.png")));
backButton.setBounds(10, 10, 100, 100);
backButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
SwingUtilities.invokeLater(() -> cardLayout.show(parentPanel, "mainPanel"));
}
});
add(backButton);
JLabel settingsLabel = new JLabel("Настройки", SwingConstants.CENTER);
settingsLabel.setFont(new Font("Arial", Font.BOLD, 40));
settingsLabel.setForeground(Color.WHITE);
settingsLabel.setBounds(0, 50, getWidth(), 50);
add(settingsLabel);
}
}
Класс кнопки старта
Java:
package loader.objects.buttons;
import loader.utils.ColorUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.RoundRectangle2D;
/** @author BossThisGame for product tense
* <p>
* Version 1.0
* <p>
* Minecraft loader
*/
/**
* Добавление кнопки "Запуск"
*/
public class StartButton extends JButton {
public StartButton(String text) {
super(text);
setContentAreaFilled(false);
setFocusPainted(false);
/**
* Установка стандартных цветов фона и текста
*/
setBackground(ColorUtil.buttonColor1);
setForeground(Color.WHITE);
/**
* Обработчик событий мыши для эффекта наведения
*/
addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
setBackground(ColorUtil.buttonColor2);
}
@Override
public void mouseExited(MouseEvent e) {
setBackground(ColorUtil.buttonColor1);
}
});
/**
* Установка шрифта для текста кнопки
*/
setFont(new Font("Arial", Font.BOLD, 20));
}
/**
* Кастомное рисование компонента кнопки
*
* @param g объект Graphics для защиты
*/
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(getBackground());
g2.fill(new RoundRectangle2D.Float(0, 0, getWidth(), getHeight(), 30, 30));
super.paintComponent(g2);
g2.dispose();
}
/**
* Обновление свойств кнопки
*/
@Override
public void updateUI() {
super.updateUI();
setOpaque(false);
setBorder(BorderFactory.createEmptyBorder(5, 15, 5, 15));
}
}
Я вам не скинул целый уже готовый проект чтобы вы поняли как это делать. Удачи. Так же вы должны учесть, что это не протект лоудер. Здесь нету проверки хвида и т.д. Систему хвида сделать не сложно, поэтому используйте лоудер как хотите
C:\Users\User\.jdks\corretto-17.0.12\bin\java.exe "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2024.1.4\lib\idea_rt.jar=49658:C:\Program Files\JetBrains\IntelliJ IDEA 2024.1.4\bin" -Dfile.encoding=UTF-8 loader.starter.Main
Error: Could not find or load main class loader.starter.Main
Caused by: java.lang.ClassNotFoundException: loader.starter.Main
C:\Users\User\.jdks\corretto-17.0.12\bin\java.exe "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2024.1.4\lib\idea_rt.jar=49658:C:\Program Files\JetBrains\IntelliJ IDEA 2024.1.4\bin" -Dfile.encoding=UTF-8 loader.starter.Main
Error: Could not find or load main class loader.starter.Main
Caused by: java.lang.ClassNotFoundException: loader.starter.Main
Запасайтесь чипсами, ведь если вы пастер, то вы здесь на долго.
Специально для новичков каждый блок был обозначен, если вам не знакомы некоторые слова советую почитать о них в интернете.
Создаем новый проект с использованиемjava 17 если у вас чит экспенсив/экселлент и т.д.
1. Создание приложения с инициализацией всего необходимого.
После создание проекта вам нужно добавить в ваш Main класс всю основу
Java:
package loader.starter;
import loader.objects.SettingObject;
import loader.objects.SquareObject;
import javax.swing.*;
import java.awt.*;
/** @author BossThisGame for product tense
* <p>
* Version 1.0
* <p>
* Minecraft loader
*/
public class Main {
/**
* Главный класс
* Добавление классов
*/
public static void main(String[] args) {
ImageIcon icon = new ImageIcon(Main.class.getResource("/loader/assets/logo.png"));
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("Loader");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setIconImage(icon.getImage());
frame.setSize(707, 509);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
JPanel parentPanel = new JPanel(new CardLayout());
CardLayout cardLayout = (CardLayout) parentPanel.getLayout();
SquareObject mainPanel = new SquareObject(cardLayout, parentPanel);
SettingObject settingsPanel = new SettingObject(cardLayout, parentPanel);
parentPanel.add(mainPanel, "mainPanel");
parentPanel.add(settingsPanel, "settingsPanel");
frame.add(parentPanel);
frame.setVisible(true);
});
}
}
2. Создание рендера/конструкторов
Для начала нужно создать класс с цветами которые мы будем использовать, чтобы каждый раз не искать нужный цвет.
Java:
package loader.utils;
import javax.swing.*;
import java.awt.*;
/** @author BossThisGame for product tense
* <p>
* Version 1.0
* <p>
* Minecraft loader
*/
/**
* Класс, содержащий все цвета которые можно заюзать
*/
public class ColorUtil extends JPanel {
public static Color background = new Color(45, 45, 45);
public static Color headerColor = new Color(29, 29, 31);
public static Color buttonColor1 = new Color(66, 91, 129);
public static Color buttonColor2 = new Color(14, 93, 213);
}
Объект рендера главного меню
Java:
package loader.objects;
import loader.objects.buttons.StartButton;
import loader.utils.ColorUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
/** @author BossThisGame for product tense
* <p>
* Version 1.0
* <p>
* Minecraft loader
*/
/**
* Класс от части всего рендера
*/
public class SquareObject extends JPanel {
private StartButton startButton;
private ImageIcon settingsIcon;
private CardLayout cardLayout;
private JPanel parentPanel;
private boolean isRunning = false;
private boolean isHovered = false;
/**
* Конструктор инициализирует главное меню с кнопкой запуска и иконкой настроек
*
* @param cardLayout макет для переключения меню
* @param parentPanel панель для переключения
*/
public SquareObject(CardLayout cardLayout, JPanel parentPanel) {
this.cardLayout = cardLayout;
this.parentPanel = parentPanel;
/**
* Рендер заднего фона
*/
setBackground(ColorUtil.background);
setLayout(null);
/**
* Рендер кнопки "Запустить"
*/
startButton = new StartButton("Запустить");
startButton.setBackground(ColorUtil.buttonColor1);
startButton.setForeground(Color.WHITE);
startButton.setFont(new Font("Arial", Font.BOLD, 20));
startButton.setPreferredSize(new Dimension(200, 50));
startButton.setBounds((707 - 200) / 2, (509 - 50) / 2 + 50, 200, 50);
add(startButton);
startButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (!isRunning) {
startButton.setBackground(Color.GREEN);
startButton.setText("Ожидайте");
/**
* Запуск майнкрафт в отдельном потоке
*/
new Thread(() -> {
loader.starter.Start.main(new String[]{});
}).start();
isRunning = true;
/**
* Закрытие лоудера через минуту
* Можете поменять значение как вам угодно
*/
Timer timer = new Timer(60000, evt -> {
Window window = SwingUtilities.getWindowAncestor(SquareObject.this);
if (window != null) {
window.dispose();
}
});
timer.setRepeats(false);
timer.start();
}
}
@Override
public void mouseEntered(MouseEvent e) {
isHovered = true;
updateButtonAppearance();
}
@Override
public void mouseExited(MouseEvent e) {
isHovered = false;
updateButtonAppearance();
}
});
settingsIcon = new ImageIcon(SquareObject.class.getResource("/loader/assets/setting.png"));
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
int iconX = getWidth() - 50;
int iconY = 4;
int iconWidth = 47;
int iconHeight = 43;
if (e.getX() >= iconX && e.getX() <= iconX + iconWidth && e.getY() >= iconY && e.getY() <= iconY + iconHeight) {
SwingUtilities.invokeLater(() -> cardLayout.show(parentPanel, "settingsPanel"));
}
}
});
}
/**
* Отрисовка компонентов
*
* @param g объект Graphics для защиты
*/
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
/**
* Рендер полосы сверху
*/
g.setColor(ColorUtil.headerColor);
g.fillRect(0, 0, getWidth(), 50);
/**
* Рендер текста
*/
String versionText = "v1.0";
String text = "Minecraft Loader";
g.setColor(Color.WHITE);
g.setFont(new Font("Arial", Font.BOLD, 40));
FontMetrics titleMetrics = g.getFontMetrics(g.getFont());
int titleX = (getWidth() - titleMetrics.stringWidth(text)) / 2 + 15;
int titleY = titleMetrics.getHeight() - 6;
g.drawString(text, titleX, titleY);
g.setFont(new Font("Arial", Font.BOLD, 20));
FontMetrics metrics = g.getFontMetrics(g.getFont());
int x = getWidth() - metrics.stringWidth(versionText) - 10;
int y = getHeight() - metrics.getHeight() + metrics.getAscent() - 10;
g.drawString(versionText, x, y);
if (settingsIcon != null) {
int iconX = getWidth() - 50;
int iconY = 4;
g.drawImage(settingsIcon.getImage(), iconX, iconY, 47, 43, this);
}
}
private void updateButtonAppearance() {
if (isRunning) {
startButton.setBackground(Color.GREEN);
startButton.setText("Ожидайте");
} else {
if (isHovered) {
startButton.setBackground(ColorUtil.buttonColor2);
} else {
startButton.setBackground(ColorUtil.buttonColor1);
}
}
}
}
Создание класса объекта меню настроек
Java:
package loader.objects;
import loader.utils.ColorUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.URI;
/** @author BossThisGame for product tense
* <p>
* Version 1.0
* <p>
* Minecraft loader
*/
/**
* Объект настроек с возможностью возврата к главному меню
*/
public class SettingObject extends JPanel {
private CardLayout cardLayout;
private JPanel parentPanel;
private int clickableTextX = 20;
private int clickableTextY = 150;
private int clickableTextWidth = 300;
private int clickableTextHeight = 20;
/**
* Отрисовка меню
*/
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
/**
* Рендер фона и элементов интерфейса
*/
setBackground(ColorUtil.background);
setLayout(null);
g.setColor(ColorUtil.headerColor);
g.fillRect(0, 0, getWidth(), 50);
g.setColor(Color.WHITE);
g.setFont(new Font("Arial", Font.PLAIN, 20));
int textX = 20;
int textY = 100;
g.drawString("Информация", textX, textY);
g.drawString("Данный лоудер просто прототип", textX, textY + 30);
g.drawString("Вы можете наложить свою обфускацию по желанию", textX, textY + 60);
FontMetrics fm = g.getFontMetrics();
String clickableText = "Ссылка на канал Tense client";
int textWidth = fm.stringWidth(clickableText);
g.setColor(Color.WHITE);
g.drawString(clickableText, clickableTextX, clickableTextY + 35);
Rectangle clickableArea = new Rectangle(clickableTextX, clickableTextY - fm.getAscent() + 35, textWidth, fm.getHeight());
addClickableArea(clickableArea);
}
/**
* Добавляет область кликабельной зоны
*
* @param clickableArea кликабельная область
*/
private void addClickableArea(Rectangle clickableArea) {
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (clickableArea.contains(e.getPoint())) {
openBrowser("https://www.youtube.com/@rarchik/videos");
}
}
});
}
/**
* Открывает браузер с указанной ссылкой
*
* @param url URL для открытия в браузере
*/
private void openBrowser(String url) {
try {
Desktop.getDesktop().browse(new URI(url));
} catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* Конструктор кнопки возврата
*
* @param cardLayout макет для переключения панелей
* @param parentPanel панель для переключения
*/
public SettingObject(CardLayout cardLayout, JPanel parentPanel) {
this.cardLayout = cardLayout;
this.parentPanel = parentPanel;
JLabel backButton = new JLabel(new ImageIcon(SettingObject.class.getResource("/loader/assets/back_arrow.png")));
backButton.setBounds(10, 10, 100, 100);
backButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
SwingUtilities.invokeLater(() -> cardLayout.show(parentPanel, "mainPanel"));
}
});
add(backButton);
JLabel settingsLabel = new JLabel("Настройки", SwingConstants.CENTER);
settingsLabel.setFont(new Font("Arial", Font.BOLD, 40));
settingsLabel.setForeground(Color.WHITE);
settingsLabel.setBounds(0, 50, getWidth(), 50);
add(settingsLabel);
}
}
Класс кнопки старта
Java:
package loader.objects.buttons;
import loader.utils.ColorUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.RoundRectangle2D;
/** @author BossThisGame for product tense
* <p>
* Version 1.0
* <p>
* Minecraft loader
*/
/**
* Добавление кнопки "Запуск"
*/
public class StartButton extends JButton {
public StartButton(String text) {
super(text);
setContentAreaFilled(false);
setFocusPainted(false);
/**
* Установка стандартных цветов фона и текста
*/
setBackground(ColorUtil.buttonColor1);
setForeground(Color.WHITE);
/**
* Обработчик событий мыши для эффекта наведения
*/
addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
setBackground(ColorUtil.buttonColor2);
}
@Override
public void mouseExited(MouseEvent e) {
setBackground(ColorUtil.buttonColor1);
}
});
/**
* Установка шрифта для текста кнопки
*/
setFont(new Font("Arial", Font.BOLD, 20));
}
/**
* Кастомное рисование компонента кнопки
*
* @param g объект Graphics для защиты
*/
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(getBackground());
g2.fill(new RoundRectangle2D.Float(0, 0, getWidth(), getHeight(), 30, 30));
super.paintComponent(g2);
g2.dispose();
}
/**
* Обновление свойств кнопки
*/
@Override
public void updateUI() {
super.updateUI();
setOpaque(false);
setBorder(BorderFactory.createEmptyBorder(5, 15, 5, 15));
}
}
Я вам не скинул целый уже готовый проект чтобы вы поняли как это делать. Удачи. Так же вы должны учесть, что это не протект лоудер. Здесь нету проверки хвида и т.д. Систему хвида сделать не сложно, поэтому используйте лоудер как хотите
Запасайтесь чипсами, ведь если вы пастер, то вы здесь на долго.
Специально для новичков каждый блок был обозначен, если вам не знакомы некоторые слова советую почитать о них в интернете.
Создаем новый проект с использованиемjava 17 если у вас чит экспенсив/экселлент и т.д.
1. Создание приложения с инициализацией всего необходимого.
После создание проекта вам нужно добавить в ваш Main класс всю основу
Java:
package loader.starter;
import loader.objects.SettingObject;
import loader.objects.SquareObject;
import javax.swing.*;
import java.awt.*;
/** @author BossThisGame for product tense
* <p>
* Version 1.0
* <p>
* Minecraft loader
*/
public class Main {
/**
* Главный класс
* Добавление классов
*/
public static void main(String[] args) {
ImageIcon icon = new ImageIcon(Main.class.getResource("/loader/assets/logo.png"));
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("Loader");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setIconImage(icon.getImage());
frame.setSize(707, 509);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
JPanel parentPanel = new JPanel(new CardLayout());
CardLayout cardLayout = (CardLayout) parentPanel.getLayout();
SquareObject mainPanel = new SquareObject(cardLayout, parentPanel);
SettingObject settingsPanel = new SettingObject(cardLayout, parentPanel);
parentPanel.add(mainPanel, "mainPanel");
parentPanel.add(settingsPanel, "settingsPanel");
frame.add(parentPanel);
frame.setVisible(true);
});
}
}
2. Создание рендера/конструкторов
Для начала нужно создать класс с цветами которые мы будем использовать, чтобы каждый раз не искать нужный цвет.
Java:
package loader.utils;
import javax.swing.*;
import java.awt.*;
/** @author BossThisGame for product tense
* <p>
* Version 1.0
* <p>
* Minecraft loader
*/
/**
* Класс, содержащий все цвета которые можно заюзать
*/
public class ColorUtil extends JPanel {
public static Color background = new Color(45, 45, 45);
public static Color headerColor = new Color(29, 29, 31);
public static Color buttonColor1 = new Color(66, 91, 129);
public static Color buttonColor2 = new Color(14, 93, 213);
}
Объект рендера главного меню
Java:
package loader.objects;
import loader.objects.buttons.StartButton;
import loader.utils.ColorUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
/** @author BossThisGame for product tense
* <p>
* Version 1.0
* <p>
* Minecraft loader
*/
/**
* Класс от части всего рендера
*/
public class SquareObject extends JPanel {
private StartButton startButton;
private ImageIcon settingsIcon;
private CardLayout cardLayout;
private JPanel parentPanel;
private boolean isRunning = false;
private boolean isHovered = false;
/**
* Конструктор инициализирует главное меню с кнопкой запуска и иконкой настроек
*
* @param cardLayout макет для переключения меню
* @param parentPanel панель для переключения
*/
public SquareObject(CardLayout cardLayout, JPanel parentPanel) {
this.cardLayout = cardLayout;
this.parentPanel = parentPanel;
/**
* Рендер заднего фона
*/
setBackground(ColorUtil.background);
setLayout(null);
/**
* Рендер кнопки "Запустить"
*/
startButton = new StartButton("Запустить");
startButton.setBackground(ColorUtil.buttonColor1);
startButton.setForeground(Color.WHITE);
startButton.setFont(new Font("Arial", Font.BOLD, 20));
startButton.setPreferredSize(new Dimension(200, 50));
startButton.setBounds((707 - 200) / 2, (509 - 50) / 2 + 50, 200, 50);
add(startButton);
startButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (!isRunning) {
startButton.setBackground(Color.GREEN);
startButton.setText("Ожидайте");
/**
* Запуск майнкрафт в отдельном потоке
*/
new Thread(() -> {
loader.starter.Start.main(new String[]{});
}).start();
isRunning = true;
/**
* Закрытие лоудера через минуту
* Можете поменять значение как вам угодно
*/
Timer timer = new Timer(60000, evt -> {
Window window = SwingUtilities.getWindowAncestor(SquareObject.this);
if (window != null) {
window.dispose();
}
});
timer.setRepeats(false);
timer.start();
}
}
@Override
public void mouseEntered(MouseEvent e) {
isHovered = true;
updateButtonAppearance();
}
@Override
public void mouseExited(MouseEvent e) {
isHovered = false;
updateButtonAppearance();
}
});
settingsIcon = new ImageIcon(SquareObject.class.getResource("/loader/assets/setting.png"));
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
int iconX = getWidth() - 50;
int iconY = 4;
int iconWidth = 47;
int iconHeight = 43;
if (e.getX() >= iconX && e.getX() <= iconX + iconWidth && e.getY() >= iconY && e.getY() <= iconY + iconHeight) {
SwingUtilities.invokeLater(() -> cardLayout.show(parentPanel, "settingsPanel"));
}
}
});
}
/**
* Отрисовка компонентов
*
* @param g объект Graphics для защиты
*/
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
/**
* Рендер полосы сверху
*/
g.setColor(ColorUtil.headerColor);
g.fillRect(0, 0, getWidth(), 50);
/**
* Рендер текста
*/
String versionText = "v1.0";
String text = "Minecraft Loader";
g.setColor(Color.WHITE);
g.setFont(new Font("Arial", Font.BOLD, 40));
FontMetrics titleMetrics = g.getFontMetrics(g.getFont());
int titleX = (getWidth() - titleMetrics.stringWidth(text)) / 2 + 15;
int titleY = titleMetrics.getHeight() - 6;
g.drawString(text, titleX, titleY);
g.setFont(new Font("Arial", Font.BOLD, 20));
FontMetrics metrics = g.getFontMetrics(g.getFont());
int x = getWidth() - metrics.stringWidth(versionText) - 10;
int y = getHeight() - metrics.getHeight() + metrics.getAscent() - 10;
g.drawString(versionText, x, y);
if (settingsIcon != null) {
int iconX = getWidth() - 50;
int iconY = 4;
g.drawImage(settingsIcon.getImage(), iconX, iconY, 47, 43, this);
}
}
private void updateButtonAppearance() {
if (isRunning) {
startButton.setBackground(Color.GREEN);
startButton.setText("Ожидайте");
} else {
if (isHovered) {
startButton.setBackground(ColorUtil.buttonColor2);
} else {
startButton.setBackground(ColorUtil.buttonColor1);
}
}
}
}
Создание класса объекта меню настроек
Java:
package loader.objects;
import loader.utils.ColorUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.URI;
/** @author BossThisGame for product tense
* <p>
* Version 1.0
* <p>
* Minecraft loader
*/
/**
* Объект настроек с возможностью возврата к главному меню
*/
public class SettingObject extends JPanel {
private CardLayout cardLayout;
private JPanel parentPanel;
private int clickableTextX = 20;
private int clickableTextY = 150;
private int clickableTextWidth = 300;
private int clickableTextHeight = 20;
/**
* Отрисовка меню
*/
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
/**
* Рендер фона и элементов интерфейса
*/
setBackground(ColorUtil.background);
setLayout(null);
g.setColor(ColorUtil.headerColor);
g.fillRect(0, 0, getWidth(), 50);
g.setColor(Color.WHITE);
g.setFont(new Font("Arial", Font.PLAIN, 20));
int textX = 20;
int textY = 100;
g.drawString("Информация", textX, textY);
g.drawString("Данный лоудер просто прототип", textX, textY + 30);
g.drawString("Вы можете наложить свою обфускацию по желанию", textX, textY + 60);
FontMetrics fm = g.getFontMetrics();
String clickableText = "Ссылка на канал Tense client";
int textWidth = fm.stringWidth(clickableText);
g.setColor(Color.WHITE);
g.drawString(clickableText, clickableTextX, clickableTextY + 35);
Rectangle clickableArea = new Rectangle(clickableTextX, clickableTextY - fm.getAscent() + 35, textWidth, fm.getHeight());
addClickableArea(clickableArea);
}
/**
* Добавляет область кликабельной зоны
*
* @param clickableArea кликабельная область
*/
private void addClickableArea(Rectangle clickableArea) {
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (clickableArea.contains(e.getPoint())) {
openBrowser("https://www.youtube.com/@rarchik/videos");
}
}
});
}
/**
* Открывает браузер с указанной ссылкой
*
* @param url URL для открытия в браузере
*/
private void openBrowser(String url) {
try {
Desktop.getDesktop().browse(new URI(url));
} catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* Конструктор кнопки возврата
*
* @param cardLayout макет для переключения панелей
* @param parentPanel панель для переключения
*/
public SettingObject(CardLayout cardLayout, JPanel parentPanel) {
this.cardLayout = cardLayout;
this.parentPanel = parentPanel;
JLabel backButton = new JLabel(new ImageIcon(SettingObject.class.getResource("/loader/assets/back_arrow.png")));
backButton.setBounds(10, 10, 100, 100);
backButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
SwingUtilities.invokeLater(() -> cardLayout.show(parentPanel, "mainPanel"));
}
});
add(backButton);
JLabel settingsLabel = new JLabel("Настройки", SwingConstants.CENTER);
settingsLabel.setFont(new Font("Arial", Font.BOLD, 40));
settingsLabel.setForeground(Color.WHITE);
settingsLabel.setBounds(0, 50, getWidth(), 50);
add(settingsLabel);
}
}
Класс кнопки старта
Java:
package loader.objects.buttons;
import loader.utils.ColorUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.RoundRectangle2D;
/** @author BossThisGame for product tense
* <p>
* Version 1.0
* <p>
* Minecraft loader
*/
/**
* Добавление кнопки "Запуск"
*/
public class StartButton extends JButton {
public StartButton(String text) {
super(text);
setContentAreaFilled(false);
setFocusPainted(false);
/**
* Установка стандартных цветов фона и текста
*/
setBackground(ColorUtil.buttonColor1);
setForeground(Color.WHITE);
/**
* Обработчик событий мыши для эффекта наведения
*/
addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
setBackground(ColorUtil.buttonColor2);
}
@Override
public void mouseExited(MouseEvent e) {
setBackground(ColorUtil.buttonColor1);
}
});
/**
* Установка шрифта для текста кнопки
*/
setFont(new Font("Arial", Font.BOLD, 20));
}
/**
* Кастомное рисование компонента кнопки
*
* @param g объект Graphics для защиты
*/
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(getBackground());
g2.fill(new RoundRectangle2D.Float(0, 0, getWidth(), getHeight(), 30, 30));
super.paintComponent(g2);
g2.dispose();
}
/**
* Обновление свойств кнопки
*/
@Override
public void updateUI() {
super.updateUI();
setOpaque(false);
setBorder(BorderFactory.createEmptyBorder(5, 15, 5, 15));
}
}
Я вам не скинул целый уже готовый проект чтобы вы поняли как это делать. Удачи. Так же вы должны учесть, что это не протект лоудер. Здесь нету проверки хвида и т.д. Систему хвида сделать не сложно, поэтому используйте лоудер как хотите