j-- java代码dead code,Java JButton操作执行冻结

I've been fooling around with Java and I was trying to make a program that starts to ping an address and printing out the "ms".

I have a JButton:

JButton start = new JButton("START");

start.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent e){

try {

doCommand();

} catch (IOException e1) {

// TODO Auto-generated catch block

e1.printStackTrace();

}

}

});

And the doCommand() method looks like this:

public static void doCommand() throws IOException{

String s = null;

ProcessBuilder pb = new ProcessBuilder(commands); //definiramo procesBuilder

Process proces = pb.start(); //zaženemo proces (vrne Process)

BufferedReader stdInput = new BufferedReader(new InputStreamReader(proces.getInputStream())); //Branje outputa procesa

BufferedReader stdError = new BufferedReader(new InputStreamReader(proces.getErrorStream())); //Branje error outputa

while((s = stdInput.readLine()) != null){ //dokler output obstaja (ni error)

int dvop = s.indexOf(":") + 16;

if(s.startsWith("Reply")){

s=s.substring(dvop);

int pres = s.indexOf(" ");

s=s.substring(0,pres-2);

//System.out.println(s);

label.setText(s);

}

}

while((s = stdError.readLine()) != null){ //dokler error obstaja

System.out.println(s);

}

}

What happens is, everytime I press the button the program just freezes and nothing happens, I cant even close it the "normal" way...

I guess I'm doing something wrong...

解决方案

An elaboration on StinePike's answer. Exactly to what he says, the actionPerformed() method will run on the main GUI event thread meaning the GUI may only respond when actionPerformed() returns. The code you have posted uses blocking I/O which may not complete in a swift manner.

Especially this line:

while((s = stdInput.readLine()) != null){

Which blocks on input from stdin. While this block is in effect the GUI becomes unresponsive as the method actionPerformed() has not returned yet.

Since you said the objective of this code is to return a response from a external application it may be that the external application has either: returned something on stderr or is blocking on another condition.

A possible solution is as follows:

The doCommand() method:

public static void doCommand() throws IOException{

String s = null;

ProcessBuilder pb = new ProcessBuilder(commands); //definiramo procesBuilder

Process proces = pb.start(); //zaženemo proces (vrne Process)

final BufferedReader stdInput = new BufferedReader(new InputStreamReader(proces.getInputStream())); //Branje outputa procesa

final BufferedReader stdError = new BufferedReader(new InputStreamReader(proces.getErrorStream())); //Branje error outputa

Thread readStdIn = new Thread(new Runnable(){

public void run(){

try{

while((s = stdInput.readLine()) != null){ //dokler output obstaja (ni error)

int dvop = s.indexOf(":") + 16;

if(s.startsWith("Reply")){

s=s.substring(dvop);

int pres = s.indexOf(" ");

s=s.substring(0,pres-2);

//System.out.println(s);

//Execute on the main AWT thread (I'm assuming 'label' is the name of one of your GUI components)

SwingUtilities.invokeLater(new Runnable(){

public void run(){

label.setText(s);

}

});

}

}

}catch(IOException ex){

//Handle This

}

}

});

Thread readStdErr = new Thread(new Runnable(){

public void run(){

try{

while((s = stdError.readLine()) != null){ //dokler error obstaja

System.out.println(s);

}

catch(IOException ex){

//Handle This Too

}

};

});

readStdIn.start();

readStdErr.start();

}

The above code will spawn two separate threads in which will read the contents of stdin and stderr and process them individually. Since the block I/O has been ported off the main GUI thread, the GUI should continue to be responsive even if the external application does something strange (such as freeze or deadlock).

Note: This will allow the button to be pressed even if the external application has no finished executing.

Edit: Added missing try-catch blocks for BufferedReader.readLine()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值