PedaloLauncher/src/com/minecraftlauncher/ui/InstalledVersionsDialog.java
VIDOKS 8bafe167ac Initial commit - PedaloLauncher with Microsoft Auth
- Modern Microsoft OAuth2 authentication
- Always-available connect button (never gets disabled)
- Dynamic port allocation (25565-25575) for Edge compatibility
- Auto-connect to PEDALO server (pedalo.vidoks.fr:25565)
- Dark theme UI with modern design
- Version management with auto-download
- Fixed browser closure handling

Features:
 Button always clickable - no more gray/disabled state
 Compatible with Microsoft Edge, Chrome, Firefox
 Automatic port conflict resolution
 Clear error messages and user guidance
 Professional launcher interface

Ready for PEDALO server deployment!
2025-09-05 02:00:17 +02:00

277 lines
10 KiB
Java

// src/com/minecraftlauncher/ui/InstalledVersionsDialog.java
package com.minecraftlauncher.ui;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
public class InstalledVersionsDialog extends JDialog {
private static final String MINECRAFT_DIR = System.getProperty("user.home") + "/.minecraft";
private JList<String> versionsList;
private DefaultListModel<String> listModel;
private JButton deleteButton;
private JButton refreshButton;
private JLabel sizeLabel;
public InstalledVersionsDialog(JFrame parent) {
super(parent, "Versions Installées", true);
initializeComponents();
setupLayout();
setupEventListeners();
loadInstalledVersions();
setSize(500, 400);
setLocationRelativeTo(parent);
setResizable(true);
}
private void initializeComponents() {
// Liste des versions
listModel = new DefaultListModel<>();
versionsList = new JList<>(listModel);
versionsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
versionsList.setFont(new Font("SansSerif", Font.PLAIN, 12));
versionsList.setBackground(Color.WHITE);
versionsList.setForeground(Color.BLACK);
versionsList.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));
// Boutons
deleteButton = new JButton("Supprimer");
deleteButton.setEnabled(false);
styleButton(deleteButton, new Color(220, 38, 38), new Color(185, 28, 28)); // Rouge
refreshButton = new JButton("Actualiser");
styleButton(refreshButton, new Color(37, 99, 235), new Color(29, 78, 216)); // Bleu
JButton closeButton = new JButton("Fermer");
styleButton(closeButton, new Color(107, 114, 128), new Color(75, 85, 99)); // Gris
// Label d'information
sizeLabel = new JLabel("Aucune version installée");
sizeLabel.setFont(new Font("SansSerif", Font.PLAIN, 11));
sizeLabel.setForeground(new Color(107, 114, 128));
// Événements des boutons
closeButton.addActionListener(e -> dispose());
}
private void styleButton(JButton button, Color bgColor, Color hoverColor) {
button.setBackground(bgColor);
button.setForeground(Color.WHITE);
button.setFocusPainted(false);
button.setBorderPainted(false);
button.setFont(new Font("SansSerif", Font.BOLD, 11));
button.setCursor(new Cursor(Cursor.HAND_CURSOR));
button.setBorder(BorderFactory.createEmptyBorder(8, 16, 8, 16));
// Effet hover
button.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseEntered(java.awt.event.MouseEvent evt) {
button.setBackground(hoverColor);
}
public void mouseExited(java.awt.event.MouseEvent evt) {
button.setBackground(bgColor);
}
});
}
private void setupLayout() {
setLayout(new BorderLayout(10, 10));
// Panel principal
JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
// Titre
JLabel titleLabel = new JLabel("Versions de Minecraft Installées");
titleLabel.setFont(new Font("SansSerif", Font.BOLD, 16));
titleLabel.setHorizontalAlignment(SwingConstants.CENTER);
titleLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 15, 0));
// Liste avec scroll
JScrollPane scrollPane = new JScrollPane(versionsList);
scrollPane.setBorder(BorderFactory.createLineBorder(new Color(75, 85, 99), 1));
scrollPane.setPreferredSize(new Dimension(400, 250));
// Panel des boutons
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 10, 0));
buttonPanel.add(deleteButton);
buttonPanel.add(refreshButton);
buttonPanel.add(new JButton("Fermer") {{
styleButton(this, new Color(107, 114, 128), new Color(75, 85, 99));
addActionListener(e -> dispose());
}});
// Panel du bas avec info et boutons
JPanel bottomPanel = new JPanel(new BorderLayout());
bottomPanel.add(sizeLabel, BorderLayout.WEST);
bottomPanel.add(buttonPanel, BorderLayout.EAST);
mainPanel.add(titleLabel, BorderLayout.NORTH);
mainPanel.add(scrollPane, BorderLayout.CENTER);
mainPanel.add(bottomPanel, BorderLayout.SOUTH);
add(mainPanel);
}
private void setupEventListeners() {
// Sélection dans la liste
versionsList.addListSelectionListener(e -> {
if (!e.getValueIsAdjusting()) {
deleteButton.setEnabled(versionsList.getSelectedValue() != null);
}
});
// Bouton supprimer
deleteButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
deleteSelectedVersion();
}
});
// Bouton actualiser
refreshButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
loadInstalledVersions();
}
});
}
private void loadInstalledVersions() {
listModel.clear();
List<String> installedVersions = getInstalledVersions();
if (installedVersions.isEmpty()) {
sizeLabel.setText("Aucune version installée");
} else {
for (String version : installedVersions) {
listModel.addElement(version);
}
// Calculer la taille totale
long totalSize = calculateTotalSize(installedVersions);
String sizeText = formatSize(totalSize);
sizeLabel.setText(installedVersions.size() + " version(s) - " + sizeText);
}
}
private List<String> getInstalledVersions() {
List<String> versions = new ArrayList<>();
Path versionsDir = Paths.get(MINECRAFT_DIR, "versions");
try {
if (Files.exists(versionsDir) && Files.isDirectory(versionsDir)) {
Files.list(versionsDir)
.filter(Files::isDirectory)
.forEach(versionDir -> {
String versionName = versionDir.getFileName().toString();
Path jarFile = versionDir.resolve(versionName + ".jar");
Path jsonFile = versionDir.resolve(versionName + ".json");
// Vérifier que les fichiers essentiels existent
if (Files.exists(jarFile) && Files.exists(jsonFile)) {
versions.add(versionName);
}
});
}
} catch (Exception e) {
System.err.println("Erreur lors de la lecture des versions: " + e.getMessage());
}
versions.sort(String::compareTo);
return versions;
}
private long calculateTotalSize(List<String> versions) {
long totalSize = 0;
for (String version : versions) {
Path versionDir = Paths.get(MINECRAFT_DIR, "versions", version);
try {
totalSize += Files.walk(versionDir)
.filter(Files::isRegularFile)
.mapToLong(path -> {
try {
return Files.size(path);
} catch (Exception e) {
return 0;
}
})
.sum();
} catch (Exception e) {
// Ignorer les erreurs pour cette version
}
}
return totalSize;
}
private String formatSize(long bytes) {
if (bytes < 1024) return bytes + " B";
if (bytes < 1024 * 1024) return String.format("%.1f KB", bytes / 1024.0);
if (bytes < 1024 * 1024 * 1024) return String.format("%.1f MB", bytes / (1024.0 * 1024.0));
return String.format("%.1f GB", bytes / (1024.0 * 1024.0 * 1024.0));
}
private void deleteSelectedVersion() {
String selectedVersion = versionsList.getSelectedValue();
if (selectedVersion == null) return;
int result = JOptionPane.showConfirmDialog(
this,
"Voulez-vous vraiment supprimer la version " + selectedVersion + " ?\n\n" +
"Cette action est irréversible.",
"Confirmer la suppression",
JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE
);
if (result == JOptionPane.YES_OPTION) {
if (deleteVersion(selectedVersion)) {
JOptionPane.showMessageDialog(
this,
"Version " + selectedVersion + " Supprimée avec succès.",
"Suppression réussie",
JOptionPane.INFORMATION_MESSAGE
);
loadInstalledVersions(); // Actualiser la liste
} else {
JOptionPane.showMessageDialog(
this,
"Erreur lors de la suppression de la version " + selectedVersion + ".\n" +
"Vérifiez que les fichiers ne sont pas en cours d'utilisation.",
"Erreur de suppression",
JOptionPane.ERROR_MESSAGE
);
}
}
}
private boolean deleteVersion(String version) {
Path versionDir = Paths.get(MINECRAFT_DIR, "versions", version);
try {
// Supprimer récursivement le dossier de la version
Files.walk(versionDir)
.sorted((a, b) -> b.compareTo(a)) // Ordre inverse pour supprimer les fichiers avant les dossiers
.forEach(path -> {
try {
Files.delete(path);
} catch (Exception e) {
System.err.println("Impossible de supprimer: " + path);
}
});
return !Files.exists(versionDir);
} catch (Exception e) {
System.err.println("[ERROR] Erreur lors de la suppression: " + e.getMessage());
return false;
}
}
}