001/**
002 * GeomSS -- The GeomSS application startup class.
003 *
004 * Copyright (C) 2009-2024, by Joseph A. Huwaldt. All rights reserved.
005 *
006 * This library is free software; you can redistribute it and/or modify it under the terms
007 * of the GNU Lesser General Public License as published by the Free Software Foundation;
008 * either version 2.1 of the License, or (at your option) any later version.
009 *
010 * This library is distributed in the hope that it will be useful, but WITHOUT ANY
011 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
012 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
013 *
014 * You should have received a copy of the GNU Lesser General Public License along with
015 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place -
016 * Suite 330, Boston, MA 02111-1307, USA. Or visit: http://www.gnu.org/licenses/lgpl.html
017 */
018package geomss.app;
019
020import jahuwaldt.swing.AppUtilities;
021import jahuwaldt.swing.MainApp;
022import java.awt.Frame;
023import java.io.File;
024import java.text.MessageFormat;
025import java.util.Locale;
026import java.util.ResourceBundle;
027
028/**
029 * Application that hosts a Geometry Scripting System.
030 *
031 * <p> Modified by: Joseph A. Huwaldt </p>
032 *
033 * @author Joseph A. Huwaldt, Date: May 2, 2009
034 * @version January 1, 2024
035 */
036public class GeomSS implements MainApp {
037
038    /**
039     * The resource bundle containing the string resources for this application. Resource
040     * bundles are useful for localizing applications. New localities (languages) can be
041     * added by adding properties files only -- no code modifications.
042     */
043    public static final ResourceBundle RESBUNDLE = ResourceBundle.getBundle("geomss.app.appStrings", Locale.getDefault());
044
045    //  A reference to our GUI application instance.
046    private final GeomSSGUI guiApp;
047
048    /**
049     * The user preferences for this program.
050     */
051    private final AppPreferences prefs;
052
053    /**
054     * Entry point for this application. This is where it starts up from.
055     *
056     * @param args Command line arguments.
057     */
058    public static void main(final String[] args) {
059
060        // Create an instance of our application.
061        if (args.length > 0) {
062            //  Run in batch mode.
063            run_batch(args);
064
065        } else {
066            //  On windows, do not allow DirectDraw as it conflicts with OpenGL.
067            if (AppUtilities.isWindows())
068                System.setProperty("sun.java2d.noddraw", "true");
069
070            // Schedule a job for the event-dispatching thread.
071            javax.swing.SwingUtilities.invokeLater(new Runnable() {
072                @Override
073                public void run() {
074                    try {
075                        //  Run in interactive GUI mode.
076                        new GeomSS();
077                    } catch (Throwable e) {
078                        e.printStackTrace();
079                        AppUtilities.showException(null, RESBUNDLE.getString("unexpectedTitle"),
080                                RESBUNDLE.getString("unexpectedMsg"), e);
081                        System.exit(0);
082                    }
083                }
084            });
085        }
086    }
087
088    /**
089     * Constructor for our application that displays the GUI.
090     *
091     * @throws java.lang.Exception if there is any problem starting the program.
092     */
093    public GeomSS() throws Exception {
094
095        //  Make sure that Java 3D is available.
096        try {
097            Test4Java3D.test(1, 5);
098        } catch (ClassNotFoundException e) {
099            javax.swing.JOptionPane.showMessageDialog(null, RESBUNDLE.getString("noJava3DMsg"),
100                    RESBUNDLE.getString("noJava3DTitle"), javax.swing.JOptionPane.ERROR_MESSAGE);
101            System.exit(1);
102
103        } catch (Exception e) {
104            String j3dVersion = e.getMessage();
105            String msg;
106            if (j3dVersion != null)
107                msg = MessageFormat.format(RESBUNDLE.getString("wrongJava3DMsg"), j3dVersion);
108            else
109                msg = RESBUNDLE.getString("noJava3DMsg");
110            javax.swing.JOptionPane.showMessageDialog(null, msg,
111                    RESBUNDLE.getString("noJava3DTitle"), javax.swing.JOptionPane.ERROR_MESSAGE);
112            System.exit(1);
113        }
114
115        guiApp = new GeomSSGUI(RESBUNDLE);
116
117        //  Load in the user preferences.
118        prefs = new GUIPreferences(this);
119        GeomSSGUI.setPreferences(prefs);
120
121        // Finally, create an instance of an application window to get the program rolling.
122        Frame window = MainWindow.newAppWindow(null, null);
123        window.setVisible(true);
124        GeomSSGUI.addWindow(window);
125    }
126
127    /**
128     * Runs the application in batch mode.
129     *
130     * @param args Command line arguments
131     */
132    public static void run_batch(String[] args) {
133
134        if (args.length != 1 || args[0].startsWith("-"))
135            printUsageAndDie();
136
137        try {
138            //  Get a file reference for the input file.
139            File scriptFile = new File(args[0]);
140            if (!scriptFile.exists()) {
141                System.out.println(RESBUNDLE.getString("scriptFileNotFoundMsg1") + args[0]
142                        + RESBUNDLE.getString("scriptFileNotFoundMsg2"));
143                System.exit(-1);
144            }
145
146            //  On MacOS, give the dock icon a descriptive name.
147            System.setProperty("com.apple.mrj.application.apple.menu.about.name",
148                    RESBUNDLE.getString("appName") + ": " + scriptFile.getName());
149            //System.setProperty("java.awt.headless", "true");
150
151            //  Create an instance of a batch script runner and run it.
152            GeomSSBatch batchThread = new GeomSSBatch(RESBUNDLE, scriptFile);
153            batchThread.start();
154
155            //  Wait for the batch job to finish.
156            batchThread.join();
157
158        } catch (Throwable e) {
159            e.printStackTrace();
160            System.exit(-1);
161        }
162
163    }
164
165    /**
166     * Method that prints out usage information for this client.
167     */
168    private static void printUsageAndDie() {
169        System.out.print(RESBUNDLE.getString("appName"));
170        System.out.print(", " + RESBUNDLE.getString("version"));
171        System.out.print(RESBUNDLE.getString("appVersion"));
172        System.out.print(", ");
173        System.out.println(RESBUNDLE.getString("appModDate"));
174        System.out.println(RESBUNDLE.getString("helpMsg1"));
175        System.out.println(RESBUNDLE.getString("helpMsg2"));
176        System.out.println(RESBUNDLE.getString("helpMsg3"));
177        System.out.println("    " + RESBUNDLE.getString("helpMsg4"));
178        System.out.println("    " + RESBUNDLE.getString("helpMsg5"));
179        System.exit(0);
180    }
181
182    //-----------------------------------------------------------------------------------
183    /**
184     * @return the resource bundle stored with this application. If no resource bundle has
185     *         been stored, then null is returned.
186     */
187    @Override
188    public final ResourceBundle getResourceBundle() {
189        return RESBUNDLE;
190    }
191
192    /**
193     * @return a reference to this program's GUI application or null if we are running in
194     *         batch mode.
195     */
196    @Override
197    public final GeomSSGUI getGUIApplication() {
198        return guiApp;
199    }
200
201    /**
202     * @return a reference to the user preferences for this application.
203     */
204    @Override
205    public final AppPreferences getPreferences() {
206        return prefs;
207    }
208
209}