2012-12-30 33 views
0

我想用一个简单的Ping生成的每个新字符串动态更改JLabel,但无法弄清楚如何用每个新字符串替换JLabel上的现有字符串,因为Ping是执行。以下是我到目前为止。到目前为止,它只替换了Ping完成执行后的JLabel文本。用Ping结果动态更改JLabel

import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.*; 
import java.io.*; 

public class Ping extends JFrame implements ActionListener{ 

private JButton runButton = new JButton("Run"); 
private JLabel pingResult = new JLabel("Result"); 
private String results; 

public Ping(){ 
    runButton.addActionListener(this); 

    add(pingResult, BorderLayout.CENTER); 
    add(runButton, BorderLayout.NORTH); 

} 

//Action Listener 
public void actionPerformed(ActionEvent e) 
{ 
    String buttonString = e.getActionCommand(); 

    if (buttonString.equals("Run")) 
    { 
     //Execute Ping 
     try { 
      String line; 
      Process p = Runtime.getRuntime().exec("/sbin/ping -c 4 www.google.com"); 
      BufferedReader input = new BufferedReader(
       new InputStreamReader(p.getInputStream())); 

      while ((line = input.readLine()) != null) { 
       results += line + "\n"; 
       pingResult.setText(results); 
       //System.out.println(line); 
      } 

      input.close(); 
     }catch (Exception err){ 
      err.printStackTrace(); 
     } 

    }else{ 
     System.exit(0); 
    } 
} 

public static void main(String[] args) { 
    Ping sp = new Ping(); 
    sp.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
    sp.setSize(400, 400); 
    sp.setVisible(true); 
    sp.setLayout(new BorderLayout()); 
} 

} 

回答

0

确切地说,只有在完成ping之后,它才会更新它。如果你想在它完成之前完成它,你需要使用不同的线程

3

在事件派发线程上调用setText。为此使用SwingUtils.invokeLater。不要从EDT执行长期操作。正如您所遇到的,这会导致您的应用冻结。

1

您的代码冻结了EDT(Event Dispatch Thread)。这就是为什么JLabel文本在ping完成后更新。你应该避免这样做。在不同线程中运行持久操作并使用SwingUtils.invokeLater更新它是一种解决方案。另一个是SwingWorker类的用法。你可以在这里找到tutorial

下面是第一个选项的示例。我用JTextArea代替JLabel。

还有一件事你应该使用ProcessBuilder而不是Runtime.exec(),here是不错的文章为什么。

import java.awt.BorderLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.nio.charset.Charset; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTextArea; 
import javax.swing.SwingUtilities; 

public class PingExample { 
    private static final Logger logger = Logger.getLogger(PingExample.class.getName()); 

    public static void main(String[] args) { 
    PingExample p = new PingExample(); 
    p.run(); 
    } 

    private void run() { 
    SwingUtilities.invokeLater(new Runnable() { 
     @Override 
     public void run() { 
     JFrame frame = new PingFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 
     } 
    }); 
    } 

    private class PingFrame extends JFrame { 
    private static final long serialVersionUID = 1L; 

    private JTextArea textArea; 

    private PingFrame() { 
     super.setName("Ping Frame"); 
     this.addComponents(); 
     super.setSize(400, 240); 
    } 

    private void addComponents() { 
     super.setLayout(new BorderLayout()); 

     this.textArea = new JTextArea(10, 0); 
     JScrollPane scrollPane = new JScrollPane(this.textArea); 
     super.add(scrollPane, BorderLayout.NORTH); 

     JButton button = new JButton("Run"); 
     button.addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      new Thread(new Ping(PingFrame.this.textArea)).start(); 
     } 
     }); 
     super.add(button, BorderLayout.SOUTH); 
    } 

    private class Ping implements Runnable { 
     private JTextArea textArea; 

     private Ping(JTextArea textArea) { 
     this.textArea = textArea; 
     } 

     @Override 
     public void run() { 
     try { 
      List<String> commands = new ArrayList<>(10); 
      commands.add("ping"); 
      commands.add("www.google.com"); 

      ProcessBuilder builder = new ProcessBuilder(); 
      builder.command(commands); 
      Process process = builder.start(); 

      try (
       BufferedReader br = new BufferedReader(
       new InputStreamReader(process.getInputStream(), Charset.defaultCharset()))) { 
      String line = br.readLine(); 
      while (null != line) { 
       final String text = line; 
       SwingUtilities.invokeLater(new Runnable() { 
       @Override 
       public void run() { 
        Ping.this.textArea.append(text); 
        Ping.this.textArea.append("\n"); 
       } 
       }); 
       line = br.readLine(); 
      } 
      } 

      process.waitFor(); 
      process.destroy(); 
     } catch (IOException | InterruptedException x) { 
      logger.log(Level.SEVERE, "Error", x); 
     } 
     } 
    } 
    } 

}

+0

另外,作为一个侧面说明,其建议至少改变鼠标指针“忙”对于可能持续更长的时间超过2秒的操作,而一个进度条将是很好的,甚至更长的操作。 –