From 6909329ff25dbee83465e5fa081a1eb50c174dc7 Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Mon, 27 Nov 2023 13:42:24 +0000 Subject: [PATCH] Removed ability to export to a standalone executable JAR file. This had a few bugs anyway, but was also increasingly difficult to support since it required Java and JavaFX to be present on the destination machine, and to construct a complex classpath to run the JAR. --- .../labels/english/greenfoot/greenfoot-labels | 1 - .../main/java/greenfoot/export/Exporter.java | 59 +-------- .../export/GreenfootScenarioApplication.java | 67 ---------- .../java/greenfoot/export/JarCreator.java | 32 +---- .../greenfoot/guifx/export/ExportAppTab.java | 122 ------------------ .../greenfoot/guifx/export/ExportDialog.java | 1 - 6 files changed, 6 insertions(+), 276 deletions(-) delete mode 100644 greenfoot/src/main/java/greenfoot/export/GreenfootScenarioApplication.java delete mode 100644 greenfoot/src/main/java/greenfoot/guifx/export/ExportAppTab.java diff --git a/greenfoot/labels/english/greenfoot/greenfoot-labels b/greenfoot/labels/english/greenfoot/greenfoot-labels index 91ea9c1751..6015c934ec 100644 --- a/greenfoot/labels/english/greenfoot/greenfoot-labels +++ b/greenfoot/labels/english/greenfoot/greenfoot-labels @@ -110,7 +110,6 @@ export.app.help=Create an executable jar file that can be run on its own. export.app.location=Save to: export.app.browse=Browse export.app.choose=Save executable jar file -export.app.more=More information on running on other machines export.project.help=Create a standalone project gfar file. This allows the whole project to be given to other people as a single file that Greenfoot can open directly. export.project.location=Save to: export.project.browse=Browse diff --git a/greenfoot/src/main/java/greenfoot/export/Exporter.java b/greenfoot/src/main/java/greenfoot/export/Exporter.java index 603e8d4baf..0506938a16 100644 --- a/greenfoot/src/main/java/greenfoot/export/Exporter.java +++ b/greenfoot/src/main/java/greenfoot/export/Exporter.java @@ -24,7 +24,6 @@ of the License, or (at your option) any later version. import bluej.Boot; import bluej.Config; import bluej.pkgmgr.Project; -import bluej.utility.Utility; import greenfoot.event.PublishEvent; import greenfoot.event.PublishListener; @@ -43,7 +42,6 @@ of the License, or (at your option) any later version. import java.util.concurrent.ExecutionException; import javafx.application.Platform; -import javafx.embed.swing.SwingFXUtils; import javafx.geometry.Dimension2D; import org.glavo.png.javafx.PNGJavaFXUtils; @@ -65,7 +63,7 @@ public class Exporter implements PublishListener */ public enum ExportFunction { - PUBLISH, PROJECT, APP; + PUBLISH, PROJECT; /** * Returns the export function which corresponds to the passed name. @@ -157,10 +155,6 @@ public void doExport(Project project, ExportDialog dialog, ScenarioSaver scenari { publishToWebServer(); } - if (function.equals(ExportFunction.APP)) - { - makeApplication(); - } if (function.equals(ExportFunction.PROJECT)) { makeProject(); @@ -196,7 +190,7 @@ private void publishToWebServer() boolean lockScenario = scenarioInfo.isLocked(); JarCreator jarCreator = new JarCreator(project, exportDir, jarName, worldName, - lockScenario, true); + lockScenario); // do not include source jarCreator.includeSource(false); @@ -318,55 +312,6 @@ private static File[] getJarsInPlusLib(Project project) File plusLibsDir = new File(project.getProjectDir(), Project.projectLibDirName); return plusLibsDir.listFiles((dir, name) -> name.toLowerCase().endsWith(".jar")); } - - /** - * Create an application (jar-file) - */ - @OnThread(Tag.Worker) - private void makeApplication() - { - dialog.setProgress(true, Config.getString("export.progress.writingJar")); - File exportFile = new File(scenarioInfo.getExportFileName()); - File exportDir = exportFile.getParentFile(); - String jarName = exportFile.getName(); - - boolean lockScenario = scenarioInfo.isLocked(); - boolean hideControls = scenarioInfo.isHideControls(); - - JarCreator jarCreator = new JarCreator(project, exportDir, jarName, worldName, - lockScenario, hideControls, false, false); - // do not include source - jarCreator.includeSource(false); - - // Add the Greenfoot standalone classes - File greenfootLibDir = Config.getGreenfootLibDir(); - File greenfootDir = new File(greenfootLibDir, "standalone"); - jarCreator.addFile(greenfootDir); - - // Add 3rd party libraries used by Greenfoot. - Set thirdPartyLibs = GreenfootUtil.get3rdPartyLibs(); - for (File lib : thirdPartyLibs) { - jarCreator.addJarToJar(lib); - } - - // Add jars in +libs dir in project directory - File[] jarFiles = getJarsInPlusLib(project); - if (jarFiles != null) { - for (File file : jarFiles) { - jarCreator.addJarToJar(file); - } - } - - // Add text file with license information - File license = new File(Config.getGreenfootLibDir(), "GREENFOOT_LICENSES.txt"); - if (license.exists()) - { - jarCreator.addFile(license); - } - - jarCreator.create(); - dialog.setProgress(false, Config.getString("export.progress.complete")); - } /** * Create an standalone project (gfar-file) diff --git a/greenfoot/src/main/java/greenfoot/export/GreenfootScenarioApplication.java b/greenfoot/src/main/java/greenfoot/export/GreenfootScenarioApplication.java deleted file mode 100644 index 9756da462b..0000000000 --- a/greenfoot/src/main/java/greenfoot/export/GreenfootScenarioApplication.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - This file is part of the Greenfoot program. - Copyright (C) 2018,2021 Poul Henriksen and Michael Kolling - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - This file is subject to the Classpath exception as provided in the - LICENSE.txt file that accompanied this code. - */ -package greenfoot.export; - -import greenfoot.core.Simulation; -import javafx.application.Application; -import javafx.application.Platform; -import javafx.scene.Scene; -import javafx.stage.Stage; -import threadchecker.OnThread; -import threadchecker.Tag; - -public class GreenfootScenarioApplication extends Application -{ - @Override - @OnThread(Tag.FXPlatform) - public void start(Stage primaryStage) throws Exception - { - Platform.setImplicitExit(true); - GreenfootScenarioViewer greenfootScenarioViewer = new GreenfootScenarioViewer(); - Scene scene = new Scene(greenfootScenarioViewer); - scene.getStylesheets().add("greenfoot.css"); - primaryStage.setScene(scene); - primaryStage.show(); - primaryStage.setOnHiding(e -> { - Simulation.getInstance().abort(); - - // Fail safe: if we haven't exited after a second, force exit: - Thread exiter = new Thread("Greenfoot exit") - { - public void run() - { - try - { - Thread.sleep(1000); - } - catch (InterruptedException ex) - { - } - System.exit(1); - } - }; - // Don't let the exiter fallback prevent us exiting normally: - exiter.setDaemon(true); - exiter.start(); - }); - } -} diff --git a/greenfoot/src/main/java/greenfoot/export/JarCreator.java b/greenfoot/src/main/java/greenfoot/export/JarCreator.java index a26b4f3b5a..f38ed8da2a 100644 --- a/greenfoot/src/main/java/greenfoot/export/JarCreator.java +++ b/greenfoot/src/main/java/greenfoot/export/JarCreator.java @@ -1,6 +1,6 @@ /* This file is part of the Greenfoot program. - Copyright (C) 2005-2009,2010,2011,2013,2014,2015,2018,2019 Poul Henriksen and Michael Kolling + Copyright (C) 2005-2009,2010,2011,2013,2014,2015,2018,2019,2023 Poul Henriksen and Michael Kolling This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -122,29 +122,6 @@ private JarCreator(File exportDir, String jarName) this.jarName = jarName; properties = new Properties(); } - - /** - * Export the class files for a project. - * - * Convenience constructor that includes settings that are common for all - * projects and export types. This will exclude BlueJ metafiles. - * - * @param project The project to be exported. - * @param exportDir The directory to export to. - * @param jarName Name of the jar file that should be created. - * @param worldClass Name of the main class. - * @param lockScenario Should the exported scenario include 'act' - * and speedslider. - * @param hideControls Should the exported scenario include the controls panel - * @param applet Whether the export is for an applet on a webpage (true) or for a stand-alone JAR (false) - */ - public JarCreator(Project project, File exportDir, String jarName, String worldClass, - boolean lockScenario, boolean hideControls, boolean fullScreen, boolean applet) - { - this(project, exportDir, jarName, worldClass, lockScenario, applet); - properties.put("scenario.hideControls", "" + hideControls); - properties.put("scenario.fullScreen", "" + fullScreen); - } /** * Export the class files for a project. @@ -157,11 +134,10 @@ public JarCreator(Project project, File exportDir, String jarName, String worldC * @param jarName Name of the jar file that should be created. * @param worldClass Name of the main class. * @param lockScenario Should the exported scenario include 'act' - * and speedslider. - * @param applet Whether the export is for an applet on a webpage (true) or for a stand-alone JAR (false) + * and speedslider. */ public JarCreator(Project project, File exportDir, String jarName, String worldClass, - boolean lockScenario, boolean applet) + boolean lockScenario) { this(exportDir, jarName); @@ -197,7 +173,7 @@ public JarCreator(Project project, File exportDir, String jarName, String worldC addSkipDir(Project.projectLibDirName); // Set the main class - String mainClass = (applet ? GreenfootScenarioViewer.class : GreenfootScenarioApplication.class).getCanonicalName(); + String mainClass = GreenfootScenarioViewer.class.getCanonicalName(); setMainClass(mainClass); // Add the properties read by the GreenfootScenarioViewer diff --git a/greenfoot/src/main/java/greenfoot/guifx/export/ExportAppTab.java b/greenfoot/src/main/java/greenfoot/guifx/export/ExportAppTab.java deleted file mode 100644 index 306d8c2f00..0000000000 --- a/greenfoot/src/main/java/greenfoot/guifx/export/ExportAppTab.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - This file is part of the Greenfoot program. - Copyright (C) 2005-2009,2011,2013,2015,2018,2019,2023 Poul Henriksen and Michael Kolling - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - This file is subject to the Classpath exception as provided in the - LICENSE.txt file that accompanied this code. - */ -package greenfoot.guifx.export; - -import static greenfoot.export.Exporter.ExportFunction; - -import bluej.Boot; -import bluej.Config; -import bluej.utility.Utility; -import bluej.utility.javafx.JavaFXUtil; -import greenfoot.export.mygame.ExportInfo; -import greenfoot.export.mygame.ScenarioInfo; - -import java.io.File; -import java.util.Map; -import java.util.stream.Collectors; - -import javafx.beans.binding.Bindings; -import javafx.geometry.Insets; -import javafx.geometry.Pos; -import javafx.scene.control.Button; -import javafx.scene.control.Hyperlink; -import javafx.scene.control.Label; -import javafx.scene.control.TextArea; -import javafx.scene.control.TextField; -import javafx.scene.input.Clipboard; -import javafx.scene.input.DataFormat; -import javafx.scene.layout.BorderPane; -import javafx.scene.layout.Pane; -import javafx.stage.Window; - -import threadchecker.OnThread; -import threadchecker.Tag; - -/** - * Export dialog's tab for exporting to a standalone application. - * - * @author Michael Kolling - * @author Amjad Altadmri - */ -@OnThread(Tag.FXPlatform) -public class ExportAppTab extends ExportLocalTab -{ - /** - * Creates a new instance of ExportAppTab - * - * @param parent The window which will host this tab. - * @param scenarioInfo The scenario info needed for different export functions. - * @param scenarioName The name of the scenario to be shared. - * @param defaultExportDir The default directory to select from. - */ - public ExportAppTab(Window parent, ScenarioInfo scenarioInfo, String scenarioName, File defaultExportDir) - { - super(parent, scenarioInfo, scenarioName, defaultExportDir, "app", ".jar"); - } - - @Override - public ExportFunction getFunction() - { - return ExportFunction.APP; - } - - @Override - protected void buildContentPane(final File targetFile) - { - super.buildContentPane(targetFile); - - String sep = Config.isWinOS() ? ";" : ":"; - String javaAndClasspathBefore = "\"" + Config.getJDKExecutablePath(null, "java") + "\" -cp \"" + - Utility.urlsToFiles(Boot.getInstance().getRuntimeUserClassPath()).stream().filter(f -> f.getName().startsWith("javafx")).map(f -> f.getAbsolutePath()).collect(Collectors.joining(sep)) + sep; - String javaAndClasspathAfter = /*"\" --module-path \"" + Boot.getInstance().getJavaFXLibDir() + "\" --add-modules=ALL-MODULE-PATH */ " greenfoot.export.GreenfootScenarioApplication"; - - Hyperlink moreInfo = new Hyperlink(Config.getString("export.app.more")); - moreInfo.setOnAction(event -> JavaFXUtil.runAfterCurrent(() -> Utility.openWebBrowser("https://www.greenfoot.org/doc/run_standalone"))); - - Label commandLineExplanation = new Label("Command to run scenario on this machine:"); - - TextArea commandLineBox = new TextArea(); - commandLineBox.setWrapText(true); - commandLineBox.setEditable(false); - commandLineBox.textProperty().bind(Bindings.concat(javaAndClasspathBefore, targetDirField.textProperty(), javaAndClasspathAfter)); - - Button copyButton = new Button(Config.getString("editor.copyLabel")); - copyButton.setOnAction(e -> Clipboard.getSystemClipboard().setContent(Map.of(DataFormat.PLAIN_TEXT, commandLineBox.getSelectedText().isEmpty() ? commandLineBox.getText() : commandLineBox.getSelectedText()))); - - BorderPane.setAlignment(copyButton, Pos.CENTER); - BorderPane.setMargin(copyButton, new Insets(0, 0, 0, 10)); - BorderPane borderPane = new BorderPane(commandLineBox, commandLineExplanation, copyButton, moreInfo, null); - - ((Pane)getContent()).getChildren().addAll(borderPane, lockScenario, hideControls); - } - - @Override - protected ExportInfo getExportInfo() - { - ExportInfo info = super.getExportInfo(); - info.setLocked(isLockScenario()); - info.setHideControls(isHideControls()); - return info; - } - - -} diff --git a/greenfoot/src/main/java/greenfoot/guifx/export/ExportDialog.java b/greenfoot/src/main/java/greenfoot/guifx/export/ExportDialog.java index ac6404c201..319d3de618 100644 --- a/greenfoot/src/main/java/greenfoot/guifx/export/ExportDialog.java +++ b/greenfoot/src/main/java/greenfoot/guifx/export/ExportDialog.java @@ -341,7 +341,6 @@ private void createTabs() File defaultExportDir = project.getProjectDir().getParentFile(); addTab(new ExportPublishTab(project, this, scenarioSaver, scenarioInfo)); - addTab(new ExportAppTab(asWindow, scenarioInfo, projectName, defaultExportDir)); addTab(new ExportProjectTab(asWindow, scenarioInfo, projectName, defaultExportDir)); tabbedPane.getTabs().setAll(exportTabs.values());