Removed FlatLaf (which was used for theming) and replaced it with JavaFX

This commit is contained in:
coolGi
2023-03-17 19:45:18 +10:30
parent 333dc4d0e0
commit 64bed83ddb
5 changed files with 103 additions and 205 deletions
+2 -2
View File
@@ -23,5 +23,5 @@ https://github.com/TheElectronWill/night-config
SVG Salamander for SVG's\
https://github.com/blackears/svgSalamander
FlatLaf for theming (for development testing)\
https://www.formdev.com/flatlaf/
JavaFX for standalone jar and config ui\
https://openjfx.io/
@@ -3,6 +3,7 @@ package com.seibel.lod.core.jar;
import com.formdev.flatlaf.FlatDarkLaf;
import com.formdev.flatlaf.FlatLightLaf;
import com.seibel.lod.core.ModInfo;
import com.seibel.lod.core.config.ConfigBase;
import com.seibel.lod.core.jar.DarkModeDetector;
import com.seibel.lod.core.jar.JarUtils;
import com.seibel.lod.core.jar.gui.BaseJFrame;
@@ -10,12 +11,22 @@ import com.seibel.lod.core.jar.gui.cusomJObject.JBox;
import com.seibel.lod.core.jar.installer.ModrinthGetter;
import com.seibel.lod.core.jar.installer.WebDownloader;
import com.seibel.lod.core.jar.JarDependencySetup;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.LoggerContext;
import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.net.URL;
import java.util.*;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
/**
@@ -24,218 +35,51 @@ import java.util.concurrent.atomic.AtomicReference;
* @author coolGi
*/
// Once built it would be in core/build/libs/DistantHorizons-<Version>-dev-all.jar
public class JarMain {
public class JarMain extends Application {
public static final Logger logger = LogManager.getLogger(JarMain.class.getSimpleName());
public static List<String> programArgs;
public static final boolean isDarkTheme = DarkModeDetector.isDarkMode();
public static boolean isOffline = WebDownloader.netIsAvailable();
@Override
public void start(Stage stage) {
logger.debug("JavaFX version "+System.getProperty("javafx.version"));
Label l = new Label("Hello, JavaFX ");
Scene scene = new Scene(new StackPane(l), 640, 480);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
programArgs = Arrays.asList(args);
if (!programArgs.contains("--no-custom-logger")) {
LoggerContext context = (LoggerContext) LogManager.getContext(false);
try {
context.setConfigLocation(JarUtils.accessFileURI("/log4jConfig.xml"));
} catch (Exception e) {
logger.error("Failed to set log4j config. Try running with the \"--no-custom-logger\" argument");
e.printStackTrace();
}
}
logger.debug("Running "+ModInfo.READABLE_NAME+" standalone jar");
logger.warn("The standalone jar is still a massive WIP, expect bugs");
logger.debug("Java version "+System.getProperty("java.version"));
// logger.debug(programArgs);
// Sets up the local
if (JarUtils.accessFile("assets/lod/lang/" + Locale.getDefault().toString().toLowerCase() + ".json") == null) {
System.out.println("The language setting [" + Locale.getDefault().toString().toLowerCase() + "] isn't allowed yet. Defaulting to [" + Locale.US.toString().toLowerCase() + "].");
logger.warn("The language setting [" + Locale.getDefault().toString().toLowerCase() + "] isn't allowed yet. Defaulting to [" + Locale.US.toString().toLowerCase() + "].");
Locale.setDefault(Locale.US);
}
// Set up the theme
System.setProperty("apple.awt.application.appearance", "system");
if (isDarkTheme)
FlatDarkLaf.setup();
else
FlatLightLaf.setup();
JarDependencySetup.createInitialBindings();
// GitlabGetter.init();
ModrinthGetter.init();
System.out.println("WARNING: The standalone jar still work in progress");
// JOptionPane.showMessageDialog(null, "The GUI for the standalone jar isn't made yet\nIf you want to use the mod then put it in your mods folder", "Distant Horizons", JOptionPane.WARNING_MESSAGE);
// if (getOperatingSystem().equals(OperatingSystem.MACOS)) {
// System.out.println("If you want the installer then please use Linux or Windows for the time being.\nMacOS support/testing will come later on");
// }
// Code will be changed later on to allow resizing and work better
BaseJFrame frame = new BaseJFrame(false, true);
frame.addExtraButtons(frame.getWidth(), 0, true, false);
// Buttons which you want to be stacked vertically should be added with this (`frame.add(obj, this);`)
GridBagConstraints verticalLayout = new GridBagConstraints();
verticalLayout.gridy = GridBagConstraints.RELATIVE;
verticalLayout.gridx = 0;
verticalLayout.fill = GridBagConstraints.HORIZONTAL;
verticalLayout.weightx = 1.0;
verticalLayout.anchor = GridBagConstraints.NORTH;
// Selected download
AtomicReference<String> downloadID = new AtomicReference<String>("");
// This is for the panel to show the update description
JPanel modVersionDescriptionPanel = new JPanel(new GridBagLayout());
JScrollPane modVersionDescriptionScroll = new JScrollPane(modVersionDescriptionPanel, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
// Sets all the layout stuff for it
int modDescriptionWidth = 275;
modVersionDescriptionScroll.setBounds(frame.getWidth()-modDescriptionWidth, 225, modDescriptionWidth, frame.getHeight()-255);
modVersionDescriptionScroll.setBorder(null); // Disables the border
modVersionDescriptionScroll.setWheelScrollingEnabled(true);
// The label
JLabel modVersionDescriptionLabel = new JLabel();
modVersionDescriptionPanel.add(modVersionDescriptionLabel, verticalLayout);
// Finally add it
frame.add(modVersionDescriptionScroll);
// This is for the pannel to select MinecraftVersion
JPanel modMinecraftVersionsPannel = new JPanel(new GridBagLayout());
JScrollPane modMinecraftVersionsScroll = new JScrollPane(modMinecraftVersionsPannel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
// Sets all the layout stuff for it
modMinecraftVersionsScroll.setBounds(0, 225, 125, frame.getHeight()-255);
modMinecraftVersionsScroll.setBorder(null); // Disables the border
modMinecraftVersionsScroll.setWheelScrollingEnabled(true);
// List to store all the buttons
ArrayList<JButton> modMinecraftReleaseButtons = new ArrayList<>();
frame.add(modMinecraftVersionsScroll);
// This is for selecting the mod version
JPanel modVersionsPannel = new JPanel(new GridBagLayout());
JScrollPane modVersionsScroll = new JScrollPane(modVersionsPannel, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
// Sets all the layout stuff for it
modVersionsScroll.setBounds(125, 225, 100, frame.getHeight()-255);
modVersionsScroll.setBorder(null); // Disables the border
modVersionsScroll.setWheelScrollingEnabled(true);
// List to store all the buttons
ArrayList<JButton> modReleaseButtons = new ArrayList<>();
frame.add(modVersionsScroll);
// Add all the buttons
for (String mcVer : ModrinthGetter.mcVersions) {
JButton btn = new JButton(mcVer);
btn.setBackground(UIManager.getColor("Panel.background")); // Does the same thing as removing the background
btn.setBorderPainted(false); // Removes the borders
// btn.setHorizontalAlignment(SwingConstants.LEFT); // Sets the text to be on the left side rather than the center
btn.addActionListener(e -> {
// Clears the selected colors for the rest of the buttons
for (JButton currentBtn : modMinecraftReleaseButtons)
currentBtn.setBackground(UIManager.getColor("Panel.background"));
btn.setBackground(UIManager.getColor("Button.background")); // Sets this to the selected color
// Clears the minecraft version panel
modVersionsPannel.removeAll();
modReleaseButtons.clear();
// Adds all the buttons for the minecraft panel
for (String modID : ModrinthGetter.mcVerToReleaseID.get(mcVer)) {
// No need to comment most of these as it is the same this as before
JButton btnDownload = new JButton(ModrinthGetter.releaseNames.get(modID));
btnDownload.setBackground(UIManager.getColor("Panel.background"));
btnDownload.setBorderPainted(false);
btnDownload.setHorizontalAlignment(SwingConstants.LEFT);
btnDownload.addActionListener(f -> {
downloadID.set(modID);
for (JButton currentBtn : modReleaseButtons)
currentBtn.setBackground(UIManager.getColor("Panel.background"));
btnDownload.setBackground(UIManager.getColor("Button.background"));
modVersionDescriptionLabel.setText(
WebDownloader.formatMarkdownToHtml(
ModrinthGetter.changeLogs.get(modID), modDescriptionWidth-75)
);
modVersionDescriptionPanel.repaint();
});
modVersionsPannel.add(btnDownload, verticalLayout);
modReleaseButtons.add(btnDownload);
}
modVersionsScroll.getVerticalScrollBar().setValue(0); // Reset the scroll bar back to the top
modVersionsPannel.repaint(); // Update the version pannel
frame.validate(); // Update the frame
});
modMinecraftVersionsPannel.add(btn, verticalLayout);
modMinecraftReleaseButtons.add(btn);
}
// Bar at the top
frame.add(new JBox(UIManager.getColor("Separator.foreground"), 0, 220, frame.getWidth(), 5));
// Minecraft version text
JLabel textMcVersionHeader = new JLabel("Minecraft version");
textMcVersionHeader.setBounds(0, 200, 125, 20);
frame.add(textMcVersionHeader);
// Version text
JLabel textVersionHeader = new JLabel("Mod version");
textVersionHeader.setBounds(125, 200, 150, 20);
frame.add(textVersionHeader);
// Stuff for setting the file install path
JFileChooser minecraftDirPop = new JFileChooser();
if (getOperatingSystem().equals(OperatingSystem.WINDOWS))
minecraftDirPop.setCurrentDirectory(new File(System.getenv("APPDATA") + "/.minecraft/mods"));
if (getOperatingSystem().equals(OperatingSystem.LINUX))
minecraftDirPop.setCurrentDirectory(new File(System.getProperty("user.home") + "/.minecraft/mods"));
minecraftDirPop.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
JButton minecraftDirBtn = new JButton("Click to select install path");
minecraftDirBtn.addActionListener(e -> {
if (minecraftDirPop.showOpenDialog(frame) == JFileChooser.APPROVE_OPTION)
minecraftDirBtn.setText(minecraftDirPop.getSelectedFile().toString());
});
minecraftDirBtn.setBounds(230, frame.getHeight()-100, 200, 20);
frame.add(minecraftDirBtn);
// Button for the install button
JButton installMod = new JButton("Install " + ModInfo.READABLE_NAME);
installMod.setBounds(230, frame.getHeight()-70, 200, 20);
installMod.addActionListener(e -> {
if (minecraftDirPop.getSelectedFile() == null) {
JOptionPane.showMessageDialog(frame, "Please select your install directory", ModInfo.READABLE_NAME, JOptionPane.WARNING_MESSAGE);
if (args.length == 0 || Arrays.asList(args).contains("--gui")) {
launch(args);
return;
}
URL downloadPath = ModrinthGetter.downloadUrl.get(downloadID.get());
try {
WebDownloader.downloadAsFile(
downloadPath,
minecraftDirPop.getSelectedFile().toPath().resolve(
ModInfo.NAME + "-" + ModrinthGetter.releaseNames.get(downloadID.get()) + ".jar"
).toFile());
JOptionPane.showMessageDialog(frame, "Installation done. \nYou can now close the installer", ModInfo.READABLE_NAME, JOptionPane.INFORMATION_MESSAGE);
} catch (Exception f) {
JOptionPane.showMessageDialog(frame, "Download failed. Check your internet connection \nStacktrace: " + f.getMessage(), ModInfo.READABLE_NAME, JOptionPane.ERROR_MESSAGE);
}
});
frame.add(installMod);
// Fabric installer
// try {
// WebDownloader.downloadAsFile(new URL("https://maven.fabricmc.net/net/fabricmc/fabric-installer/0.11.0/fabric-installer-0.11.0.jar"), new File(System.getProperty("java.io.tmpdir") + "/fabricInstaller.jar"));
// Runtime.getRuntime().exec("java -jar " + System.getProperty("java.io.tmpdir") + "/fabricInstaller.jar");
// } catch (Exception e) {e.printStackTrace();}
frame.addLogo(); // Has to be run at the end cus of a bug with java swing (it may not be a bug but idk how to fix it so I'll call it a bug)
frame.validate(); // Update to add the widgets
frame.setVisible(true); // Start the ui
}
@@ -251,7 +95,7 @@ public class JarMain {
} else if (os.contains("nix") || os.contains("nux")) {
return OperatingSystem.LINUX;
} else {
return OperatingSystem.NONE; // If you are the 0.00001% who don't use one of these 3 os's then you get light theme
return OperatingSystem.NONE;
}
}
}
@@ -1,8 +1,11 @@
package com.seibel.lod.core.jar;
import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Objects;
/**
* Some general utils for the jar
@@ -14,6 +17,15 @@ public class JarUtils {
public static final File jarFile = new File(JarUtils.class.getProtectionDomain().getCodeSource().getLocation().getPath());
/**
* Gets the URI of a resource
* @param resource Resource location
* @return The URI of that file
* @throws URISyntaxException If the file doesnt exist
*/
public static URI accessFileURI(String resource) throws URISyntaxException {
return Objects.requireNonNull(JarUtils.class.getResource(resource)).toURI();
}
/**
* Get a file within the mods resources
@@ -5,12 +5,15 @@ import com.electronwill.nightconfig.core.io.ParsingMode;
import com.electronwill.nightconfig.json.JsonFormat;
import com.seibel.lod.core.jar.JarUtils;
import com.seibel.lod.core.wrapperInterfaces.config.ILangWrapper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.Locale;
public class LangWrapper implements ILangWrapper {
public static final LangWrapper INSTANCE = new LangWrapper();
private static final Config jsonObject = Config.inMemory();
private static final Logger logger = LogManager.getLogger(LangWrapper.class);
public static void init() {
try {
@@ -20,7 +23,10 @@ public class LangWrapper implements ILangWrapper {
JarUtils.convertInputStreamToString(JarUtils.accessFile("assets/lod/lang/"+ Locale.getDefault().toString().toLowerCase()+".json")),
jsonObject, ParsingMode.REPLACE
);
} catch (Exception e) { e.printStackTrace(); }
} catch (Exception e) {
logger.error("Failed to read lang file");
e.printStackTrace();
}
}
@Override
+36
View File
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
If this file was named log4j2.xml then it would automatically be applied
But, Minecraft has their own which causes the game to break if we try to use ours
So ours is enabled in the code (or more specifically, the JarMain)
-->
<Configuration status="WARN">
<Appenders>
<Console name="console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<File name="all_logs_file" fileName="logs/all.log">
<PatternLayout>
<pattern>%d %p %c{1.} [%t] %m%n</pattern>
</PatternLayout>
</File>
<File name="important_logs_file" fileName="logs/important.log">
<Filters>
<ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout>
<pattern>%d %p %c{1.} [%t] %m%n</pattern>
</PatternLayout>
</File>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="console"/>
<AppenderRef ref="all_logs_file"/>
<AppenderRef ref="important_logs_file"/>
</Root>
</Loggers>
</Configuration>