From 40d3bd6be1334e2380c8ffa5bd1f1c1aff2f769b Mon Sep 17 00:00:00 2001 From: piitex Date: Tue, 11 Nov 2025 14:11:38 -0600 Subject: [PATCH 1/9] Refactored maps into separate package. --- src/main/java/me/piitex/engine/loaders/ImageLoader.java | 2 +- src/main/java/me/piitex/engine/{ => maps}/LimitedHashMap.java | 2 +- src/main/java/me/piitex/engine/{ => maps}/LimitedTreeMap.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename src/main/java/me/piitex/engine/{ => maps}/LimitedHashMap.java (98%) rename src/main/java/me/piitex/engine/{ => maps}/LimitedTreeMap.java (95%) diff --git a/src/main/java/me/piitex/engine/loaders/ImageLoader.java b/src/main/java/me/piitex/engine/loaders/ImageLoader.java index 011b565..080ab24 100644 --- a/src/main/java/me/piitex/engine/loaders/ImageLoader.java +++ b/src/main/java/me/piitex/engine/loaders/ImageLoader.java @@ -3,7 +3,7 @@ import javafx.embed.swing.SwingFXUtils; import javafx.scene.image.Image; import javafx.scene.image.WritableImage; -import me.piitex.engine.LimitedHashMap; +import me.piitex.engine.maps.LimitedHashMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/me/piitex/engine/LimitedHashMap.java b/src/main/java/me/piitex/engine/maps/LimitedHashMap.java similarity index 98% rename from src/main/java/me/piitex/engine/LimitedHashMap.java rename to src/main/java/me/piitex/engine/maps/LimitedHashMap.java index 1bbb1d0..2ee38a2 100644 --- a/src/main/java/me/piitex/engine/LimitedHashMap.java +++ b/src/main/java/me/piitex/engine/maps/LimitedHashMap.java @@ -1,4 +1,4 @@ -package me.piitex.engine; +package me.piitex.engine.maps; import java.util.Collection; import java.util.HashMap; diff --git a/src/main/java/me/piitex/engine/LimitedTreeMap.java b/src/main/java/me/piitex/engine/maps/LimitedTreeMap.java similarity index 95% rename from src/main/java/me/piitex/engine/LimitedTreeMap.java rename to src/main/java/me/piitex/engine/maps/LimitedTreeMap.java index 3a82029..307ff2b 100644 --- a/src/main/java/me/piitex/engine/LimitedTreeMap.java +++ b/src/main/java/me/piitex/engine/maps/LimitedTreeMap.java @@ -1,4 +1,4 @@ -package me.piitex.engine; +package me.piitex.engine.maps; import java.util.TreeMap; From 0bdbd392fc5151205eac51e964bb8edcf71521b5 Mon Sep 17 00:00:00 2001 From: piitex Date: Tue, 11 Nov 2025 14:12:00 -0600 Subject: [PATCH 2/9] Added font smoothing parameter for text. --- .../me/piitex/engine/overlays/TextFlowOverlay.java | 13 +++++++++++++ .../java/me/piitex/engine/overlays/TextOverlay.java | 11 +++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/main/java/me/piitex/engine/overlays/TextFlowOverlay.java b/src/main/java/me/piitex/engine/overlays/TextFlowOverlay.java index 3dfe6f1..ca0d8ff 100644 --- a/src/main/java/me/piitex/engine/overlays/TextFlowOverlay.java +++ b/src/main/java/me/piitex/engine/overlays/TextFlowOverlay.java @@ -4,6 +4,7 @@ import javafx.scene.Node; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; +import javafx.scene.text.FontSmoothingType; import javafx.scene.text.Text; import javafx.scene.text.TextFlow; import me.piitex.engine.loaders.FontLoader; @@ -16,6 +17,7 @@ public class TextFlowOverlay extends Overlay implements Region { private String text; private Color textFillColor; private FontLoader font; + private FontSmoothingType fontSmoothingType = FontSmoothingType.GRAY; private double width, height, prefWidth, prefHeight, maxWidth, maxHeight; private double scaleWidth, scaleHeight; @@ -88,6 +90,14 @@ public void setFont(FontLoader font) { } } + public FontSmoothingType getFontSmoothingType() { + return fontSmoothingType; + } + + public void setFontSmoothingType(FontSmoothingType fontSmoothingType) { + this.fontSmoothingType = fontSmoothingType; + } + public void add(Overlay overlay) { texts.add(overlay); textFlow.getChildren().add(overlay.assemble()); @@ -135,6 +145,9 @@ public Node render() { if (textFillColor != null) { text1.setTextFill(textFillColor); } + if (fontSmoothingType != null) { + text1.setFontSmoothingType(fontSmoothingType); + } } case HyperLinkOverlay hyperlink -> { if (font != null) { diff --git a/src/main/java/me/piitex/engine/overlays/TextOverlay.java b/src/main/java/me/piitex/engine/overlays/TextOverlay.java index 209e619..d07fbff 100644 --- a/src/main/java/me/piitex/engine/overlays/TextOverlay.java +++ b/src/main/java/me/piitex/engine/overlays/TextOverlay.java @@ -2,6 +2,7 @@ import javafx.scene.Node; import javafx.scene.paint.Color; +import javafx.scene.text.FontSmoothingType; import javafx.scene.text.Text; import me.piitex.engine.loaders.FontLoader; import org.kordamp.ikonli.javafx.FontIcon; @@ -11,6 +12,7 @@ public class TextOverlay extends Overlay { private String string; private Color textFillColor; private FontLoader fontLoader; + private FontSmoothingType fontSmoothingType; private boolean strikeout, underline; @@ -66,6 +68,14 @@ public TextOverlay(String text, Color textFillColor, FontLoader fontLoader, int setY(y); } + public FontSmoothingType getFontSmoothingType() { + return fontSmoothingType; + } + + public void setFontSmoothingType(FontSmoothingType fontSmoothingType) { + this.fontSmoothingType = fontSmoothingType; + } + @Override public Node render() { if (node instanceof FontIcon icon) { @@ -75,6 +85,7 @@ public Node render() { } else if (node instanceof Text text) { // If text is set, render a Text node. text.setText(string); + text.setFontSmoothingType(fontSmoothingType); if (textFillColor != null) { text.setFill(textFillColor); } From d77360abc77c5433eca12007e2d04d39dc023398 Mon Sep 17 00:00:00 2001 From: piitex Date: Tue, 11 Nov 2025 14:12:54 -0600 Subject: [PATCH 3/9] Attached window instance to Renderer. --- src/main/java/me/piitex/engine/Renderer.java | 10 ++++++++++ src/main/java/me/piitex/engine/Window.java | 1 + 2 files changed, 11 insertions(+) diff --git a/src/main/java/me/piitex/engine/Renderer.java b/src/main/java/me/piitex/engine/Renderer.java index eebac32..10593c6 100644 --- a/src/main/java/me/piitex/engine/Renderer.java +++ b/src/main/java/me/piitex/engine/Renderer.java @@ -29,6 +29,7 @@ public class Renderer extends Element { private Color borderColor; private double borderWidth = 1; private final List styles = new ArrayList<>(); + private Window window; // Handlers for events private IRendererKey iRendererKey; @@ -146,6 +147,15 @@ public void addStyle(String style) { styles.add(style); } + public Window getWindow() { + return window; + } + + public void setWindow(Window window) { + this.window = window; + } + + public TreeMap getElements() { return elements; } diff --git a/src/main/java/me/piitex/engine/Window.java b/src/main/java/me/piitex/engine/Window.java index fa33816..86bfe21 100644 --- a/src/main/java/me/piitex/engine/Window.java +++ b/src/main/java/me/piitex/engine/Window.java @@ -301,6 +301,7 @@ public void addContainer(Container container, int index) { addContainer(current, i); } containers.put(index, container); + container.setWindow(this); // Store window reference. Node assemble = container.assemble(); From 36d71014e4ebdcb04d9896856e8c0dc2ea0a56ad Mon Sep 17 00:00:00 2001 From: piitex Date: Tue, 11 Nov 2025 14:13:59 -0600 Subject: [PATCH 4/9] Added parameter to disable antialiasing. --- src/main/java/me/piitex/engine/Window.java | 11 +++++++++++ src/main/java/me/piitex/engine/WindowBuilder.java | 9 +++++++++ 2 files changed, 20 insertions(+) diff --git a/src/main/java/me/piitex/engine/Window.java b/src/main/java/me/piitex/engine/Window.java index 86bfe21..d5111ef 100644 --- a/src/main/java/me/piitex/engine/Window.java +++ b/src/main/java/me/piitex/engine/Window.java @@ -21,6 +21,8 @@ import me.piitex.engine.layouts.Layout; import me.piitex.engine.loaders.ImageLoader; import me.piitex.engine.overlays.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.LinkedList; import java.util.Map; @@ -86,11 +88,14 @@ public class Window { private final boolean scale; private final boolean focused; + private boolean antialiasing; private TreeMap containers = new TreeMap<>(); private Container currentPopup = null; private IWindowResize windowResize; + private static final Logger logger = LoggerFactory.getLogger(Window.class); + /** * Constructs a Window instance using properties defined in a {@link WindowBuilder}. * This allows for a flexible and readable way to configure window properties. @@ -125,6 +130,7 @@ public Window(WindowBuilder builder) { this.maximized = builder.isMaximized(); this.focused = builder.isFocused(); this.scale = builder.isScale(); + this.antialiasing = builder.isAntialiasing(); buildStage(); // Display stage. @@ -157,6 +163,11 @@ protected void buildStage() { Scale scale = new Scale(getWidthScale(), getHeightScale(), 0, 0); root.getTransforms().setAll(scale); } + if (!antialiasing) { + logger.warn("Forced disabled anti-aliasing."); + System.setProperty("prism.lcdtext", "false"); + System.setProperty("prism.subpixeltext", "false"); + } handleWindowScaling(stage); diff --git a/src/main/java/me/piitex/engine/WindowBuilder.java b/src/main/java/me/piitex/engine/WindowBuilder.java index 3a5a18f..e1433ce 100644 --- a/src/main/java/me/piitex/engine/WindowBuilder.java +++ b/src/main/java/me/piitex/engine/WindowBuilder.java @@ -33,6 +33,7 @@ public class WindowBuilder { private boolean maximized = false; private boolean focused = true; private boolean scale = true; + private boolean antialiasing = true; /** * Starts the building process for a new Window with a required title. @@ -130,6 +131,11 @@ public WindowBuilder setScale(boolean scale) { return this; } + public WindowBuilder setAntiAliasing(boolean aliasing) { + this.antialiasing = aliasing; + return this; + } + /** * Constructs and returns a new {@link Window} object based on the builder's configurations. * @return A new Window instance. @@ -182,4 +188,7 @@ public boolean isScale() { return scale; } + public boolean isAntialiasing() { + return antialiasing; + } } From b8c4f37c2a7555e1a948fd20f129d852825e0585 Mon Sep 17 00:00:00 2001 From: piitex Date: Tue, 11 Nov 2025 14:15:16 -0600 Subject: [PATCH 5/9] Added parameter to handle close events when closing a window. --- src/main/java/me/piitex/engine/Window.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/me/piitex/engine/Window.java b/src/main/java/me/piitex/engine/Window.java index d5111ef..4f240a3 100644 --- a/src/main/java/me/piitex/engine/Window.java +++ b/src/main/java/me/piitex/engine/Window.java @@ -472,8 +472,12 @@ public void clear(boolean render) { * Closes the JavaFX Stage associated with this window. * A garbage collection hint is provided to the JVM. */ - public void close() { + public void close(boolean handleEvent) { if (stage != null) { + if (!handleEvent) { + stage.setOnHidden(null); + stage.setOnCloseRequest(null); + } stage.close(); } } From 76f7d83bc3a1ebe1f396c2752e99ad8141579e09 Mon Sep 17 00:00:00 2001 From: piitex Date: Tue, 11 Nov 2025 14:15:56 -0600 Subject: [PATCH 6/9] Updated pom version. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 446ec42..9b0cf5e 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ me.piitex.engine ren-engine - 1.0.5-SNAPSHOT + 1.0.6-SNAPSHOT RenEngine From f83684ac262f44627baaedbea9148e76c36ddda3 Mon Sep 17 00:00:00 2001 From: piitex Date: Wed, 12 Nov 2025 08:26:41 -0600 Subject: [PATCH 7/9] Added request property mapping. --- src/main/java/me/piitex/os/FileDownloader.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/java/me/piitex/os/FileDownloader.java b/src/main/java/me/piitex/os/FileDownloader.java index 80c6cc1..f46e729 100644 --- a/src/main/java/me/piitex/os/FileDownloader.java +++ b/src/main/java/me/piitex/os/FileDownloader.java @@ -7,9 +7,12 @@ import java.io.*; import java.net.HttpURLConnection; +import java.net.URI; import java.net.URL; import java.net.URLConnection; import java.util.Collections; +import java.util.HashMap; +import java.util.Map; import java.util.Set; import java.util.concurrent.*; @@ -20,6 +23,8 @@ public class FileDownloader { private final ConcurrentMap activeConnections = new ConcurrentHashMap<>(); private final Set listeners = Collections.newSetFromMap(new ConcurrentHashMap<>()); + private final Map requestProperties = new HashMap<>(); + /** * Initializes the FileDownloader and its thread pool. */ @@ -47,9 +52,11 @@ public void startDownload(String fileUrl, File outputFile) { private void performDownload(String fileUrl, File outputFile) { DownloadInfo info = null; try { - URL url = new URL(fileUrl); + URL url = new URI(fileUrl).toURL(); URLConnection connection = url.openConnection(); connection.setConnectTimeout(5000); + requestProperties.forEach(connection::setRequestProperty); + activeConnections.put(fileUrl, connection); // Store the connection long fileSize = connection.getContentLengthLong(); @@ -152,6 +159,10 @@ public long getRemoteFileSize(String fileUrl) throws IOException { return connection.getContentLengthLong(); } + public void addRequestProperty(String key, String value) { + requestProperties.put(key, value); + } + public void addDownloadListener(DownloadListener listener) { this.listeners.add(listener); logger.debug("DownloadListener added: {}", listener.getClass().getSimpleName()); From 25432d64a36d66d61484cb34d5367606e56b26c3 Mon Sep 17 00:00:00 2001 From: piitex Date: Wed, 12 Nov 2025 08:27:07 -0600 Subject: [PATCH 8/9] Added utility for downloading GitHub releases. --- src/main/java/me/piitex/os/GitHubUtil.java | 98 ++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 src/main/java/me/piitex/os/GitHubUtil.java diff --git a/src/main/java/me/piitex/os/GitHubUtil.java b/src/main/java/me/piitex/os/GitHubUtil.java new file mode 100644 index 0000000..523f542 --- /dev/null +++ b/src/main/java/me/piitex/os/GitHubUtil.java @@ -0,0 +1,98 @@ +package me.piitex.os; + +import me.piitex.os.FileDownloader; +import org.json.JSONArray; +import org.json.JSONObject; + +import java.io.*; +import java.net.HttpURLConnection; +import java.net.URL; + +/** + * Utility for GitHub REST API. Used for automatically updating and pulling information from releases and assets. + */ +public class GitHubUtil { + private final String repositoryUrl; //https://api.github.com/repos/owner/repo/ + + /** + * Initializes the base url for the repository. To get the repository link, use the following format. + *
+     *     https://api.github.com/repos/$OWNER/$REPO/
+     * 
+ * @param repositoryUrl The GitHub REST api repository link. + */ + public GitHubUtil(String repositoryUrl) { + this.repositoryUrl = repositoryUrl; + } + + /** + * Gathers the latest release of the repository into a {@link JSONObject}. + * @return {@link JSONObject} of the latest release. + * @throws IOException If a connection cannot be made. + */ + public JSONObject getLatestReleaseJson() throws IOException { + URL url = new URL(repositoryUrl + "releases/latest"); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + + connection.setRequestMethod("GET"); + + int responseCode = connection.getResponseCode(); + + if (responseCode == HttpURLConnection.HTTP_OK) { + try (BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { + String inputLine; + StringBuilder response = new StringBuilder(); + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + return new JSONObject(response.toString()); + } + } + return null; + } + + public int getLatestReleaseID() throws IOException { + JSONObject object = getLatestReleaseJson(); + return object.getInt("id"); + } + + public JSONArray getReleaseAssets(int releaseID) throws IOException { + URL url = new URL(repositoryUrl + "releases/" + releaseID + "/assets"); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + + connection.setRequestMethod("GET"); + + int responseCode = connection.getResponseCode(); + + if (responseCode == HttpURLConnection.HTTP_OK) { + try (BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { + String inputLine; + StringBuilder response = new StringBuilder(); + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + return new JSONArray(response.toString()); + } + } else { + throw new RuntimeException("GitHub API request failed. Response Code: " + responseCode); + } + } + + public JSONObject getReleaseAsset(int releaseID, String pattern) throws IOException { + JSONArray array = getReleaseAssets(releaseID); + for (int i = 0; i < array.length(); i++) { + JSONObject asset = array.getJSONObject(i); + if (asset.getString("name").matches(pattern)) { + return asset; + } + } + return null; + } + + public FileDownloader downloadAsset(int assetId, File output) throws IOException { + FileDownloader downloader = new FileDownloader(); + downloader.addRequestProperty("Accept", "application/octet-stream"); + downloader.startDownload(repositoryUrl + "releases/" + "assets/" + assetId, output); + return downloader; + } +} From 90b716b58cad29be817f22986758281268a925a4 Mon Sep 17 00:00:00 2001 From: piitex Date: Thu, 13 Nov 2025 06:40:25 -0600 Subject: [PATCH 9/9] Finished FileChooserOverlay. --- .../engine/overlays/FileChooserOverlay.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/main/java/me/piitex/engine/overlays/FileChooserOverlay.java b/src/main/java/me/piitex/engine/overlays/FileChooserOverlay.java index 7ec7efb..a33d83a 100644 --- a/src/main/java/me/piitex/engine/overlays/FileChooserOverlay.java +++ b/src/main/java/me/piitex/engine/overlays/FileChooserOverlay.java @@ -16,6 +16,7 @@ public class FileChooserOverlay extends Overlay { private String text; private ButtonOverlay button; private FontLoader fontLoader; + private String[] fileExtensions; public FileChooserOverlay(Window window, String text) { this.window = window; @@ -31,6 +32,10 @@ public String getText() { return text; } + public void setText(String text) { + this.text = text; + } + public ButtonOverlay getButton() { return button; } @@ -51,6 +56,14 @@ public void onFileSelect(IDirectorySelect iDirectorySelect) { this.directorySelect = iDirectorySelect; } + /** + * Set a specific file extension to be use used. You can set both a prefix and a subfix; *.png, filename.*, *.* + * @param fileExtensions The array of all valid file extensions. + */ + public void setFileExtensions(String[] fileExtensions) { + this.fileExtensions = fileExtensions; + } + @Override public Node render() { Button jfxButton; @@ -64,7 +77,7 @@ public Node render() { jfxButton.setOnMouseClicked(event -> { FileChooser chooser = new FileChooser(); - chooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Select character card", "*.png")); + chooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(text, fileExtensions)); File directory = chooser.showOpenDialog(window.getStage()); if (getFileSelect() != null) {