作者sbrhsieh (十年~)
看板java
标题Re: [问题] 绘图的两个问题
时间Mon Jul 9 11:41:26 2012
※ 引述《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