From 3bfcb49547dca136385fc3cc5e6bd74efe134313 Mon Sep 17 00:00:00 2001 From: Muhammed Zohaib Anwer Date: Tue, 3 Dec 2024 14:15:42 +0500 Subject: [PATCH] Implemented Check For Update --- .vscode/launch.json | 7 + .../java/com/zam/dialogboxes/AboutDialog.java | 4 +- .../java/com/zam/menubar/ViewMenuHandler.java | 20 ++- .../java/com/zam/utils/UpdateChecker.java | 130 +++++++++++++----- 4 files changed, 127 insertions(+), 34 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index b8d2d84..37b696d 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,5 +4,12 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ + { + "type": "java", + "name": "Launcher", + "request": "launch", + "mainClass": "com.zam.Launcher", + "projectName": "bitcode" + } ] } \ No newline at end of file diff --git a/src/main/java/com/zam/dialogboxes/AboutDialog.java b/src/main/java/com/zam/dialogboxes/AboutDialog.java index b6477e3..9e36719 100644 --- a/src/main/java/com/zam/dialogboxes/AboutDialog.java +++ b/src/main/java/com/zam/dialogboxes/AboutDialog.java @@ -35,7 +35,7 @@ * ``` * * @author Muhammed Zohaib - * @version 1.0 + * @version 1.0.4 * @since 2024-01-07 */ public class AboutDialog extends JDialog { @@ -70,7 +70,7 @@ public AboutDialog(JFrame parent) { GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); - titleLabel.setText("

BitCode

Version 1.0.2.0"); + titleLabel.setText("

BitCode

Version "+ App.APP_VERSION +""); titleLabel.setFont(titleLabel.getFont().deriveFont(titleLabel.getFont().getSize() + 5f)); contentPane.add(titleLabel, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, diff --git a/src/main/java/com/zam/menubar/ViewMenuHandler.java b/src/main/java/com/zam/menubar/ViewMenuHandler.java index 9f6446a..6882c9d 100644 --- a/src/main/java/com/zam/menubar/ViewMenuHandler.java +++ b/src/main/java/com/zam/menubar/ViewMenuHandler.java @@ -7,11 +7,13 @@ import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.KeyStroke; +import javax.swing.SwingWorker; import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; import com.zam.dialogboxes.ThemeChanger; import com.zam.ui.App; +import com.zam.utils.UpdateChecker; /** * Custom menu handler for the View menu in BitCode IDE. @@ -31,7 +33,7 @@ * ``` * * @author Muhammed Zohaib - * @version 1.0.3 + * @version 1.0.4 * @since 2023-12-12 */ public class ViewMenuHandler extends JMenu { @@ -39,6 +41,7 @@ public class ViewMenuHandler extends JMenu { private final JMenuItem increaseFontSizeItem = new JMenuItem("Increase Font Size"); private final JMenuItem decreaseFontSizeItem = new JMenuItem("Decrease Font Size"); private final JMenuItem changeThemeItem = new JMenuItem("Change Theme"); + private final JMenuItem checkUpdateItem = new JMenuItem("Check for Update"); final private App mainApp; @@ -56,6 +59,8 @@ public ViewMenuHandler(String title, App parent) { add(increaseFontSizeItem); add(decreaseFontSizeItem); add(changeThemeItem); + addSeparator(); // Add a separator line + add(checkUpdateItem); // Add action listeners and accelerators configureMenuItems(); @@ -76,6 +81,19 @@ private void configureMenuItems() { // Add an action listener to the "Change Theme" menu item changeThemeItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_T, ActionEvent.CTRL_MASK)); changeThemeItem.addActionListener(e -> openThemeDialog()); + + // Add an action listener to the "Check for Update" menu item + checkUpdateItem.addActionListener(e -> { + SwingWorker worker = new SwingWorker<>() { + @Override + protected Void doInBackground() { + UpdateChecker.checkForUpdate(mainApp); + return null; + } + }; + worker.execute(); + }); + } /** diff --git a/src/main/java/com/zam/utils/UpdateChecker.java b/src/main/java/com/zam/utils/UpdateChecker.java index c37de68..bf19d65 100644 --- a/src/main/java/com/zam/utils/UpdateChecker.java +++ b/src/main/java/com/zam/utils/UpdateChecker.java @@ -1,54 +1,122 @@ package com.zam.utils; import javax.swing.*; +import com.zam.ui.App; import java.awt.*; import java.io.*; import java.net.HttpURLConnection; import java.net.URI; +import java.net.URISyntaxException; import java.util.Properties; +/** + * Utility class for checking updates for the BitCode IDE application. + * + * This class fetches the latest version information from a remote properties file + * and compares it with the current application version. If a new version is + * available, it prompts the user to download it. + * + * Usage: + * - Call `UpdateChecker.checkForUpdate(App parent)` from your application. + * + * Example: + * ```java + * UpdateChecker.checkForUpdate(mainApp); + * ``` + * + * @author Muhammed Zohaib + * @version 1.0.4 + * @since 2024-12-03 + */ public class UpdateChecker { - private static final String UPDATE_URL = "https://raw.githubusercontent.com/zohaibanwer984/BitCode-Java-IDE/development/App.properties"; - private static final String CURRENT_VERSION = "1.0.0"; - public static void main(String[] args) { - SwingUtilities.invokeLater(UpdateChecker::checkForUpdate); - } + /** + * URL of the remote properties file containing version information. + */ + private static final String UPDATE_URL = "https://raw.githubusercontent.com/zohaibanwer984/BitCode-Java-IDE/development/App.properties"; - public static void checkForUpdate() { + /** + * Checks for updates by comparing the current application version with the latest version available online. + * + * @param parent The parent component for displaying dialog boxes. + */ + public static void checkForUpdate(App parent) { try { - // Fetch the properties file - Properties remoteProperties = new Properties(); - HttpURLConnection connection = (HttpURLConnection) new URI(UPDATE_URL).toURL().openConnection(); - connection.setRequestMethod("GET"); - - try (InputStream inputStream = connection.getInputStream()) { - remoteProperties.load(inputStream); - } + // Fetch the properties file from the remote server + Properties remoteProperties = fetchRemoteProperties(); - // Get version + // Retrieve the latest version from the remote properties String latestVersion = remoteProperties.getProperty("version"); - // String downloadUrl = remoteProperties.getProperty("downloadUrl"); - String downloadUrl = "LINK TO DOWNLOAD"; - - // Compare versions - if (latestVersion != null && !CURRENT_VERSION.equals(latestVersion)) { - int choice = JOptionPane.showConfirmDialog( - null, - "A new version (" + latestVersion + ") is available. Do you want to download it?", - "Update Available", - JOptionPane.YES_NO_OPTION - ); + String downloadUrl = "https://sourceforge.net/projects/bitcode-java-ide/"; - if (choice == JOptionPane.YES_OPTION && downloadUrl != null) { - Desktop.getDesktop().browse(new URI(downloadUrl)); - } + // Compare versions and notify the user + if (latestVersion != null && !App.APP_VERSION.equals(latestVersion)) { + promptForUpdate(parent, latestVersion, downloadUrl); } else { - JOptionPane.showMessageDialog(null, "You are already using the latest version.", "No Updates", JOptionPane.INFORMATION_MESSAGE); + JOptionPane.showMessageDialog( + parent, + "You are already using the latest version.", + "No Updates", + JOptionPane.INFORMATION_MESSAGE + ); } } catch (Exception e) { - JOptionPane.showMessageDialog(null, "Failed to check for updates: " + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog( + parent, + "Failed to check for updates: " + e.getMessage(), + "Error", + JOptionPane.ERROR_MESSAGE + ); e.printStackTrace(); } } + + /** + * Fetches the remote properties file containing version information. + * + * @return The loaded Properties object. + * @throws IOException If an I/O error occurs during the fetch. + */ + private static Properties fetchRemoteProperties() throws IOException, URISyntaxException { + Properties remoteProperties = new Properties(); + HttpURLConnection connection = (HttpURLConnection) new URI(UPDATE_URL).toURL().openConnection(); + connection.setRequestMethod("GET"); + + // Read the response content from the server + StringBuilder responseContent = new StringBuilder(); + try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { + String line; + while ((line = reader.readLine()) != null) { + responseContent.append(line).append("\n"); + } + } + + // Load properties from the fetched content + try (InputStream inputStream = new ByteArrayInputStream(responseContent.toString().getBytes())) { + remoteProperties.load(inputStream); + } + + return remoteProperties; + } + + /** + * Prompts the user with an update dialog if a new version is available. + * + * @param parent The parent component for the dialog. + * @param latestVersion The latest version available online. + * @param downloadUrl The URL to download the new version. + * @throws Exception If an error occurs while opening the download link. + */ + private static void promptForUpdate(Component parent, String latestVersion, String downloadUrl) throws Exception { + int choice = JOptionPane.showConfirmDialog( + parent, + "A new version (" + latestVersion + ") is available. Do you want to download it?", + "Update Available", + JOptionPane.YES_NO_OPTION + ); + + if (choice == JOptionPane.YES_OPTION) { + Desktop.getDesktop().browse(new URI(downloadUrl)); + } + } }