4 * License : The MIT License
5 * Copyright(c) 2008 olyutorskii
8 package jp.sfjp.jindolf;
10 import java.awt.Dimension;
11 import java.awt.EventQueue;
12 import java.io.PrintStream;
13 import java.lang.reflect.InvocationTargetException;
14 import java.text.MessageFormat;
15 import java.util.logging.Level;
16 import java.util.logging.Logger;
17 import javax.swing.JFrame;
18 import javax.swing.UIManager;
19 import jp.sfjp.jindolf.config.AppSetting;
20 import jp.sfjp.jindolf.config.CmdOption;
21 import jp.sfjp.jindolf.config.ConfigStore;
22 import jp.sfjp.jindolf.config.EnvInfo;
23 import jp.sfjp.jindolf.config.OptionInfo;
24 import jp.sfjp.jindolf.data.LandsModel;
25 import jp.sfjp.jindolf.log.LogUtils;
26 import jp.sfjp.jindolf.log.LoggingDispatcher;
27 import jp.sfjp.jindolf.util.GUIUtils;
28 import jp.sfjp.jindolf.view.ActionManager;
29 import jp.sfjp.jindolf.view.WindowManager;
34 * <p>{@link JindolfJre17}の下請けとして本格的なJindolf起動処理に入る。
36 public final class JindolfMain {
38 /** クラスロード時のナノカウント。 */
39 public static final long NANOCT_LOADED;
40 /** クラスロード時刻(エポックmsec)。 */
41 public static final long EPOCHMS_LOADED;
45 private static final Logger LOGGER = Logger.getAnonymousLogger();
47 private static final String LOG_LOADED =
48 "{0} は {1,date} {2,time} に"
49 + "VM上のクラス {3} としてロードされました。 ";
50 private static final String LOG_NANOCT =
51 "Initial Nano-Count : {0}";
52 private static final String LOG_HEAP =
53 "Max-heap : {0} Bytes Total-heap : {1} Bytes";
54 private static final String LOG_CONF =
55 "設定格納ディレクトリに[ {0} ]が指定されました。";
56 private static final String LOG_NOCONF =
58 private static final String FATALMSG_INITFAIL =
60 private static final String ERRMSG_HELP =
62 + "起動オプションに「{0}」を指定すると確認できます。";
64 private static final PrintStream STDOUT = System.out;
65 private static final PrintStream STDERR = System.err;
68 NANOCT_LOADED = System.nanoTime();
69 EPOCHMS_LOADED = System.currentTimeMillis();
76 private JindolfMain(){
82 * 標準出力および標準エラー出力をフラッシュする。
84 private static void flush(){
91 * 標準出力端末にヘルプメッセージ(オプションの説明)を表示する。
93 private static void showHelpMessage(){
96 String helpText = CmdOption.getHelpText();
97 STDOUT.print(helpText);
106 * @param appSetting アプリ設定
108 private static void dumpBootInfo(AppSetting appSetting){
111 logArgs = new Object[]{
115 Jindolf.class.getName(),
117 LOGGER.log(Level.INFO, LOG_LOADED, logArgs);
119 LOGGER.log(Level.INFO, LOG_NANOCT, NANOCT_LOADED);
121 Runtime runtime = Runtime.getRuntime();
122 logArgs = new Object[]{
124 runtime.totalMemory(),
126 LOGGER.log(Level.INFO, LOG_HEAP, logArgs);
128 OptionInfo optinfo = appSetting.getOptionInfo();
129 StringBuilder bootArgs = new StringBuilder();
130 bootArgs.append("\n\n").append("起動時引数:\n");
131 for(String arg : optinfo.getInvokeArgList()){
132 bootArgs.append("\u0020\u0020").append(arg).append('\n');
134 bootArgs.append('\n');
135 bootArgs.append(EnvInfo.getVMInfo());
136 LOGGER.info(bootArgs.toString());
138 ConfigStore configStore = appSetting.getConfigStore();
139 if(configStore.useStoreFile()){
140 LOGGER.log(Level.INFO, LOG_CONF, configStore.getConfigPath());
142 LOGGER.info(LOG_NOCONF);
149 * JindolfMain のスタートアップエントリ。
150 * @param args コマンドライン引数
151 * @return 起動に成功すれば0。失敗したら0以外。
153 public static int main(String... args){
158 optinfo = OptionInfo.parseOptions(args);
159 }catch(IllegalArgumentException e){
160 String message = e.getLocalizedMessage();
161 STDERR.println(message);
164 MessageFormat.format(ERRMSG_HELP, CmdOption.OPT_HELP);
165 STDERR.println(info);
171 exitCode = main(optinfo);
177 * JindolfMain のスタートアップエントリ。
178 * @param optinfo コマンドライン引数情報
179 * @return 起動に成功すれば0。失敗したら0以外。
181 public static int main(OptionInfo optinfo){
184 if(optinfo.hasOption(CmdOption.OPT_HELP)){
190 if(optinfo.hasOption(CmdOption.OPT_VERSION)){
191 STDOUT.println(VerInfo.ID);
196 // ここ以降、アプリウィンドウの生成と表示に向けてまっしぐら。
198 // あらゆるSwing文字列表示処理より前に必要。
199 // システムプロパティ swing.boldMetal は無視される。
201 if(optinfo.hasOption(CmdOption.OPT_BOLDMETAL)){
202 // もの凄く日本語表示が汚くなるかもよ!注意
203 boldFlag = Boolean.TRUE;
205 boldFlag = Boolean.FALSE;
207 UIManager.put("swing.boldMetal", boldFlag);
209 exitCode = splashedMain(optinfo);
215 * JindolfMain のスタートアップエントリ。
218 * スプラッシュウィンドウが出ている状態として想定されていた。
219 * 時間のかかる初期化処理はなるべくこの中へ。
221 * @param optinfo コマンドライン引数情報
222 * @return 起動に成功すれば0。失敗したら0以外。
224 public static int splashedMain(OptionInfo optinfo){
225 if(optinfo.hasOption(CmdOption.OPT_VMINFO)){
226 STDOUT.println(EnvInfo.getVMInfo());
229 LogUtils.initRootLogger(optinfo.hasOption(CmdOption.OPT_CONSOLELOG));
232 final AppSetting appSetting = new AppSetting(optinfo);
233 dumpBootInfo(appSetting);
235 ConfigStore configStore = appSetting.getConfigStore();
236 configStore.prepareConfigDir();
237 configStore.tryLock();
240 appSetting.loadConfig();
242 final Runtime runtime = Runtime.getRuntime();
243 runtime.addShutdownHook(new Thread(){
246 @SuppressWarnings("CallToThreadYield")
248 LOGGER.info("シャットダウン処理に入ります…");
252 runtime.runFinalization(); // 危険?
258 LoggingDispatcher.replaceEventQueue();
262 EventQueue.invokeAndWait(new Runnable(){
266 startGUI(appSetting);
270 }catch(InvocationTargetException | InterruptedException e){
271 LOGGER.log(Level.SEVERE, FATALMSG_INITFAIL, e);
272 e.printStackTrace(STDERR);
280 * AWTイベントディスパッチスレッド版スタートアップエントリ。
281 * @param appSetting アプリ設定
283 private static void startGUI(AppSetting appSetting){
284 JFrame topFrame = buildMVC(appSetting);
286 GUIUtils.modifyWindowAttributes(topFrame, true, false, true);
290 Dimension initGeometry =
291 new Dimension(appSetting.initialFrameWidth(),
292 appSetting.initialFrameHeight());
293 topFrame.setSize(initGeometry);
295 if( appSetting.initialFrameXpos() <= Integer.MIN_VALUE
296 || appSetting.initialFrameYpos() <= Integer.MIN_VALUE ){
297 topFrame.setLocationByPlatform(true);
299 topFrame.setLocation(appSetting.initialFrameXpos(),
300 appSetting.initialFrameYpos() );
303 topFrame.setVisible(true);
310 * @param appSetting アプリ設定
311 * @return アプリケーションのトップフレーム
313 private static JFrame buildMVC(AppSetting appSetting){
314 LandsModel model = new LandsModel();
315 WindowManager windowManager = new WindowManager();
316 ActionManager actionManager = new ActionManager();
318 model.loadLandList();
320 Controller controller = new Controller(model,
325 JFrame topFrame = controller.getTopFrame();