長時間禁用UI 主執行緒
在UI 中, 若每隔一最時間就要更新, 比如計時器, 就千萬別在UI主執行緒執行迴圈, 否則整個UI就會被卡住
非UI執行緒更新畫面
在Java中, 是可以在別的執行緒使用setText來更新UI, 也保証是安全的. 但這也僅限於JLabel而以, 且官方文件並沒有說明, 那些是安全的, 那些是不安全的. 再加上Andorid, C#都是禁止非UI主行緒進行畫面更新, 所以並不建議此法.
SwingUtilities invokeLater
此法是產生一個執行緒, 稱為UIThread, 畫面的更新放在run裏面, 但我們並不使用 start()產生新執行緒來更新. 而是將此執行緒放在SwingUtilities.invokeLater()裏面. 待UI主執行緒有空時, 使用UI主執行緒來執行. 此法是最正確的作法. 程式碼如下
private void btnActionPerformed(java.awt.event.ActionEvent evt) {
new Thread(new Runnable(){
@Override
public void run() {
while(true){
try {Thread.sleep(10);} catch (InterruptedException ex) {}
SwingUtilities.invokeLater(new UiThread(timer++));
}
}
}).start();
}
class UiThread extends Thread{
int value;
public UiThread(int v){
value=v;
}
public void run(){
lbl.setText(String.valueOf(value));
}
}
Lambda
當然, 如果懂得Lambda的話, 上面藍色的部份就可以改成如下, 然後 class UIThread就可以整個拿掉.
SimpleDateFormat sdf=new SimpleDateFormat("HH:mm:ss:SSS"); boolean runFlag=false; private void btnActionPerformed(java.awt.event.ActionEvent evt) { runFlag=!runFlag; new Thread(()->{ while(runFlag){ try {Thread.sleep(1);} catch (InterruptedException ex) {} SwingUtilities.invokeLater(()->lbl.setText(sdf.format(new Date()))); } }).start(); }