您的位置:首页 > 产品设计 > UI/UE

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

2016-07-14 10:01 459 查看
(转载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给我的链接很好,所以我把分说给他。祝大家圣诞快乐。

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



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

收藏于 2010-04-24
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息