国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

事件處理中UI的刷新問題(筆記體小品文)

2019-11-18 15:15:32
字體:
供稿:網(wǎng)友

  注:根據(jù)yigemaser、JFML、Crazyjavar的建議更新,對(duì)三位的幫助表示感謝!

在寫UI應(yīng)用時(shí),通常會(huì)在一些事件處理的過程中,尤其當(dāng)這個(gè)處理比較耗時(shí)的時(shí)候,希望能夠及時(shí)把一些進(jìn)度信息顯示給用戶。這時(shí)通常大家都會(huì)使用一個(gè)文本控件來顯示這些進(jìn)度信息。比如下面的程序中,有一個(gè)JTextPane和JButton,在JButton中的action事件中需要進(jìn)行一些耗時(shí)的處理,例子程序中使用了Thread.sleep()使當(dāng)前線程休眠3秒來模擬耗時(shí)的操作。action事件處理分為3步,我們希望及時(shí)把當(dāng)前的進(jìn)度顯示在JTextPane上。
代碼如下:

package brUCe.test;import javax.swing.*;import java.awt.Container;import java.awt.BorderLayout;import java.awt.Dimension;import java.awt.event.WindowAdapter;import java.awt.event.ActionListener;import java.awt.event.ActionEvent;/** * 事件處理過程中UI的刷新 * @author Bruce * @version 1.0 */public class TestUIUpdate2 { public TestUIUpdate2() { TestUIUpdate2Frame frame = new TestUIUpdate2Frame(); frame.pack(); frame.setVisible(true); } public static void main(String[] args) { new TestUIUpdate2(); }}class TestUIUpdate2Frame extends JFrame { JTextPane pane = new JTextPane(); JButton button = new JButton("action..."); TestUIUpdate2Frame() { init(); this.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e){ try { pane.setText("step one..."); Thread.sleep(3000); pane.setText("step two..."); Thread.sleep(3000); pane.setText("finished."); Thread.sleep(3000); } catch (InterruptedException ie) { //ignored } } }); } PRivate void init() { pane.setPreferredSize(new Dimension(300,200)); Container content = getContentPane(); content.setLayout(new BorderLayout()); content.add(pane, BorderLayout.CENTER); content.add(button, BorderLayout.SOUTH); }}
但在實(shí)際運(yùn)行過程中可以發(fā)現(xiàn),點(diǎn)擊JButton后,JTextPane并不能及時(shí)更新,而是在整個(gè)JButton的action事件處理完畢后才能顯示出最后的信息。為什么會(huì)出現(xiàn)這種情況呢?因?yàn)樵谔幚鞪Button的action事件過程中,雖然更新了JTextPane的內(nèi)容,但由于JButton的事件處理是在當(dāng)前main線程中運(yùn)行,雖然JTextPane更新了內(nèi)容,但沒有得到刷新顯示的執(zhí)行機(jī)會(huì)。

解決這個(gè)問題的方法非常簡(jiǎn)單,只需要把JButton的action處理代碼放入一個(gè)新的線程,然后啟動(dòng)這個(gè)線程。另外,由于Swing的操作大部分是非線程安全的,所以對(duì)Swing界面的刷新也單獨(dú)放在一個(gè)線程,并調(diào)用SwingUtilities.invokeLater()執(zhí)行。這樣action事件處理、更新JTextPane的界面和main主線程就分別運(yùn)行在各自的線程中,都可以及時(shí)得到執(zhí)行。JButton的
actionPerformed(ActionEvent e)的處理代碼修改如下:[code] button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e){ try { new Thread() { public void run() { try { showMessage("step one..."); Thread.sleep(3000); showMessage("step two..."); Thread.sleep(3000); showMessage("finished."); Thread.sleep(3000); } catch (InterruptedException ie) { //ignored } } }.start(); } catch (Exception ex) { ex.printStackTrace(); } } });

showMessage方法如下:

private void showMessage (final String msg) { SwingUtilities.invokeLater(new Runnable() { public void run() { pane.setText(pane.getText() + msg); } }); }
大家可以測(cè)試運(yùn)行觀察效果。這樣也使界面更加友好,因?yàn)榧偃绮话補(bǔ)ction的處理代碼放在一個(gè)單獨(dú)的線程中,用戶點(diǎn)擊JButton后,界面就停止一切響應(yīng),直到action處理代碼執(zhí)行完畢。大家可以擴(kuò)展這種方法,答應(yīng)用戶隨時(shí)停止該耗時(shí)的操作,使界面更加友好。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 扎赉特旗| 孙吴县| 博乐市| 武宁县| 双江| 闽清县| 定西市| 东阿县| 隆回县| 咸阳市| 上杭县| 清徐县| 清镇市| 南充市| 双桥区| 莱芜市| 富民县| 册亨县| 开封市| 扎赉特旗| 新丰县| 临洮县| 赤城县| 中江县| 晋城| 铜陵市| 哈尔滨市| 永春县| 鹤庆县| 潞城市| 任丘市| 富锦市| 瑞安市| 桐庐县| 长海县| 辛集市| 宜章县| 苏州市| 平塘县| 江北区| 万全县|