首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

打造 Java 桌面應用原型 (三):關鍵技術決策與效能優化實戰

     編輯:Java 相關知識

前言:原型驅動技術決策

開發過程中必須解決技術難題並做出架構決策。原型不僅是可丟棄的實驗代碼,更是**產品基石**——在原型階段驗證想法、測試冷門 API、確保效能指標,為正式開發鋪路。本文分享 JImaging 圖片註解原型中的兩大關鍵決策。

決策一:多層面板整合 Swing 文字編輯器與自繪元件

需求背景

類 Windows 畫圖應用需支援:滑鼠繪圖 (線、矩形、橢圖)、物件變形 (移動、縮放、重排序、刪除、複製/剪貼/貼上)、文字註解 (編輯、縮放、換行)。自行實作文字編輯器成本極高,Swing 已提供豐富文字元件 (JTextComponent 族群)。

方案比較

  1. Cell Editor 模式:參考 JTable 的儲存格編輯器。但調整文字框大小、移動位置需額外技巧,實作複雜。
  2. JDesktopPane + JInternalFrame (採用):JDesktopPane 本質為**多層面板**。MainPane 繼承之,建立兩層:
    • 底層:PaintView 自繪元件,處理幾何圖形繪製。
    • 頂層:JInternalFrame 內嵌 Swing 文字元件,自動獲得移動、縮放、編輯功能。

關鍵技術:取得含註解的合成影像

JInternalFrame 內容非直接繪製於 PaintView,需程式化合成。MainPanel.getAnnotatedImage() 實現:

BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
printAll(g);  // 將整個元件階層 (含內部框架) 繪製到影像
g.dispose();

printAll() 遞迴繪製所有子元件,完美融合自繪圖形與 Swing 文字註解。

決策二:繞過 paint() 即時繪製,滑鼠拖曳零延遲

痛點

Swing 繪製通常在 paint() 內進行。滑鼠繪圖時,MOUSE_PRESSED 到 MOUSE_RELEASED 間產生數百個 MOUSE_DRAGGED 事件。若每次事件都呼叫 repaint() 重繪整個 PaintView (含所有文字註解),效能將不可接受。

解決方案:取得 Graphics 直接繪製

於滑鼠事件處理中呼叫 getGraphics() 取得即時繪圖上下文,委派給工具物件繪製:

protected void toolAction(MouseEvent e) {
    e.consume();
    Graphics2D g2 = (Graphics2D) getGraphics();  // 關鍵:繞過 paint()
    float zoomFactor = model.getZoomFactor();
    g2.scale(zoomFactor, zoomFactor);
    float x = e.getX() / zoomFactor;
    float y = e.getY() / zoomFactor;
    currentTool.action(e.getID(), x, y, g2);
    g2.dispose();
}

滑鼠釋放時才呼叫 repaint() 觸發完整重繪,**使用者完成繪圖後 paint() 僅執行一次**。

事件註冊架構

protected void registerListeners() {
    addMouseListener(new MouseAdapter() {
        public void mousePressed(MouseEvent e) {
            if (SwingUtilities.isLeftMouseButton(e)) {
                requestFocus();
                currentTool = model.createTool(AbstractTool.DRAW_STYLE);
                toolAction(e);
            }
        }
        public void mouseReleased(MouseEvent e) {
            if (SwingUtilities.isLeftMouseButton(e)) {
                toolAction(e);
                model.setLastTool(currentTool);
                currentTool = null;
                repaint();  // 單次完整重繪
            }
        }
    });
    addMouseMotionListener(new MouseMotionAdapter() {
        public void mouseDragged(MouseEvent e) {
            if (SwingUtilities.isLeftMouseButton(e)) toolAction(e);
        }
    });
    // ... 其他監聽器
}

總結

原型是產品的基礎而非垃圾代碼。透過原型驗證「多層面板整合 Swing 元件」與「繞過 paint() 即時繪製」兩大決策,JImaging 解決了複合編輯器架構與高頻繪製效能的核心挑戰。正式開發時,這些經驗將轉化為穩健的架構與優化代碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved