承接第一部分的架構概覽,本文深入 JImaging 原型的啟動流程:設定系統原生外觀、建立/顯示主視窗、處理關閉事件、命令列參數驅動的影像載入與儲存。
預設 Metal 風格顯然不夠原生。setSystemLookAndFeel() 呼叫 UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()) 切換至平台原生風格 (Windows/Linux/Mac)。捕獲四種異常 (UnsupportedLookAndFeelException、ClassNotFoundException、IllegalAccessException、InstantiationException) 並以標準 Logging API 記錄為嚴重錯誤:
private static void log(Exception x) {
Logger.global.severe(x.getMessage());
}
原型用全域 Logger 即可,正式產品應建立專屬 Logger 寫入檔案。
private void createFrame() {
mainFrame = new MainFrame();
mainPanel = mainFrame.getMainPanel();
mainPanel.updateSize(); // 設定主面板合理尺寸
mainFrame.pack(); // 自動調整視窗大小以容納面板與工具列
loadImage(); // 載入命令列指定影像
}
pack() 繼承自 java.awt.Window,依元件慣用尺寸調整視窗。
private void showFrame() {
mainFrame.setDefaultCloseOperation(MainFrame.DO_NOTHING_ON_CLOSE); // 禁用預設關閉行為
mainFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
saveImage(); // 儲存註解後影像
mainFrame.dispose(); // 釋放資源
System.exit(0); // 結束程式
}
});
mainFrame.show();
mainPanel.requestFocus(); // 確保主面板獲得焦點 (否則工具列下拉框會搶焦點)
}
關鍵點:
DO_NOTHING_ON_CLOSE + 自訂 WindowListener 完全掌控關閉流程。requestFocus() 確保主繪圖區為焦點擁有者,即使不處理鍵盤事件亦符合 UX 原則。原型聚焦核心功能,暫不實作自訂 JFileChooser (可用 setAccessory() 嵌入預覽/參數面板),改以命令列參數指定路徑。使用 javax.imageio.ImageIO 簡潔 API:
private void loadImage() {
if (args.length >= 1) try {
File file = new File(args[0]);
BufferedImage image = ImageIO.read(file);
mainPanel.getPaintView().getModel().setBackImage(image);
} catch (IOException x) { log(x); }
}
private void saveImage() {
if (args.length >= 2) try {
File file = new File(args[1]);
String ext = file.getName().substring(file.getName().lastIndexOf('.') + 1);
BufferedImage image = mainPanel.getAnnotatedImage(); // 合成含註解影像
ImageIO.write(image, ext, file); // 自動依格式 (JPEG/PNG) 編碼
} catch (IOException x) { log(x); }
}
注意:J2SE 支援讀取 GIF/JPEG/PNG,但**僅能寫入 JPEG/PNG**。註解影像勿存為 GIF。
java -jar JImaging.jar sourceImage.jpg annotatedImage.png
第一參數為源影像路徑,第二參數為輸出路徑 (副檔名決定編碼格式)。