java 板


LINE

※ 引述《issuemylove (skill)》之铭言: : 大家好^^ : 在下最近稍微研究了一下User interface的部份 : 想说试着让某图形(圆形)在视窗上位移 : 如在右方的连结情况下 http://nopaste.info/3b91c2304d.html : 图形正常的移动了 : 但是我使用 Button控制它的移动时机时(即按下button後才移动) : 如右方连结 http://nopaste.info/4cb008e3bf.html : 却出现了中间移动过程皆不出现的情况 : 而直接时间到後,才将最後一个画面印出 : 请问这是哪边出了问题呢? : 谢谢大家的回答 repaint 是个 asynchronous operation,(大致上来说)它的任务可看成是 queue 一个 PaintEvent 到 event-dispatching thread。他并不是直接造成元件的 paint routine 被执行来绘制外观。此外过多的 PaintEvent 累积在 event- dispatching thread 里可能会被合并,因此并不是每 invoke 一次就一定会令元件 repaint 一次。 你的程式在 event-dispatching thread 执行把多个 paint event queue 到 event-dispatching thread 里的动作(A),在 A 完成以前 event-dispatching thread(EDT) 不会有机会去处理 paint event。等到 A 完成了,EDT 可以处理已累积 的 paint event,就算 EDT 有照实一个 paint event 做一次 UI 上的绘图,你看起来 的效果也会是直接看到 UI component 最後的状态时外观(在 30 ms 内,萤幕上如果有 许多变化,你可能也看不出来)。 整个程式并不是如你想的 repaint method 执行一次 UI 元件外观更新一次,停个 100 ms 再继续。而会是程式先停了 10 秒,然後突然执行了 100 次绘图动作,或是 一次(两者你用肉眼观察或许感觉上是相同的)。 你的程式要有动画的效果,主要可以往两个方向来改。 1. 在 event-dispatching thread 里改变的 UI component 状态後,invoke UI component 的 paintImmediately method 来直接触发 paint routine 来更新外观。 例如把 frame.repaint(); 改成执行 myPanel instance 的 paintImmediately method。 import java.awt.BorderLayout; import java.awt.Color; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; public class myCircleMove { JFrame frame; JButton button; myPanel panel; int x; int y; public static void main(String[] args) { myCircleMove gui = new myCircleMove(); gui.go(); } public void go() { x = 10; y = 10; panel = new myPanel(); button = new JButton("click me"); button.addActionListener(new myActionListener()); frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(BorderLayout.SOUTH, button); frame.getContentPane().add(BorderLayout.CENTER, panel); frame.setSize(600, 600); frame.setVisible(true); } public class myActionListener implements ActionListener { public void actionPerformed(ActionEvent e) { for (int i = 0; i < 100; i++) { x++; y++; // frame.repaint(); // <= 怪怪的 panel.paintImmediately(0, 0, panel.getWidth(), panel.getHeight()); try { Thread.sleep(100); } catch (Exception e1) { } } } } class myPanel extends JPanel { public void paintComponent(Graphics g) { g.setColor(Color.black); g.fillRect(0, 0, this.getWidth(), this.getHeight()); g.setColor(Color.red); g.fillOval(x, y, 40, 40); } } } 2. 把变更 UI component 状态的动作由 event-dispatching thread 以外的 thread 来执行。 public class myActionListener implements ActionListener { public void actionPerformed(ActionEvent e) { new Thread(new Runnable() { public void run() { for (int i = 0; i < 100; i++) { x++; y++; // frame.repaint(); // <= 怪怪的 panel.repaint(); try { Thread.sleep(100); } catch (Exception e1) { } } } }).start(); } } --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 218.173.139.219 ※ 编辑: sbrhsieh 来自: 218.173.139.219 (06/28 17:06)
1F:推 issuemylove:谢谢你的答覆~ 06/28 17:27
2F:→ issuemylove:可是我不明白为何使用Button的方法,此问题会浮现?..? 06/28 17:29
3F:→ issuemylove:照理说,没用Button(即直接移动)也会有该问题?@@ 06/28 17:31
没有使用 button 触发动画的版本中,move100 method 不是在 EDT 里执行,而是在 main thread 里。move100 method 执行过程中 EDT 有机会去处理 repaint 安排的 paint event(导致 EDT 去执行 UI component 的 paint routine)。如果在 go method 里把 move100 invocation 丢到 EDT 去跑,就会出现相同问题。 javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { move100(); } } ※ 编辑: sbrhsieh 来自: 218.173.139.219 (06/28 17:57)
4F:推 issuemylove:感谢s大的解述^^ 我已经甚有了解此问题了,谢谢 06/28 18:08







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:iOS站内搜寻

TOP