JLabel.setText();方法在while(true)循环中出现死循环,无法实时刷新

酷呐么踏踏 发布于 2017/07/31 10:51
阅读 295
收藏 1
JButton btnNewButton = new JButton("begin");
		btnNewButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				this.rollText();
			}
			public void rollText() {
				String[] arr = { "haorui", "xixi", "lala", "qq" };
				boolean b = true;
				while (b) {
					Random rand = new Random();
					int i = rand.nextInt(2);
					String str = "123";
					try {
						Thread.sleep(1000);
						lblNewLabel.setText("123");
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}

			}
		});
		btnNewButton.setBounds(61, 163, 93, 23);
		contentPane.add(btnNewButton);

现在卡住不能动了

加载中
0
tcxu
tcxu

吸取 battyman依然菜刀 的建议,将代码修改如下,以便 随机显示 arr 中的名字。

import javax.swing.*;
import java.awt.event.*;
import java.util.*;

public class SwitchLabel extends JFrame implements Runnable{
	
	JButton btnNewButton, btnEnd;
	JLabel lblNewLabel;
	String[] arr = { "haorui", "xixi", "lala", "qq" };
	Thread thread;
	
	public void start() {
	if (thread==null)
	thread = new Thread(this);
	thread.start();
    }
    
    public void stop() {
	thread = null;
    }
	
	public void run( ){
		while (thread != null) {
			Random rand = new Random();
			try {
				Thread.sleep(1000);
				lblNewLabel.setText(arr[rand.nextInt(4)]);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}	
	}

	public SwitchLabel(){
	setVisible(true);
	setSize(450,250);
		
	setLayout(null);
	lblNewLabel = new JLabel("Label");
		lblNewLabel.setBounds(200, 120, 93, 23);

	btnNewButton = new JButton("begin");
		btnNewButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				start();
			} } );			
		btnNewButton.setBounds(61, 163, 93, 23);
		
	btnEnd = new JButton("End");
		btnEnd.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				stop();
			}
		});		
		btnEnd.setBounds(261, 163, 93, 23);
				
		getContentPane().add(btnNewButton);
		getContentPane().add(btnEnd);
		getContentPane().add(lblNewLabel);
	}

public static void main(String args[]){
	new SwitchLabel();	
	}
}

 

0
battyman
battyman

Swing是线程不安全的,所以在Swing中专门提供了一个线程用于对组件的安全访问,这个线程就称为事件派发线程,而且只能从事件派发线程访问将要在屏幕上绘制的Swing组件,否则运行会不正常。

从代码中的rollText方法可以看出,此方法没返回之前,界面就是假死的状态

因此:

1.需要将耗时的工作(rollText方法)放到一个单独的线程中

2.将绘制工作(rollText中的lblNewLabel.setText("123"))使用Runnable接口实现,然后使用SwingUtilities.invokeLater(此接口);

0
依然菜刀
依然菜刀

1、将rollText的代码放到单独的线程里面

2、while(true)改为while(isRolling)

3、按钮的点击只负责修改isRolling成员变量的true/false值

0
WeiXiaodong
WeiXiaodong

为何不用JavaFX

返回顶部
顶部