如何使用每个Ping更新JTextArea?

时间:2017-08-07 01:25:03

标签: java swing jtextarea

我遇到的问题是当我ping IP时,JTextArea在ping完成之前不会更新。这里的目标是每次IP被ping时JTextArea都会更新。这是我第一次使用swing库,我在网上找不到任何答案。非常感谢任何帮助,谢谢!

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.Border;

public class pingGUI 
{
    private JFrame mainFrame;       //initializing objects
    private JLabel headerLabel;
    private JLabel statusLabel;
    private JPanel controlPanel;
    private JTextField inputIP;
    private JButton pingButton;
    private JTextArea textArea;
    private JScrollPane scroll;

    public pingGUI(){
        prepareGUI();
    }
    public static void main(String[] args){
        pingGUI window = new pingGUI();  
        window.showEvent();       
    }
    private void prepareGUI(){
        mainFrame = new JFrame("Ping Test");
        mainFrame.setSize(400,400);
        mainFrame.setLayout(new GridLayout(4, 0));

        headerLabel = new JLabel("",JLabel.CENTER);
        statusLabel = new JLabel("",JLabel.CENTER);
        statusLabel.setVerticalAlignment(0);
        statusLabel.setSize(350,100);

        mainFrame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent windowEvent){
                System.exit(0);
            }        
        });    
        controlPanel = new JPanel();
        controlPanel.setLayout(new FlowLayout());

        mainFrame.add(headerLabel);
        mainFrame.add(controlPanel);
        mainFrame.add(statusLabel);
        mainFrame.setVisible(true);
    }

    private void showEvent(){

        headerLabel.setText("Enter a IP address to ping."); 
        inputIP = new JTextField(15);
        pingButton = new JButton("Ping");
        textArea = new JTextArea();
        textArea.setColumns(20);
        textArea.setRows(20);
        textArea.setLineWrap(true);
        textArea.setEditable(false);
        textArea.setVisible(true);
        scroll = new JScrollPane(textArea);
        scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

        pingButton.setActionCommand("Ping");
        pingButton.addActionListener(new ButtonClickListener());

        controlPanel.add(pingButton);
        controlPanel.add(inputIP);
        mainFrame.add(scroll);
        mainFrame.setVisible(true); 
    }   
    public void printIP(String s) {
           textArea.append(s + "\n");
       }
    private class ButtonClickListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            String command = e.getActionCommand(); 
            if (command.equals( "Ping" ))  {
                if (!inputIP.getText().isEmpty()) {
                    statusLabel.setText("Pinging IP Address...");
                    runPing("ping " + inputIP.getText());
                }
                else
                    statusLabel.setText("No IP address entered.");
            }
        }
    }
    public void runPing(String command) {   //Ping user specified IP address
        try {
            Process p = Runtime.getRuntime().exec(command); //accepts a command and returns according to command received.
            BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));

            String str = "";
            while ((str = input.readLine()) != null) {
                printIP(str);
            }
        } catch (Exception e){
            e.printStackTrace();
        }
    }
}

1 个答案:

答案 0 :(得分:1)

runPing()的实施阻止了event dispatch thread,因此在完成之后才能进行GUI更新。而是使用SwingWorker在后台运行命令并发布临时更新。使用ProcessBuilder从完整example开始,以下更改会生成显示的结果。

@Override
protected Integer doInBackground() {
    try {
        ProcessBuilder pb = new ProcessBuilder("ping", "-c 3", "example.com");
    …
}

image