Re: [問題] 繪圖的兩個問題

看板java作者 (十年~)時間13年前 (2012/07/09 11:41), 編輯推噓0(000)
留言0則, 0人參與, 最新討論串4/4 (看更多)
※ 引述《the2046 (wz)》之銘言: : 重畫(repaint)是一件很耗時的工作, 所以它執行的優先權(priority)是最低的. : 它必需讓其他指令先執行, 它才能執行. 例如: : import javax.swing.*; : import javax.swing.event.MouseInputListener; : import java.awt.Graphics; : import java.awt.event.MouseEvent; : class TeachPanel extends JPanel implements MouseInputListener{ : public TeachPanel() { : this.addMouseListener(this); : this.addMouseMotionListener(this); : } : @Override : public void paintComponent(Graphics g) { : System.out.println("paint done"); : System.out.println("----------------"); : } : public void t() { : System.out.println("t done1"); : System.out.println("t done2"); : } : //--------[ implements MouseInputListener : @Override : public void mouseDragged(MouseEvent e) { : System.out.println("drag done1"); : repaint(); : System.out.println("drag done2"); : System.out.println("drag done3"); : System.out.println("drag done4"); : t(); : } : @Override public void mouseClicked(MouseEvent e) {} : @Override public void mouseEntered(MouseEvent e) {} : @Override public void mouseExited(MouseEvent e) {} : @Override public void mouseMoved(MouseEvent e) {} : @Override public void mousePressed(MouseEvent e) {} : @Override public void mouseReleased(MouseEvent e) {} : //--------] implements MouseInputListener : public static void main(String[] args) { : JFrame jf = new JFrame(); : jf.setSize(500, 500); : jf.setVisible(true); : jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); : jf.setContentPane(new TeachPanel()); : } : } : 輸出結果: : paint done : ---------------- : drag done1 : drag done2 : drag done3 : drag done4 : t done1 : t done2 : paint done : ---------------- : 螢幕初始化時, 系統會自動調用 paintComponent一次, : 但隨後 repaint()都最後才執行. 會得到這樣的結果主因是 repaint method 本身是 asynchronous operation,它 會造成(觸發) UI 組件的 paint routine 在某個時刻執行(在 event-dispatching thread),精確地說是 repaint 會 enqueue PaintEvent 到 EDT,造成 paint method 的執行。 因為 mouseDragged method 本身是執行在 EDT 裡,那麼 repaint method 所安排 的 PaintEvent 必定會在 mouseDragged 執行完之後才被處理,於是 paint method 的執行是在 mouseDragged 執行完畢之後,然 mouseDragged method 執行過程裡, repaint method 被執行的時機則是依照其在 mouseDragged method 裡出現的順序, 換句話說,repaint method 執行的時間點定在 t method 之前。 試著把 mouseDragged method 裡的所有 statemenets 打包到一個 Runnable object 丟到另一個 thread 來執行,你多少可以觀察到 paint method 的執行不是落在最後 的情況。 @Override public void mouseDragged(MouseEvent e) { new Thread(new Runnable() { public void run() { System.out.println("drag done1"); repaint(); System.out.println("drag done2"); System.out.println("drag done3"); System.out.println("drag done4"); t(); } }).start(); } -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 218.173.81.225
文章代碼(AID): #1F-bBfU2 (java)
文章代碼(AID): #1F-bBfU2 (java)