java gui 多线程,界面假死、僵死问题

(转载1)

楼主bluepb(流星) 2005-06-04 20:28:17 在 Java / GUI 设计 提问

我现在在用jAVA做图形化设计,想问个多线程的问题。 
比如在一个窗口上点个按钮执行一个操作,这个操作至少要花10秒钟,如何不让这个窗口在执行中没相应,比如下面一个文本框,随时在显示着执行的时间。 
不要跟我说不用多线程就可以实现,因为我认为是不可能的。 
哪位高手能否给个GUI中这样的一个例子。谢谢!

---------------------------------------------------------------------------------------

1 楼yxxcrtd(Report中) 回复于 2005-06-05 11:34:52 得分 0

Uping.....

---------------------------------------------------------------------------------------

2 楼chenweionline(键盘上的舞者) 回复于 2005-06-05 11:54:01 得分 0

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

class ThreadTest extends JFrame{ 
JTextField txt = new JTextField(); 
JButton btn = new JButton("start"); 

ThreadTest(){ 
btn.addActionListener(new AbstractAction(){ 
public void actionPerformed(ActionEvent event){ 
// 耗时操作线程 
new Thread(){ 
public void run(){ 
for(int i=0;i<10;i++){ 
txt.setText(i+" seconds"); 
try{ 
sleep(1000); 

catch(Exception ex){ 
ex.printStackTrace(); 


txt.setText("finished"); 

}.start(); 

}); 


this.getContentPane().add(btn,BorderLayout.NORTH); 
this.getContentPane().add(txt,BorderLayout.CENTER); 


public static void main(String[] args){ 
JFrame frame = new ThreadTest(); 
frame.pack(); 
frame.setVisible(true); 

}

---------------------------------------------------------------------------------------

3 楼chenweionline(键盘上的舞者) 回复于 2005-06-05 11:55:38 得分 0

这只是一个演示例子,最好不要在事件派发线程以外的线程里更新组件。

---------------------------------------------------------------------------------------

4 楼SaKura2003(小飞仔) 回复于 2005-06-05 15:22:51 得分 0

不要跟我说不用多线程就可以实现,因为我认为是不可能的。 

只有想不到,没有做不到的。

---------------------------------------------------------------------------------------

5 楼wuyafeixue(蓝色天空) 回复于 2005-06-05 20:09:40 得分 0

这是我写的读一个文件的线程,当点击open按钮时,执行下面的线程 

private ActionListener open=new ActionListener(){ 
public void actionPerformed(ActionEvent e){ 

try{ 

new threadOpen().start(); 

}catch(Exception f){ 
System.err.println("error"); 


}; 
private class threadOpen extends Thread{ 
private BufferedReader in; 
threadOpen(){ 

public void run(){ 
JFileChooser c=new JFileChooser(); 
JFrame frame = getFrame(); 
c.showOpenDialog(frame); 

try{ 
String name=c.getSelectedFile().getName(); 
String dir=c.getCurrentDirectory().toString(); 
dir=dir.replaceAll("\\\\","\\\\\\\\"); 
String openName=dir+"\\"+name; 

in=new BufferedReader(new FileReader(openName)); 
txt.setText(""); 

String s = null; 
String s2=new String(); 
int size=0,counter=0; 
while((s = in.readLine())!= null){ 
s=s+"\n"; 
if(++counter%100==0) 
sleep(10); 
txt.getDocument().insertString(size,s,null); 
size+=s.length(); 

in.close(); 
jmi61.setEnabled(false); 
jmi62.setEnabled(false); 
}catch(Exception e){ 
System.err.println("error"); 


}

(转载2)

楼主PHMan() 2003-12-24 13:05:06 在 Java / J2SE / 基础类 提问

当我触发一个BUTTON事件后,程序将执行一段耗时的操作(大约30分钟),这时SWING界面将”死”掉了,在耗时操作完成之前,将不会有任何反映。我想把这个耗时操作用invokeLater() 去执行,但是在这个操作完成之前,SWING界面还是没反映。大家是否有经验解决过这种问题?谢谢。

----------------------------------------------------------------------------------------

1 楼ManFirst(春梦空陶醉,醒来梦已碎.) 回复于 2003-12-24 13:11:11 得分 0

多线程可解决。 
就是隔多少秒,执行一下。

----------------------------------------------------------------------------------------

2 楼ManFirst(春梦空陶醉,醒来梦已碎.) 回复于 2003-12-24 13:15:55 得分 0

timer = new javax.swing.Timer(8, createTextLoadAction()); 
timer.start(); 
public Action createTextLoadAction() { 
return new AbstractAction("text load action") { 
public void actionPerformed (ActionEvent e) { 
if(jProgressBar1.getValue() < jProgressBar1.getMaximum()) { 
jProgressBar1.setValue(jProgressBar1.getValue() +1); 
tmp_CheckDb.getResultCheck(jProgressBar1.getValue());//你的程序 
jLabel2.setText("目前已经检查:"+jProgressBar1.getValue()+"/"+jProgressBar1.getMaximum()); 
} else { 
if(timer != null) { 
timer.stop(); 
timer = null; 



}; 
}

----------------------------------------------------------------------------------------

3 楼PHMan() 回复于 2003-12-24 14:26:52 得分 0

谢谢。从你的代码中,我怎么确定jProgressBar1.getMaximum()的值。因为我要执行一段耗时操作。但我没法确定要多少时间(30分钟只是一个例子)。所以我觉得没法确定getMaximum()的值。另外一点就是如果任务不能很快的完成,也许应该用SwingWorker 而不是Timer.

----------------------------------------------------------------------------------------

4 楼xxisxx(xx) 回复于 2003-12-24 16:14:56 得分 0

关注! 
我也再做这方面的调查,大家共同探讨 
UP

-----------------------------------------------------------------------------------------

5 楼ManFirst(春梦空陶醉,醒来梦已碎.) 回复于 2003-12-24 16:36:12 得分 5

timer = new javax.swing.Timer(8, createTextLoadAction());//关键是这句了。 
timer.start();   
------------------------------------------------------------------------------------------

6 楼xxisxx(xx) 回复于 2003-12-24 17:03:01 得分 5

我从别处找来了这样一个例子,不知道对你又无帮助 

package cosmos.alm; 

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

/** * 事件处理过程中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) { 
new Thread() { 
public void run() { 
try { 
showMessage("step one..."); 
Thread.sleep(3000); 
showMessage("\nstep two..."); 
Thread.sleep(3000); 
showMessage("\nfinished."); 
Thread.sleep(3000); 

catch (InterruptedException ie) { 
//ignored 


}.start(); 


}); 

private void showMessage (final String msg) { 
SwingUtilities.invokeLater(new Runnable() { 
public void run() { 
pane.setText(pane.getText() + msg); 

}); 


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); 


它把按钮的action事件坐到一个线程里,然后用SwingUtilities.invokeLater调用

-----------------------------------------------------------------------------------------------

7 楼sallina(我想骂人!!) 回复于 2003-12-24 17:14:01 得分 0

楼上正解!

-----------------------------------------------------------------------------------------------

8 楼binny(骑个破车看夕阳) 回复于 2003-12-24 17:41:17 得分 10

http://www.javaresearch.org/article/showarticle.jsp?column=287&thread=4429

-----------------------------------------------------------------------------------------------

9 楼PHMan() 回复于 2003-12-25 01:22:36 得分 0

谢谢大家的帮助,我已经解决了这个问题。事实上只要把耗时操作放到一个新线程里去就够了。然后在事件中运行这个线程。 
Thread t = new Thread(){ 
public void run(){ 
//我的耗时操作 

}; 
t.start() ; 

很感谢ManFirst 和xxisxx, 但我觉得binny给我的链接很好,所以我把分说给他。祝大家圣诞快乐。

------------------------------------------------------------------------------------------------------------

(注:该方案可行!更多内容可以浏览我的其他文章,有详细测试!!!)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值