java 板


LINE

※ 引述《gp123 (George Peng)》之铭言: : 这个问题很明显是thread的问题, : 由於Swing元件的更新在另一个thread中进行, : 而这个thread的优先权很低。 : : 我发现函式只会自己跑自己的 : : 但JLabel完全没有反应 : : 等到递回函式跑完了 : : Label才终於显示最後的状态 : : 可是中途完全没有任何反应 : 在你的状况中, : 几乎要等到递回的method执行完後, : 才有机会轮到Swing一次更新到最新状况, : 才会造成你看到的结果。 : 通常不建议在一般的worker thread中直接操作Swing, : 长时间的操作中更不合适, : 可试着参考 : http://slientfreaky.blogspot.tw/2011/09/java-swing.html : 的方式, : 将你的函式移到GUI的执行绪中进行。 通常 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 ) *减少看官翻页动作,注解(讨论)写在前头,程式码殿後 如果把 start 按钮按下後的动作改成 counter.syncStart(10); 取代了原本的 counter.asyncStart(10); 这就是在 UI Thread(event-dispatching thread) 里做耗时的工作(倒数需要 好几秒),会导致倒数的期间(约 10 秒) GUI 像是死了一般(不会更新);直到 倒数完毕才直接显示 0 秒。 =========================================================================== CountDown.java package cc.ptt; public class CountDown { public interface OnTickListener { public void onTick(int seconds); } private static class NullTickListener implements OnTickListener { @Override public void onTick(int seconds) { } } private static final OnTickListener nullListener = new NullTickListener(); private OnTickListener tickListener = nullListener; public void asyncStart(final int seconds) { // run in some worker thread new Thread(new Runnable() { public void run() { try { count(tickListener, seconds); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); } public void syncStart(int seconds) { // run in the caller thread try { count(tickListener, seconds); } catch (InterruptedException e) { e.printStackTrace(); } } private void count(OnTickListener listener, int timeInSecs) throws InterruptedException { if (timeInSecs <= 0) { listener.onTick(0); return; } listener.onTick(timeInSecs); Thread.sleep(1000); count(listener, timeInSecs - 1); } public OnTickListener getTickListener() { return tickListener == nullListener ? null : tickListener; } public void setTickListener(OnTickListener tickListener) { if (tickListener == null) this.tickListener = nullListener; else this.tickListener = tickListener; } } =========================================================================== CountDownDemo.java package cc.ptt; 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.SwingUtilities; public class CountDownDemo { 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(); counter.setTickListener(new CountDown.OnTickListener() { @Override public void onTick(int seconds) { // setText method is thread-safe messageBar.setText(String.format("%d 秒", seconds)); if (seconds <= 0) { SwingUtilities.invokeLater(new Runnable() { public void run() { start.setEnabled(true); } }); } } }); start.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { start.setEnabled(false); counter.asyncStart(10); // counter.syncStart(10); } }); frm.setSize(400, 400); frm.setLocationRelativeTo(null); frm.setVisible(true); } } --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 1.172.190.207 ※ 编辑: sbrhsieh 来自: 1.172.187.77 (01/04 01:31)







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

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

TOP