java 板


LINE

※ 引述《sbrhsieh (十年~)》之铭言: : 通常 GUI 回应不够及时(常见於提问中的说法是:中间变化略过直接显示最後的 : 状态),是由於在 UI Thread 做了耗时间的事,若这些事里头包含了操作 UI 组件 : 或变更组件资料/状态,就会出现『常见说法』中的情况。 : 这不是由於 UI Thread 的 priority 太低所致。 : 原帖主希望在一个递回函式的执行过程中由 UI 组件显示执行的状态(也许是每一个 : call stack 的参数或某些状态),要这样子做来帮助了解递回函式执行的流程(教学 : 用的程式?)势必要在递回函式中加入 delay,否则程式执行的速度很快,肉眼是 : 无法观察到过程中 UI 组件显示的即时资讯(人的反应太慢)。 : 下面是一个以递回函式来做倒数的 demo(对,很矫情的 demo),它显示出一般 : 要做一件耗时的事情又需要在过程中更新 UI 组件来显示其 progress 的常见做法。 : 这只是一个用来点出某些观念(我在上一篇的推文)的demo,所以暂时请不要讲究 : 这倒数精不精确或其他小细节。 : CountDownDemo.java(网页版: http://ideone.com/VEY1io ) : CountDown.java(网页版: http://ideone.com/edwtgI ) 个人凭着久远的错误印象,在未经查证的状况下回覆。 很感谢sbrhsieh的回应,发现这问题,并提醒我将来要更谨慎。 以下参考自Java SE的官方文件 Swing's Threading Policy总结一下 Ref: http://docs.oracle.com/javase/7/docs/api/javax/swing/package-summary.html Swing元件并非thread-safe, 基本上所有更改Swing元件状态的动作都应该要在Swing Thread中完成, 且不能花太长的时间执行,以免拖垮Swing元件的重绘。 但因为actionListener等AWT/Swing的event handling通常预设在Swing Thread中执行, 所以一般我们不会查觉到这问题, 通常问题会发生在: (1)当Dialog或Frame显示後,仍直接在原本的worker thread中 (即没有在event handler)中操作Swing component, 这可能会造成Swing元件不可预期的状态。 (2)操作Swing执行时间太久,这会拖垮元件重绘/反应的时间, 此即原PO者的问题所在。 如果要在长时间的工作中操作Swing元件, 最好将操作Swing元件的部分单独在Swing thread中执行, sbrshieh的作法即是标准作法, 而这会牵涉到Thread的建立/执行/沟通, 另一种作法是使用SwingWorker(详情请见API说明), 可以省下自行操作执行绪的工作。 以下用SwingWorker改写原s大的倒数计时程式, 功能差不多(但改成只能倒数一次,以集中问题焦点), 在部份程式码加注与原写法的不同: package swingworkertest; import java.util.List; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.SwingWorker; public class CountDownDemo_SwingWorker { public static void main(String[] args) { JFrame frm = new JFrame("Demo for Java@ptt"); frm.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); final JLabel messageBar = new JLabel("", JLabel.CENTER); messageBar.setBorder(BorderFactory.createLoweredBevelBorder()); messageBar.setFont(messageBar.getFont().deriveFont(48f)); frm.getContentPane().add(messageBar); final JButton start = new JButton("开始倒数 10 秒"); frm.getContentPane().add(start, BorderLayout.SOUTH); final CountDown counter = new CountDown(10, messageBar); start.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { start.setEnabled(false); counter.execute(); // 原为 counter.asyncStart(10); // counter.get(); // 原为counter.syncStart(10); } }); frm.setSize(400, 400); frm.setLocationRelativeTo(null); frm.setVisible(true); } } class CountDown extends SwingWorker<Integer,Integer> { private int m_sec; private JLabel m_message; CountDown(int seconds, JLabel message) { m_sec = seconds; m_message = message; } @Override protected Integer doInBackground() throws Exception { count(m_sec); return 0; } private void count(int timeInSecs) throws InterruptedException { if (timeInSecs <= 0) { publish(0); // 原为 listener.onTick(0); return; } publish(timeInSecs); // 原为 listener.onTick(timeInSecs); Thread.sleep(1000); count(timeInSecs - 1); } // 以下原为 counter.setTickListener(new CountDown.OnTickListener() {...} @Override protected void process(List<Integer> intermediate_data) { if (!intermediate_data.isEmpty()) m_message.setText(String.format("%d 秒", intermediate_data.get(intermediate_data.size()-1))); } } --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 140.114.88.25
1F:推 popcorny:推这篇... SwingWorker好用 01/08 22:18
2F:→ sbrhsieh:可以完全不改CountDown class直接套进SwingWorker里使用 01/11 23:55







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灯, 水草

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

TOP